Bienvenue sur le wiki de Nuit debout, nous sommes le 2987 mars.




Villes/Montluçon/sciences/FastGraph

De NuitDebout
Aller à : navigation, rechercher
 Table des matières


Chapitre 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 1

Qu'est-ce que Fastgraph?  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  2
   Fastgraph / Lumière.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  2
   Connaissances requises.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  3
   Compilateurs pris en charge.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  3
   En mode réel, mode protégé, et DOS Extender.  .  .  .  .  .  .  .  .  .  .  .  4
   Modèles de mémoire.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  5
   Installation Fastgraph.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  6
   Le fichier READ.ME.  . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  7
   Le fichier WHATS.NEW.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  7
   Fastgraph Conventions de dénomination.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  7
   Compilation et des liaisons.  .  .  .  .  .  .  .  .  .. . . . . . . . . . . . 7
        Borland C ++. . . . . . . . . . . . . . . . . . . . . . . . . . dix
        Borland Pascal. . . . . . . . . . . . . . . . . . . . . . . . 12
        MetaWare haut C / C ++. . . . . . . . . . . . . . . . . . . . . . 13
        Système de développement professionnel Microsoft BASIC. . . . . . . . 14
        Microsoft C / C ++. . . . . . . . . . . . . . . . . . . . . . . . 15
        Microsoft FORTRAN. . . . . . . . . . . . . . . . . . . . . . . 16
        Microsoft FORTRAN PowerStation. . . . . . . . . . . . . . . . 17
        Microsoft QuickBASIC. . . . . . . . . . . . . . . . . . . . . 18
        Microsoft QuickC. . . . . . . . . . . . . . . . . . . .. . . 19
        Microsoft Visual Basic pour DOS. . . . . . . . . . . . . . . . 20
        Microsoft Visual C ++.  .  .  .  .  .  .  .  .  .  .  .  .. . .. . . . .  21
        Edition 32 bits de Microsoft Visual C. . . . . . . . . . . . .  .  22
        Puissance C.  .  .. . . . . . .  .  .  .  .  .  .  .  .. . . . . . . . . . 23
        Turbo C et Turbo C ++.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  24
        Turbo Pascal.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  25
        WATCOM C / C ++.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  26
        WATCOM C32 pour DOS.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  26
        Zortech C ++.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  27
   Pilote Fastgraph / Light Vidéo.  .  .  .  .. . . . . . . . . . . . . . . 28

Chapitre 2 PC et PS / 2 Modes vidéo. . . . . . . . . . . . . . . . . . . 29

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

   Modes de texte.  .. . . . . . . . . . . . . . . . . . . . . . . . . . . 31
   Modes graphiques. . . . . . . . . . . . . . . . . . . . . . . . . . . 33
        CGA Modes graphiques. . . . . . . . . . . . . . . . . . . . . . 33
        Tandy 1000 et PCjr Modes graphiques. . . .  .  .  .. . . . . . . 34
        Hercules Modes graphiques. . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  34
        EGA Modes graphiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  35
        VGA et MCGA Modes graphiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  36
        VGA étendu (XVGA) Modes graphiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  37
        SuperVGA Modes (SVGA) Graphiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  38

Chapitre 3 Initialisation de l'environnement vidéo. . . . . . . . . . . . . . 41

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  42
   Mise en place d'un mode texte.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  42
   43 lignes et 50 lignes Modes de texte.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  45
   L'établissement d'un mode graphique.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  46
   SuperVGA Modes graphiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  50
   Résumé de la vidéo Initialisation Routines.  .  .  .  .  .  .  .  .  .  .  .  .  .  55


iii   

Chapitre 4 Systèmes de coordonnées. . . . . . . . . . . . . . . . . . . . . . 57

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  58
   Espace de caractère.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  58
   Espace de l'écran.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  59
   Viewports.  .  .  .  .  .  .. . . . . . . . . .. . . . . . . . . .  .  .  60
   Mondiale de l'espace.  . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  62
   Routines de conversion.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  64
   Résumé des coordonnées Routines.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  64

Chapitre 5 L'utilisation de la couleur. . . . . . . . . . . . . . . . . . . . . . . 67

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  68
   Modes de texte.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  68
        Couleur Modes de texte.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  68
        Mode texte monochrome.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  69
   Modes graphiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  70
        CGA Modes couleur.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  70
        Mode Two-Color CGA.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  72
        Tandy et modes PCjr.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  73
        Mode de Hercules.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  74
        Mode Faible résolution Hercules.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  75
        EGA Modes de 200 lignes.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  76
        Monochrome Mode EGA.  .  .  .  .  .  .  .. . . . . . . . .. . . . . 78
        EGA Enhanced Mode. . . . . . . . . . . . . . . . . . . . . . . 79
        VGA et le mode deux couleurs MCGA. . . . . . . . . . . . . . . . . . 81
        VGA / SVGA Modes de 16 couleurs. . . . . . . . . . . . . . . . . . . . 83
        Modes de 256 couleurs. . . . . . . . . . . . . . . . . . . . . . . . 83
   Utilisation de la vidéo Registres du CAD dans les modes EGA. . . . . . . . . . . . . . . 87
   Cartographie couleur RVB. . . . . . . . . . . . . . . . . . . . . . . . . 89
   Définition de tous les registres de la palette. . . . . . . . . . . . . . . . . . . 90
   Couleurs virtuelles. . . . . . . . . . . . . . . . . . . . . . . . . . . 90
   A Multiple-Mode Exemple. . . . . . . . . . . . . . . . . . . . . . 92
   Résumé des Routines Color-connexes. . . . . . . . . . . . . . . . . 94

Chapitre 6 Fundamentals graphiques. . . . . . . . . . . . . . . . . . . . 97

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

   Effacement de l'écran. . . . . . . . . . . . . . . . . . . . . . . . 98
   Clipping. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
   Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
   Le curseur graphique. . . . . . . . . . . . . . . . . . . . . . . . 100
   Lignes solides. . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
   Lignes en pointillé . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
   Polygones.  .  .. . . . . . . . .. . . . . . . . . . . . . . . . . . 104
   Les cercles et les Ellipses. . . . . . .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  107
   Rectangles solides.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  109
   Rectangles vacants.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  110
   Dithered Rectangles.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  112
   Région Fill.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  119
   Résumé des fondamentaux Routines graphiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  121

Chapitre 7 Caractère d'affichage Routines. . . . . . . . . . . . . . . . . . 125

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  126
   Espace de caractère.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .. . . . . 126
   Hardware Caractères. . . . . . . . . . . . . . . . . . . . . . . . 127
   Hauteur du personnage. . . . . . . . . . . . . . . . . . . . . . . . . . 135
   Routines de conversion. . . . . . . . . . . . . . . . . . . . . . . . 137
   Logiciel Caractères. . . . . . . . . . . . . . . . . . . . . . . . 138


iv   
   Personnages bitmap. . . . . . . . . . . . . . . . . . . . . . . . 143
   Résumé de l'affichage de caractères Routines. . . . . . . . . . . . . . . 144

Chapitre 8 Pages vidéo et Tampons virtuels. . . . . . . . . . . . . . . 147

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

   Pages physiques et Pages virtuelles. . . . . . . . . . . . . . . . . . 148
   Pages ayant une signification particulière. . . . . . . . . . . . . . . . . . . . 150
   Quelques exemples simples. . . . . . . . . . . . . . . . . . . . . . . . 150
   Curseurs de texte. . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
   Obtention vidéo Informations sur la page. . . . . . . . . . . . . . . . . . 158
   Considérations pour les pages virtuelles. . . . . . . . . . . . . . . . . . 159
   Considérations pour Pages SuperVGA. . . . . . . . . . . . . . . . . 160
   Pages logiques. . . . . . . . . . . . . . . . . . . . . . . . . . . 161
   Extended Pages vidéo. . . . . . . . . . . . . . . . . . . . . . . . 163
   Vidéo page Redimensionnement. . . . . . . . . . . . . . . . . . . . . . . . 166
   Préserver la vidéo Contenu de la page sur des commutateurs de mode. . . . . . . . 167
   Contrôle Allocation Page. . . . . . . . . . . . . . . . . . . . 169
   Tampons virtuels. . . . . . . . . . . . . . . . . . . . . . . . . . 171
   Résumé de la vidéo et de la page Virtual Routines Buffer. . . . . . . . . 180

Chapitre 9 fichiers image. . . . . . . . . . . . . . . . . . . . . . . . . 183

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184

   Fichiers PCX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
   Fichiers GIF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
   fichiers FLI et FLC. . . . . . . . . . . . . . . . . . . . . . . . . 192
   Pixel Fichiers Run. . . . . . . . . . . . . . . . . . . . . . . . . . 196
   Afficher Patterns. . . . . . . . . . . . . . . . . . . . . . . . . . 200
   Contrôle de l'image Buffer Size. . . . . . . . . . . . . . . . . 206
   Résumé des Routines de fichier image. . . . . . . . . . . . . . . . . . . 208

Chapitre 10 Images bitmap. . . . . . . . . . . . . . . . . . . . . . 211

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

   Mode-indépendant des images bitmap. . . . . . . . . . . . . . . . . 212
   Mode-spécifique des images bitmap. . . . . . . . . . . . . . . . . . . 217
        Images régulières. . . . . . . . . . . . . . . . . . . . . . . . 217
        Images détourées. . . . . . . . . . . . . . . . . . . . . . . . 225
        Images Inversée. . . . . . . . . . . . . . . . . . . . . . . . 225
        Images détourées Inversée. . . . . . . . . . . . . . . . . . . . 226
        Images Sans pixels transparents. . . . . . . . . . . . . . . 226
        Quelques exemples . . . . . . . . . . . . . . . . . . . . . . . . . 226
   Récupération d'images. . . . . . . . . . . . . . . . . . . . . . . . . 229
   Inversant bitmaps. . . . . . . . . . . . . . . . . . . . . . . . . 234
   Conversion de bitmaps spécifiques à chaque mode. . . . . . . . . . . . . . . . . . 236
   Bitmap Scaling et Shearing. . . . . . . . . . . . . . . . . . . . 239
   Pixel Plans Run. . . . . . . . . . . . . . . . . . . . . . . . . . . 244
   Cartes masquants. . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
   Résumé de l'image bitmap d'affichage Routines. . . . . . . . . . . . 251

Chapitre 11 Routines Bloc de transfert. . . . . . . . . . . . . . . . . . . 255

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

   Plein transfert. . . . . . . . . . . . . . . . . . . . . . . . . 256
   Limites d'octets. . . . . . . . . . . . . . . . . . . . . . . . . . 257
   Banques SVGA double. . . . . . . . . . . . . . . . . . . . . . . . . . 259
   La vidéo "Hidden" page.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  259
   Sauvegarde et restauration de blocs.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  259
   A Plus Routine Block Transfer général.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  262


v   
   Routines Bloc de transfert pour Tampons virtuels.  .  .  .  .  .  .  .  .  .  .  .  266
   Blocs avec les couleurs transparentes.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  267
   Transferts de blocs transparents pour Tampons virtuels.  .  .  .  .  .  .  .  .  .  269
   Transfert de blocs vers et depuis la mémoire conventionnelle.  .  .  .  .  .  .  .  270
   Résumé des programmes de transfert de bloc.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  271

Chapitre 12 Techniques d'animation. . . . . . . . . . . . . . . . . . . . 273

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  274
   Une simple animation.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  274
   XOR Animation.  .  .  .  .  .  .  .  .  .  .  .. . . . . . . . . . . . . . . 276
   Animation cadre statique. . . . . . . . . . . . . . . . . . . . . . . 278
   Animation Dynamic Frame. . . . . . . . . . . . . . . . . . . . . . 280
   Flipping page. . . . . . . . . . . . . . . . . . . . . . . . . . . 282
   Un exemple d'animation: Le Fastgraph Fish Tank.  .  .  .  .  .  .  .  .  .  .  284
   Résumé des Techniques d'animation.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  284

Chapitre 13 Effets spéciaux. . . . . . . . . . . . . . . . . . . . . . . 287

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  288
   Dissoudre de l'écran.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  288
   Défilement.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  290
   Modification de l'origine de l'écran.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  293
   Panning Avec Tampons Virtuels.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  296
   Écran divisé .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  298
   Résumé des effets spéciaux Routines.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  300

Chapitre 14 Support de périphériques d'entrée. . . . . . . . . . . . . . . . . . . . 301

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  302
   Keyboard Support.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  302
        Frappes de lecture.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  304
        Test et réglage États clés.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  305
        Low-Level Keyboard Handler.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  307
   Mouse Support.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  309
        Initialisation de la souris.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  309
        XVGA et SVGA Souris Considérations.  .  .  .  .  .  .  .  .  .  .  .  .  .  310
        Contrôle du curseur de la souris.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  311
        Indication de l'état de la souris.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  313
        Définir le curseur de la souris.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  315
   Soutien Joystick.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  323
        Initialisation Joysticks.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  323
        Rapports Joystick Etat.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  324
        Keyboard Emulation.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  325
        Considérations Joystick spéciales.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  326
   Résumé des Routines d'entrée.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  326

Chapitre 15 Effets sonores. . . . . . . . . . . . . . . . . . . . . . . . 329

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  330
   Sources sonores.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  330
   Synchrone Sound.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  330
   Asynchronous Sound.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  335
   Résumé des Routines sonores.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  340

Chapitre 16 Timing du programme. . . . . . . . . . . . . . . . . . . . . . . 343

Aperçu .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  344
   Real-Time Routines.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  344
   Routines dépendant de la vitesse du système.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  345
   Résumé des Routines Timing.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  347


vi   

Chapitre 17 Divers Routines. . . . . .. . . . . . . . . . . . . 349

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350

   Détermination de la mémoire disponible. . . . . . . . . . . . . . . . . . . . 350
   Choisir la fonction Mise à jour vidéo mémoire. . . . . . . . . . . . . 351
   Contrôle vertical Retrace synchronisation. . . . . . . . . . . . 352
   Externe Commutation SVGA Bank. . . . . . . . . . . . . . . . . . . . 353
   Sauvegarde et restauration de l'État vidéo. . . . . . . . . . . . . . . . 353
   Résumé des divers Routines. . . . . . . . . . . . . . . . . 354

Annexe A Utilitaires Fastgraph. . . . . . . . . . . . . . . . . . . . . 355

Aperçu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356

   INSTANTANÉ Utility. . . . . . . . . . . . . . . . . . . . . . . . . . 356
   Utilitaire CLIP. . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
   CONVERT Utility. . . . . . . . . . . . . . . . . . . . . . . . . . 358
   EDITSPR Utility. . . . . . . . . . . . . . . . . . . . . . . . . . 359
   GrabRGB Utility. . . . . . . . . . . . . . . . . . . . . . . . . . 359
   HERCFIX Utility. . . . . . . . . . . . . . . . . . . . . . . . . . 360
   PCXHEAD Utility. . . . . . . . . . . . . . . . . . . . . . . . . . 361

Annexe B Utilisation de Fastgraph de langage d'assemblage. . . . . . . . . . . 363

Annexe C Interruptions et Fastgraph. . . . . . . . . . . . . . . . . . 367

Les interruptions Utilisé par Fastgraph. . . . . . . . . .. . . . . . . . . . 368

   L'extension du temps d'interruption de journée. . . . . . . . . .  .. . . . . 368

Table des matières D Annexe des bibliothèques du compilateur spécifique. .. . . . . . . 373

Annexe E Contenu des fichiers Unité Pascal. . . . . . . . . . . . . . 375

Annexe F Intégration de Fastgraph avec d'autres logiciels graphiques. . . . . 379

Annexe G Conversion des programmes en mode protégé. . . . . . . . . . . . 381

Mode protégé Initialisation.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  382
   Considérations pour les pages logiques.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  382
   Considérations pour Tampons virtuels.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  382
   Définition curseur de la souris.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  382
   Types de données FORTRAN.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  383
   Incompatible comportement du mode réel.  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  383

Annexe H Image File Formats Header. . . . . . . . . . . . . . . . . . 385





vii   
















viii   



Chapitre 1


Introduction

2 Fastgraph utilisateur


Qu'est-ce que Fastgraph?

Fastgraph est une bibliothèque de plus de 275 routines hautement optimisées

sont appelable de haut niveau et des programmes de langues d'assemblage fonctionnant sous les systèmes d'exploitation MS-DOS ou PC-DOS. Cette collection de routines fournit un programmeur avec éprouvées, des outils puissants pour prendre le commandement du PC et PS / 2 environnement vidéo. En plus de son support vidéo, Fastgraph comprend également des routines pour effectuer le clavier, la souris, et le contrôle de la manette, ainsi que musique et de son capacités. Fastgraph est un outil de développement idéal pour le divertissement et les logiciels éducatifs, produits graphiques de présentation, les applications scientifiques et d'ingénierie, CAD / CAM, animation, ou toute autre application qui exige des graphiques robustes.

Comme son nom l'indique, la caractéristique la plus notable de Fastgraph est sa vitesse.

La quasi-totalité des Fastgraph est écrit en langage d'assemblage, et chaque routine a été optimisé à la main pour fournir une performance maximale. Les bibliothèques de mode protégé de Fastgraph tirer parti des fonctionnalités offertes par les jeux d'instructions 80286 et 80386.

Fastgraph supporte tous les modes de texte et de graphiques vidéo standard utilisés par

le PC IBM et les systèmes compatibles (PC, PC / XT, et PC / AT, 80386, 80486 et Pentium) et IBM PS / 2 famille. En outre, Fastgraph fournit un support pour six SuperVGA (SVGA) modes graphiques, quatre VGA étendu (XVGA) modes graphiques, et un mode graphique 16 couleurs unique pour Tandy 1000 ordinateurs de la série et la PCjr. Même si le mode de la carte graphique Hercules graphique est pas une norme IBM, sa popularité unique a fait un standard de facto, et pour cette raison Fastgraph soutient également. Au total, Fastgraph prend en charge 23 modes graphiques et 5 modes de texte. Une discussion complète de ces modes vidéo apparaît dans le chapitre suivant.


Fastgraph / Light

Fastgraph / Light est un sous-ensemble de Fastgraph. Il comprend l'ensemble des Fastgraph de

caractéristiques, sauf les routines de support de fichiers GIF, l'espace mondial redéfinissable système de coordonnées, et les routines relatives aux caractères de logiciels. Les programmes créés en utilisant Fastgraph / Light sont 100% code source compatible avec Fastgraph.

La différence la plus importante entre Fastgraph / Lumière et Fastgraph est

la méthode de l'exécution d'un programme créé avec les deux produits. Avec Fastgraph, l'une de ses routines utilisées dans votre programme sont liés directement dans le fichier EXE résultant. Avec Fastgraph / Lumière, cependant, ce n'est pas le cas. Au lieu de cela, les routines Fastgraph / lumière fournissent une interface à un pilote externe, appelé le pilote Fastgraph / Light Video, qui doit être chargé séparément avant d'exécuter des programmes qui appellent des routines Fastgraph / Lumière. Voir la dernière section de ce chapitre pour plus d'informations.

Une autre différence importante entre Fastgraph et Fastgraph / Light est le

le nom de la bibliothèque (LIB) fichiers. Toutes les bibliothèques Fastgraph commencent par les deux personnages FG, tandis que les bibliothèques Fastgraph / lumière équivalentes commencent par les trois personnages FGL. Par exemple, FGS.LIB est le petit modèle de bibliothèque Fastgraph utilisé avec la plupart des compilateurs C, mais FGLS.LIB est le nom équivalent bibliothèque Fastgraph / Light. Notez que les fichiers de l'unité Pascal commencent toujours par FG, si vous utilisez Fastgraph ou Fastgraph / Light.

Chapitre 1: Introduction 3


Dans le Guide de l'utilisateur Fastgraph et l'accompagnement Fastgraph Référence

Manuel, les références à Fastgraph appliquent également à Fastgraph / Light, sauf indication contraire.


connaissances requises

Fastgraph est un outil de programmation, ce qui signifie que les programmeurs sont son but

public.Pour cette raison, le manuel Guide et Fastgraph Référence de l'utilisateur Fastgraph suppose que vous avez une connaissance de la programmation. En outre, une connaissance de convertir des nombres entre binaire, décimal et hexadécimal est supposé.

Pratiquement tous les exemples de ce manuel sont écrites dans le C

langage de programmation, donc une connaissance de C serait particulièrement utile. Les exemples évitent intentionnellement utilisant l'une des caractéristiques et des idiomes de C qui pourraient ne pas être évident pour un programmeur familier avec C. Si vous programmez en mode réel, ne pas être confondu par le fait que tous les exemples appellent la routine de fg_initpm de Fastgraph pour initialisation du mode protégé - en mode réel, fg_initpm retourne simplement à l'appelant. Enfin, nous aimerions souligner que les exemples doivent être lus pas par eux-mêmes, mais dans le cadre du texte qui l'entoure.


compilateurs pris en charge

Vous pouvez utiliser Fastgraph avec tous les compilateurs ou assembleurs qui utilisent le même

appel et les conventions de nommage que la petite, moyenne, grande ou modèles de mémoire plats des compilateurs pris en charge. la programmation en langue mixte est autorisée si soutenu par le traducteur de langue, éditeur de liens et d'extension DOS utilisé. Fastgraph prend en charge les compilateurs suivants:

* Borland C ++ (version 2.0 ou ultérieure)
   * Borland Pascal (version 7.0 ou ultérieure)
   * MetaWare haut C / C ++ (version 3.0 ou ultérieure)
   * Système de développement professionnel BASIC Microsoft (version 7.0 ou 7.1)
   * Microsoft C / C ++ (version 5.1 ou ultérieure)
   * Microsoft FORTRAN (version 4.0 ou ultérieure)
   * Microsoft FORTRAN PowerStation (version 1.0 ou ultérieure)
   * Microsoft QuickBASIC (version 4.0 ou ultérieure)
   * Microsoft QuickC (version 2.0 ou ultérieure)
   * Microsoft Visual Basic pour DOS (version 1.0 ou ultérieure)
   * Microsoft Visual C ++ (version 1.0 ou ultérieure)
   * Microsoft Visual C ++ Edition 32 bits (version 1.0 ou ultérieure)
   * Puissance C (version 2.0 ou ultérieure)
   * Turbo C (version 2.0 ou ultérieure)
   * Turbo C ++ (version 1.0 ou ultérieure)
   * Turbo Pascal (version 6.0 ou ultérieure)
   * WATCOM C / C ++ (version 9.5 ou ultérieure)
   * WATCOM C32 pour DOS (version 9.5 ou ultérieure)
   * Zortech C ++ (version 3.0 ou ultérieure)

Les numéros de version répertoriés sont les versions du compilateur sous lequel Fastgraph a été développé et testé. Fastgraph peut ou peut ne pas fonctionner avec les versions antérieures de ces compilateurs. Comme nous ajoutons constamment de soutien pour les nouveaux compilateurs, s'il vous plaît vérifier le fichier READ.ME dans le répertoire \ FG pour les ajouts possibles au Guide de l'utilisateur ci-dessus 4 Fastgraph

liste. L'utilisation de Fastgraph des programmes de langue d'assemblage est abordée dans l'annexe B.


En mode réel, mode protégé, et DOS Extenders

DOS est fondamentalement un système d'exploitation en mode réel. le mode réel est le natif

(Et seulement) le mode de fonctionnement des 8086 et 8088 microprocesseurs, sur lesquels étaient fondés les systèmes PC / XT IBM PC et. Bien que ces processeurs à condition que la capacité de traiter un mégaoctet de mémoire, IBM a réservé la 384K supérieure de cette adresse un espace de mégaoctet pour des choses telles que la mémoire vidéo et le BIOS ROM. Cela a laissé un maximum de 640K pour les applications DOS.

plus tard microprocesseurs (80286, 80386, 80486 et Pentium d'Intel) fournissent

un deuxième mode de fonctionnement appelé mode protégé. Peut-être l'aspect le plus important du mode protégé est sa capacité à utiliser beaucoup plus de mémoire. Lors de l'exécution en mode protégé, le processeur 16-bit 80286 a une adressabilité 16 méga-octets, tandis que les 32 bits 80386 et plus tard les processeurs peuvent répondre à quatre gigaoctets. services de mémoire étendue et étendue fournissent un accès limité à ce plus grand espace d'adresse, mais un programme doit fonctionner en mode protégé si elle veut traiter cette mémoire comme la mémoire DOS conventionnelle. Parce que DOS est un véritable système d'exploitation en mode, les applications DOS en cours d'exécution sur 80286 et plus tard les processeurs sont encore limités à ubiquitaire 640K barrière DOS. Dans ce cas, ces systèmes fonctionnent simplement comme plus rapides 8086 ou 8088 systèmes.

Quand un système compatible DOS protégé fonctionnement du mode ne semble pas, DOS

extendeurs sont arrivés à la place. Une extension DOS est un produit, un «système mini-exploitation" si vous voulez, qui peut exécuter des applications en mode protégé sous DOS. L'extension DOS accomplit cela en exécutant un programme stub en mode réel qui commute le processeur en mode protégé et passe le contrôle de votre programme. Votre programme continue à fonctionner en mode protégé jusqu'à ce qu'il délivre un service BIOS ou DOS comme un dossier de demande d'E / S. L'extenseur passe alors de nouveau en mode réel pour satisfaire la demande, et à la fin revient en mode protégé. Lorsque votre programme se termine, l'extension DOS repasse en mode réel et renvoie le contrôle au DOS. Ceci est bien sûr une simplification excessive de la façon dont une extension DOS fonctionne, mais ceux-ci derrière les tâches les scènes sont transparentes aux utilisateurs finaux de votre programme. De leur point de vue, une application DOS étendue exécute comme toute application ordinaire DOS.

extendeurs DOS viennent en deux saveurs: 16-bit et 32-bit. Programmes écrits

16-bit extendeurs DOS nécessitent au moins un système à base de 80286, tandis que ceux écrits pour extendeurs 32 bits nécessitent un 80386 ou mieux. Beaucoup de compilateurs en mode réel peuvent créer 16 bits étendu des applications DOS, mais vous aurez besoin des compilateurs spéciaux 32 bits pour créer 32 bits des applications DOS étendues. Fastgraph prend en charge les 16 bits extendeurs DOS suivants:

* Blinker
   * Borland Pascal 7 (construit en extender DPMI)
   * Borland PowerPack pour DOS
   * Phar Lap 286 | Dos-Extender SDK
   * Phar Lap 286 | Dos-Extender Lite
   * Rational Systems DOS / 16M

Fastgraph prend en charge les 32 bits extendeurs DOS suivants:

* Borland PowerPack pour DOS
   * Causeway
                                                Chapitre 1: Introduction 5
* DOSXMSF (fourni avec Microsoft FORTRAN PowerStation)   
   * X 32 FlashTek
   * Phar Lap SDK TNT Dos-Extender (anciennement 386 | Dos-Extender SDK)
   * Phar Lap TNT Dos-Extender Lite
   * Rational Systems DOS / 4G
   * Rational Systems DOS / G4G (fourni avec 32 bits compilateurs Watcom)
   * Rational Systems DOS / G4G Professional

S'il vous plaît vérifier le fichier READ.ME dans le répertoire \ FG pour les ajouts possibles aux listes ci-dessus.

Notez que certains extendeurs DOS exigent des frais de licence ou les paiements de redevances

avant que vous pouvez inclure ou lier leurs composants avec des applications que vous distribuez. Nous vous recommandons de vérifier vos manuels d'extension DOS ou contrat de licence pour plus de détails, ou si vous n'êtes pas sûr, contacter directement le fabricant d'extension DOS.

Modèles de mémoire

pris en charge en mode réel de C, C ++ et Fortran de Fastgraph compilateurs offrent

plusieurs modèles de mémoire. Un modèle de mémoire définit la façon dont la mémoire est mis en place pour le code et les données des segments d'un programme. Fastgraph comprend des bibliothèques réelles de mode pour les petites, moyennes et grandes modèles de mémoire et les bibliothèques en mode protégé pour les environnements 16 bits et 32 ​​bits. Les bibliothèques protégées en mode 16 bits utilisent une extension du modèle de mémoire, tandis que les bibliothèques 32 bits utilisent un modèle de mémoire plat spécial.

Le petit modèle de mémoire permet un segment de code et un segment de données.

Les programmes qui utilisent le petit modèle peut ainsi avoir un maximum de 64K octets de code et 64K octets de données. Parce que le petit modèle met en œuvre des instructions d'appel et des références de données à travers près de pointeurs, il produit le code le plus efficace des trois modèles de mémoire en mode réel pris en charge. Le petit modèle de mémoire est spécifique aux véritables compilateurs de mode.

Le modèle de support de mémoire permet de multiples segments de code et une donnée

segment.Les programmes qui utilisent le modèle moyen ont donc aucune limite de compilateur imposée à la taille du code (bien que pas un segment peut dépasser 64K octets) et un maximum de 64K octets de données. Comme le petit modèle, le modèle moyen met en œuvre des références de données par le biais de près de pointeurs, mais il met en œuvre des instructions d'appel par le biais de pointeurs loin. L'utilisation de pointeurs far ajoute deux octets de code et 13 cycles d'horloge pour chaque appel de sous-programme. Le modèle moyen est un choix populaire pour les programmes en mode réel et est spécifique aux véritables compilateurs de mode.

Le grand modèle de mémoire prend en charge le code et de données multiples segments.  Programmes

qui utilisent le grand modèle ne pas avoir de limites du compilateur imposé pour code et de données de tailles. Toutefois, aucun segment de code ou de données unique peut dépasser 64K octets. Parce que le grand modèle met en œuvre des instructions d'appel et les références de données via les pointeurs loin, il produit le code moins efficace des trois modèles de mémoire pris en charge. En mode réel, la taille totale de tous les codes et les segments de données est limité par la barrière DOS 640K, mais en réalité, la vraie limite sera un peu moins en fonction de la configuration et les programmes résidents du système cible. En mode protégé 16 bits, la taille totale de tous les codes et les segments de données peut atteindre 16 mégaoctets, bien que personne ne peut dépasser le segment 64K octets.

Le modèle de mémoire plat permet un segment de code et un segment de données,

tout comme le petit modèle de mémoire. Le modèle plat diffère en ce que le Guide du secteur 6 Fastgraph utilisateur


tailles peuvent être jusqu'à quatre gigaoctets au lieu de 64K. Par défaut, le modèle plat implémente instructions d'appel et les références de données à 32 bits près de pointeurs, ce qui élimine pratiquement le besoin de segments. Le modèle de mémoire plat est spécifique à 32 bits compilateurs en mode protégé.

Pour plus d'informations sur les modèles de mémoire, s'il vous plaît se référer à l'utilisateur de

guide ou manuel de référence fourni avec votre compilateur.


Installation Fastgraph

Cette section explique comment utiliser le programme d'installation pour charger Fastgraph

(Ou Fastgraph / Light) et ses fichiers associés sur un disque dur. Le programme d'installation vous permet de sélectionner les compilateurs, les modèles de mémoire, et DOS extenders que vous souhaitez utiliser avec Fastgraph. Il vous donne également la possibilité de charger de nombreux exemples de programmes Fastgraph spécifiques aux compilateurs de votre choix.

Avant de commencer l'installation, nous vous recommandons d'utiliser les commandes DOS

COPY ou DISKCOPY de faire des copies de travail des disques de distribution Fastgraph (reportez-vous à votre manuel de référence DOS si vous n'êtes pas familier avec ces commandes). Une fois que vous avez créé les copies de travail, stocker les disques d'origine dans un endroit sûr. Installez Fastgraph des copies de travail que vous venez de créer.

Pour plus de simplicité, nous supposerons que vous installez Fastgraph du

lecteur de disquette A: le disque dur C :, mais bien sûr vous pouvez utiliser tous les disques disponibles. Le disque de distribution Fastgraph étiqueté Installation and Utilities contient INSTALLER programme de Fastgraph. Placez ce disque dans le lecteur A:, assurez-A: votre lecteur en cours, et entrez la commande INSTALLER, comme indiqué ici:

C> A:
                                A> INSTALLER

De ce point, il suffit de suivre les instructions sur chaque écran. A tout moment, vous pouvez appuyer sur la touche Echap pour annuler l'installation.

Le programme d'installation vous demandera les compilateurs, les modèles de mémoire, et

DOS extenders vous allez utiliser avec Fastgraph, ainsi que les noms de répertoires pour les services publics Fastgraph, les bibliothèques, et inclure des fichiers. Pour les services publics, le répertoire par défaut est C: \ FG. Pour les fichiers à inclure et les bibliothèques, nous vous recommandons d'utiliser des répertoires où le compilateur que vous avez choisi normalement recherches pour de tels fichiers. INSTALLER va essayer de déterminer automatiquement ces répertoires et les proposer comme valeurs par défaut.

Vous pouvez installer le support pour les compilateurs supplémentaires, des modèles de mémoire, ou DOS

extendeurs à tout moment. Si vous choisissez de le faire, vous devez utiliser la commande INSTALLER / L pour éviter la copie des fichiers communs à tous les environnements.


Le fichier READ.ME

Le fichier READ.ME contient des ajouts et des modifications qui peuvent avoir été faites

à Fastgraph depuis la publication des manuels. Nous vous encourageons à examiner le fichier READ.ME immédiatement après l'installation de Fastgraph. READ.ME est un fichier texte ASCII, adapté à une imprimante ou d'éditeur de texte. Le programme d'installation place le fichier READ.ME dans le répertoire des utilitaires Fastgraph (C: \ FG par défaut).

Chapitre 1: Introduction 7


Le fichier WHATS.NEW

Le fichier WHATS.NEW contient des informations sur les nouvelles fonctionnalités ajoutées dans

Fastgraph version 4.0. Les programmeurs qui ont utilisé des versions antérieures de Fastgraph peuvent vouloir examiner le fichier WHATS.NEW apprendre de nouvelles modifications de fonctionnalités et possibles de Fastgraph nécessaires lors de la conversion des applications à la version 4.0. WHATS.NEW est un fichier texte ASCII, adapté à une imprimante ou d'éditeur de texte. Le programme d'installation place le fichier WHATS.NEW dans le répertoire des utilitaires Fastgraph (C: \ FG par défaut).


Conventions de nommage Fastgraph

Les noms de toutes les routines Fastgraph commencent par les trois caractères

"Fg_". Ce préfixe permet d'identifier les routines Fastgraph dans un programme, et il permet également de réduire les risques de conflits de noms qui pourraient autrement se produire entre Fastgraph et d'autres bibliothèques de tiers.

Parce que BASIC ne permet pas de soulignement dans les identificateurs, le BASIC

versions de routines Fastgraph commencent avec les deux caractères "FG". Par exemple, la routine est appelée fg_version FGversion dans les bibliothèques de base. Toutes les références futures routines Fastgraph dans le Guide de l'utilisateur Fastgraph et le Manuel de référence Fastgraph utiliseront la convention de nommage fg_ au lieu des noms BASIC.


Compilation et liaison

Pour construire un exécutable (EXE) pour un programme qui utilise Fastgraph

routines, d'abord compiler ou assembler le programme en utilisant l'un des modèles de mémoire pris en charge. Cette étape produit un fichier objet, qui vous liez puis avec une ou plusieurs bibliothèques Fastgraph (ou les fichiers de l'unité Pascal) et éventuellement d'autres bibliothèques pour produire un fichier exécutable. Lors de la création des exécutables en mode protégé, les étapes de liaison supplémentaires peuvent être nécessaires, comme décrit dans votre compilateur ou DOS manuels d'extension. Les bibliothèques Fastgraph ou les fichiers de l'unité Pascal doivent résider dans un répertoire où le lieur recherche normalement pour de tels fichiers.

Exemple 1-1 utilise la fg_version routine Fastgraph pour afficher la version

numéro de votre copie de Fastgraph. Il utilise également une autre routine Fastgraph, fg_initpm, de mettre en place la protection du noyau de mode de Fastgraph pour l'extension DOS sélectionné (en utilisant le mode réel bibliothèques Fastgraph, fg_initpm ne fait rien). Les versions de ce programme sont présentés pour chaque langage de haut niveau Fastgraph prend en charge: C / C ++, BASIC, FORTRAN et Pascal. Si vous avez chargé les programmes d'exemple lorsque vous avez installé Fastgraph, les fichiers \ FG \ EXAMPLES \ 01-01.C, 01-01.BAS, 01-01.FOR et 01-01.PAS contiennent le code source pour ces exemples. Vous pouvez les utiliser pour tester la compilation et le processus de liaison pour les compilateurs que vous allez utiliser avec Fastgraph.

Exemple 1-1 (version C ++ / C).
 #include <fastgraf.h>
     #include <stdio.h>
     void main (void); 

Guide de l'utilisateur 8 Fastgraph


 void main ()
     {
       int majeur;
       int mineur;
 fg_initpm ();
       fg_version (et majeur, et mineur);
       printf ( "Ceci est la version% d% 2.2d de Fastgraph \ n..", majeur, mineur);
     }


Le FASTGRAF.H de fichier d'en-tête contient les prototypes ++ C et C de fonction pour

chaque routine Fastgraph. Il doit résider dans un répertoire où le compilateur recherche normalement pour les autres fichiers d'en-tête. Lors de la création de 32 bits des applications en mode protégé, FASTGRAF.H définira le symbole FG32. Ce symbole est utile pour contrôler la compilation conditionnelle lors de la création d'applications qui fonctionnent dans les deux environnements 16 bits et 32 ​​bits.

Exemple 1-1 (version BASIC).
REM $ INCLUDE: 'fastgraf.bi'
DEFINT AZ
FGversion Major, Minor
        Version! = Major + Minor * 0,01

PRINT UTILISATION "Ceci est la version # ## de Fastgraph.."; Version!

 FIN


Vous devez inclure les commandes DECLARE dans le fichier FASTGRAF.BI au

à partir de chaque module de base. Ce fichier doit résider dans un répertoire où le compilateur recherche normalement pour les fichiers de BI, ou dans l'un des répertoires spécifiés par la variable d'environnement INCLUDE. Les commandes DECLARE dans ce fichier fournissent automatiquement la convention d'appel et convention de dénomination pour chaque routine Fastgraph. En outre, ils soulagent le programmeur BASIC des arguments distinctifs passés par valeur de ceux qui sont passés par référence.

Exemple 1-1 (version FORTRAN).
$ INCLUDE: '\ FG \ FASTGRAF.FI'
PROGRAMME PRINCIPAL
ENTIER MAJOR
          ENTIER MINOR
FG_INITPM CALL
          APPEL FG_VERSION (MAJOR, MINOR)
WRITE (6,10) MAJOR, MINOR
    10 FORMAT ( 'Ceci est une version ", I1,'. ', I2.2,' de Fastgraph. ')
ARRÊTEZ ' '   
                                                Chapitre 1: Introduction 9


 FIN


Vous devez inclure les états d'interface dans le fichier FASTGRAF.FI au

à partir de programmes FORTRAN (ce fichier doit résider dans le répertoire \ FG). Les états d'interface dans ce fichier fournissent automatiquement la convention d'appel et convention de dénomination pour chaque routine Fastgraph. En outre, ils soulagent le programmeur FORTRAN des arguments distinctifs passés par valeur de ceux qui sont passés par référence.

Exemple 1-1 (version Pascal).
programme principal;
     utilise fgmain;
var
       Major: integer;
       Minor: integer;
commencer
       fg_initpm;
       fg_version (Major, Minor);
       writeln ( 'Ceci est une version', Major, Minor: 2, 'de Fastgraph.' '.');
      fin.


programmes Pascal qui utilisent Fastgraph ou Fastgraph / Light doit inclure une utilisation

déclaration précisant les noms des fichiers d'unités (fichiers TPU ou TPP) nécessaires dans le programme. Cette liste doit toujours inclure l'unité de fgmain; pour les programmes en mode protégé qui appellent GlobalAllocPtr, GlobalFreePtr, ou d'autres fonctions dans WinAPI, il doit également inclure l'unité de WinAPI. Tous les fichiers de l'unité doivent résider dans un répertoire où le compilateur recherche normalement pour de tels fichiers. Annexe E énumère les fonctions Fastgraph dans chaque unité.

Les sections suivantes présentent les procédures les plus simples pour la compilation d'un

programme et de le lier avec Fastgraph. L'information est présentée pour chaque compilateur supporté, par ordre alphabétique du nom du compilateur. Dans ce qui suit, les éléments entre crochets d'angle, tels que <source_file>, sont des espaces réservés pour les paramètres que vous devez fournir (le nom d'un fichier dans ce cas). Articles entre crochets, comme [/ E], sont facultatifs. Pour plus de simplicité, nous ne montrons les noms de bibliothèques Fastgraph. Si vous utilisez Fastgraph / Light, les noms de bibliothèques vont commencer par "FGL" au lieu de "FG". Par exemple, FGS.LIB est le mode réel petit modèle Fastgraph pour la plupart des compilateurs C, tandis que FGLS.LIB est la bibliothèque équivalente pour Fastgraph / Lumière. Notez que Fastgraph / Light ne supporte pas les environnements de mode protégé. Guide de l'utilisateur 10 Fastgraph


Borland C ++

Borland C ++ peut créer en mode réel, en mode protégé 16 bits et 32 ​​bits

applications en mode protégé (Borland C ++ 4.0 ou version ultérieure est nécessaire pour le mode protégé 32 bits). Vous pouvez compiler et lier les programmes directement à partir de la ligne de commande DOS ou de l'environnement de développement Borland C ++ intégré (IDE). Les bibliothèques Fastgraph suivants sont compatibles avec Borland C ++:

FGS.LIB en mode réel petit modèle bibliothèque générale
   FGM.LIB en mode réel moyen modèle bibliothèque générale
   FGL.LIB en mode réel grand modèle bibliothèque générale
   FGTCS.LIB en mode réel petit modèle bibliothèque auxiliaire
   FGTCM.LIB en mode réel moyen modèle bibliothèque auxiliaire
   FGTCL.LIB en mode réel grand modèle bibliothèque auxiliaire
   FG16.LIB 16 bits en mode protégé bibliothèque générale
   FG16BC.LIB 16 bits en mode protégé bibliothèque auxiliaire
   Bibliothèque de support d'extension FG16DPMI.LIB 16 bits DPMI compatible DOS
   FG16PHAR.LIB Phar Lap 286 | Dos-Extender Bibliothèque de support
   FG32.LIB 32 bits en mode protégé bibliothèque générale
   FG32BC.LIB 32 bits en mode protégé bibliothèque auxiliaire
   Bibliothèque de support d'extension FG32DPMI.LIB 32 bits DPMI compatible DOS
   FG32PHAR.LIB Phar Lap TNT | Bibliothèque de support Dos-Extender
Pour construire des applications en mode réel Fastgraph dans le Borland C ++ IDE, le

options de compilation doivent correspondre à l'un des modèles de mémoire disponibles de Fastgraph (petites, moyennes ou grandes). programmes protégés en mode 16 bits doivent utiliser le modèle de mémoire, tandis que les programmes protégés en mode 32 bits doivent être compilés comme des applications console. Dans tous les cas, vous devez également créer un fichier de projet qui comprend le nom de chaque C, CPP, et le fichier LIB requis par votre application (reportez-vous à vos manuels Borland C ++ pour obtenir des informations sur les fichiers de projet). Pour Borland C ++ 4.0 et au-dessus, le fichier de projet spécifie également la plate-forme: DOS pour les applications en mode réel, DOS (16-bit DPMI) pour des applications 16 bits en mode protégé, ou DOS (32-bit DPMI) pour le mode 32 bits protégé applications. Les dossiers de projet ne sont nécessaires que lorsque vous utilisez l'IDE.

Vous pouvez également compiler et lier les programmes de la ligne de commande DOS en utilisant

la BCC ou BCC32 commandes. Voici par exemple BCC et les commandes BCC32 pour compiler un programme Borland C ++ et en le reliant avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compiler- ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D.

Mode réel, petit modèle de mémoire:
      <Source_file> FGS.LIB [FGTCS.LIB] BCC
Mode réel, modèle de support de mémoire:
      <Source_file> FGM.LIB [FGTCM.LIB] BCC
Mode réel, grand modèle de mémoire:
      BCC -ml <source_file> FGL.LIB [FGTCL.LIB]
mode protégé 16 bits, extender Borland PowerPack DOS:
      BCC -ml -WX <source_file> FG16.LIB FG16DPMI.LIB [FG16BC.LIB]
mode protégé 16 bits, Phar Lap 286 | Dos-Extender:
      BCC286 <source_file> FG16.LIB FG16PHAR.LIB [FG16BC.LIB]   
                                               Chapitre 1: Introduction 11


mode protégé 32 bits, extender Borland PowerPack DOS:
      BCC32 -WX <source_file> FG32.LIB FG32DPMI.LIB [FG32BC.LIB]

Pour créer 16 bits protégées des programmes en mode de Borland C utilisant les systèmes DOS / 16M extender Rational, s'il vous plaît se référer au Guide de l'utilisateur DOS / 16M. Pour créer 32 bits protégées des programmes en mode de Borland C en utilisant le Phar Lap TNT | Dos-Extender, s'il vous plaît consulter le C de Phar Lap / Guide de l'utilisateur C de TNT Dos-Extender.

Pour plus d'informations sur les modèles de mémoire ou autre compilation et liaison

les options, s'il vous plaît consulter le Guide de l'utilisateur de Borland C, Borland PowerPack pour le Guide de l'utilisateur DOS, de Phar Lap Borland C ++ Guide de l'utilisateur à 286 Dos-Extender, ou le Guide de l'utilisateur DOS / 16M. Guide de l'utilisateur 12 Fastgraph


Borland Pascal

Borland Pascal peut créer en mode réel et en mode 16 bits protégé

applications.les applications en mode protégées peuvent être construites sans un tiers d'extension DOS, comme les extensions en mode protégé nécessaires sont mises en œuvre par le biais d'une interface en mode DOS protégé (DPMI) serveur et un gestionnaire d'exécution. Vous pouvez compiler en mode réel et les programmes en mode protégé directement à partir de la ligne de commande DOS ou à partir de l'environnement de développement intégré Borland Pascal (IDE).

Pour créer des applications Fastgraph dans le Borland Pascal IDE, il suffit de commencer la

IDE comme vous le feriez pour tout autre programme Pascal, en vérifiant que les fichiers d'unités Fastgraph résider dans l'un des répertoires listés dans "Unité Répertoires" l'option de l'IDE. Si vous créez une application en mode protégé de l'EDI, choisissez Compile | Target et sélectionnez «Application en mode protégé" de la boîte de dialogue Plate-forme cible.

Vous pouvez également compiler des programmes Borland Pascal de la ligne de commande DOS

en utilisant les BPC ou TPC commandes, comme indiqué ici. programmes en mode réel peuvent utiliser soit BPC ou PTC, alors que les programmes de mode protégé doivent utiliser BPC.

Mode réel:
      BPC <source_file>
      TPC <source_file>
16 bits en mode protégé:
      BPC / CP <source_file>
Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît

reportez-vous au Borland Pascal avec le Guide de l'utilisateur des objets.

Tous les exemples de programmes restants dans le Guide de l'utilisateur Fastgraph sont écrits

dans le langage de programmation C. Toutefois, lorsque vous installez Fastgraph pour Borland Pascal, la procédure d'installation copie les versions Pascal des exemples de programmes dans le répertoire \ FG \ EXEMPLES.

Chapitre 1: Introduction 13


MetaWare haut C / C ++

MetaWare haut C / C ++ est strictement un compilateur en mode protégé 32 bits.  Il

soutient le Phar Lap TNT | Dos-Extender SDK et l'extension des systèmes DOS / 4G Rational. Les bibliothèques Fastgraph suivants sont compatibles avec MetaWare haut C / C ++:

FG32.LIB 32 bits en mode protégé bibliothèque générale
   FG32HC.LIB 32 bits en mode protégé bibliothèque auxiliaire
   Bibliothèque de support d'extension FG32DPMI.LIB 32 bits DPMI compatible DOS
   FG32PHAR.LIB Phar Lap TNT | Bibliothèque de support Dos-Extender
Les programmes sont compilés et liés à partir de la ligne de commande DOS en utilisant la

commande HC386. Voici un exemple de commandes HC386 pour compiler un programme MetaWare haut C / C ++ et en le reliant avec Fastgraph. La bibliothèque auxiliaire spécifique au compilateur (FG32HC) ne doit être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D.

mode protégé 32 bits, Phar Lap TNT | Dos-Extender:
      HC386 <source_file> -lFG32 -lFG32PHAR [-lFG32HC] -nomap -onecase
32 bits en mode protégé, Rational extender Systems DOS / 4G:
      HC386 <source_file> -Hdos4g -lFG32 -lFG32DPMI [-lFG32HC]
Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît

consultez le Guide de l'MetaWare haut C / C ++ Programmer, le C de Phar Lap / C ++ Guide d'utilisation de TNT Dos-Extender, ou le manuel de l'utilisateur DOS / 4G. Guide de l'utilisateur 14 Fastgraph


Système de développement professionnel BASIC Microsoft

Vous pouvez compiler et lier système de développement professionnel BASIC Microsoft

(PDS) des programmes directement à partir de la ligne de commande DOS ou de l'environnement de programmation de PDS. Dans les deux cas, BASIC PDS crée toujours des programmes en mode réel. Les bibliothèques Fastgraph suivants sont compatibles avec PDS DE BASE:

 FGQBX.LIB bibliothèque autonome pour PDS DE BASE
    FGQBX.QLB bibliothèque rapide pour BASE PDS
 Pour créer des applications Fastgraph dans le PDS environnement de programmation, juste

spécifier le nom de la bibliothèque rapide FGQBX lors du démarrage PDS DE BASE:

 QBX / LFGQBX [<source_file>]

Vous devez utiliser la valeur par défaut "Far Strings" mise dans l'environnement PDS. Il n'y a pas de bibliothèques Fastgraph de chaîne près de disponibles pour BASE PDS.

 Pour compiler un programme BASIC PDS à partir de la ligne de commande DOS et le lien avec

Fastgraph, utilisez les commandes de la Colombie-Britannique et LINK:

 BC / Fs [/ O] <source_file>;
       LINK [/ E] <object_file> ,, NUL, FGQBX;

L'option / O sur la commande BC est recommandée car elle crée des fichiers EXE qui ne nécessitent pas le module run-time BASIC PDS. L'option de liaison / E est pas obligatoire mais va produire un fichier EXE plus petit si spécifié. Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît consulter le Guide de Microsoft BASIC Professional System Development Programmer.

 Tous les exemples de programmes restants dans le Guide de l'utilisateur Fastgraph sont écrits

dans le langage de programmation C. Toutefois, lorsque vous installez Fastgraph pour Microsoft BASIC PDS, la procédure d'installation copie les versions de base des exemples de programmes dans le répertoire \ FG \ EXEMPLES.

 Chapitre 1: Introduction 15


Microsoft C / C ++

 Microsoft C / C ++ peut créer en mode réel et en mode 16 bits protégé

applications. Pour le mode protégé, il prend en charge le Phar Lap 286 | Dos-Extender (deux SDK et Lite versions) et les systèmes DOS / 16M extender Rational. Les bibliothèques Fastgraph suivants sont compatibles avec Microsoft C / C ++:

 FGS.LIB en mode réel petit modèle bibliothèque générale
    FGM.LIB en mode réel moyen modèle bibliothèque générale
    FGL.LIB en mode réel grand modèle bibliothèque générale
    FGMSCS.LIB en mode réel petit modèle bibliothèque auxiliaire
    FGMSCM.LIB en mode réel moyen modèle bibliothèque auxiliaire
    FGMSCL.LIB en mode réel grand modèle bibliothèque auxiliaire
    FG16.LIB 16 bits en mode protégé bibliothèque générale
    FG16MSC.LIB 16 bits en mode protégé bibliothèque auxiliaire
    Bibliothèque de support d'extension FG16DPMI.LIB 16 bits DPMI compatible DOS
    FG16PHAR.LIB Phar Lap 286 | Dos-Extender Bibliothèque de support
 Les programmes sont compilés et liés à partir de la ligne de commande DOS en utilisant la CL

commander. Voici des exemples de commandes CL pour compiler un programme Microsoft C / C ++ et en le reliant avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compilateur ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D. Dans les exemples de mode réel, l'option de liaison / E est pas obligatoire mais va produire un fichier EXE plus petit si spécifié.

 Mode réel, petit modèle de mémoire:
       CL / AS <source_file> / link FGS.LIB [FGMSCS.LIB] [/ E]
 Mode réel, modèle de support de mémoire:
       CL / AM <source_file> / lien FGM.LIB [FGMSCM.LIB] [/ E]
 Mode réel, grand modèle de mémoire:
       CL / AL <source_file> / link FGL.LIB [FGMSCL.LIB] [/ E]
 mode 16 bits protégé, Phar Lap 286 SDK ou extender Lite:
       CL / AL / Lp <source_file> / link FG16.LIB FG16PHAR.LIB [FG16MSC.LIB]

Pour créer des programmes en mode Microsoft C / C ++ protégées utilisant les systèmes DOS / 16M extender Rational, s'il vous plaît se référer au Guide de l'utilisateur DOS / 16M.

 Pour plus d'informations sur les modèles de mémoire ou autre compilation et liaison

les options, s'il vous plaît se référer au Guide de l'utilisateur Microsoft C Optimisation du compilateur, Microsoft C & Guide de C de l'utilisateur 286 de Phar Lap | Dos-Extender, ou le Guide de l'utilisateur DOS / 16M. Guide de l'utilisateur 16 Fastgraph


Microsoft FORTRAN

 Microsoft FORTRAN crée des applications en mode réel.  La Fastgraph suivante

bibliothèques sont compatibles avec Microsoft FORTRAN:

 FGM.LIB en mode réel moyen modèle bibliothèque générale
    FGL.LIB en mode réel grand modèle bibliothèque générale
    FGMSFM.LIB en mode réel moyen modèle bibliothèque auxiliaire
    FGMSFL.LIB en mode réel grand modèle bibliothèque auxiliaire
 Les programmes sont compilés et liés à partir de la ligne de commande DOS en utilisant le FL

commander. Voici par exemple les commandes FL pour compiler un programme Microsoft FORTRAN et en le reliant avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compilateur ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D. L'option / E lieur ne sont pas nécessaires, mais produira un fichier EXE plus petit si spécifié.

 Moyen modèle de mémoire:
       FL / AM / FPi / 4I2 / 4NT <source_file> / lien FGM.LIB [FGMSFM.LIB] [/ E]
 Grand modèle de mémoire:
       FL / AL / FPi / 4I2 / 4NT <source_file> / link FGL.LIB [FGMSFL.LIB] [/ E]
 Pour plus d'informations sur les modèles de mémoire ou autre compilation et liaison

les options, s'il vous plaît se référer au Guide de l'utilisateur Microsoft FORTRAN Optimisation du compilateur.

 Tous les exemples de programmes restants dans le Guide de l'utilisateur Fastgraph sont écrits

dans le langage de programmation C. Toutefois, lorsque vous installez Fastgraph pour le compilateur Microsoft FORTRAN, les versions procédure d'installation copie FORTRAN des exemples de programmes dans le répertoire \ FG \ EXEMPLES.

 Chapitre 1: Introduction 17


Microsoft FORTRAN PowerStation

 Microsoft FORTRAN PowerStation est strictement un mode protégé 32 bits

compilateur. Il prend en charge l'extension DOSXMSF DOS inclus avec le compilateur et le Lap TNT Phar | Dos-Extender SDK (DOSXMSF est un sous-ensemble de la TNT | Dos-Extender). La bibliothèque Fastgraph suivante est compatible avec Microsoft FORTRAN PowerStation:

 FG32MSF.LIB bibliothèque PM 32 bits pour Microsoft FORTRAN PowerStation

FG32MSF.LIB comprend Phar fonctions support Lap de Fastgraph normalement trouvés dans la bibliothèque FG32PHAR.LIB.

 Les programmes sont compilés et liés à partir de la ligne de commande DOS en utilisant le FL32

commander:

 FL32 <source_file> FG32MSF.LIB

Cette commande appelle le compilateur PowerStation et Microsoft Portable Executable Linker (LINK32) pour créer un 32 bits en mode protégé exécutable.

 Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît

consultez le Guide de l'utilisateur FORTRAN Guide ou Phar Lap du Microsoft FORTRAN PowerStation utilisateur TNT Dos-Extender. Guide de l'utilisateur 18 Fastgraph


Microsoft QuickBASIC

 Vous pouvez compiler et lier les programmes Microsoft QuickBASIC directement à partir du

DOS ligne de commande ou de l'environnement de programmation QuickBASIC. Dans les deux cas, QuickBASIC crée toujours des programmes en mode réel. Les bibliothèques Fastgraph suivants sont compatibles avec QuickBASIC:

 FGQB.LIB bibliothèque autonome pour QuickBASIC
    FGQB.QLB bibliothèque rapide pour QuickBASIC
 Pour créer des applications Fastgraph dans l'environnement de programmation de QuickBASIC,

il suffit de spécifier le nom de la bibliothèque rapide FGQB lors du démarrage QuickBASIC:

 QB / LFGQB [<source_file>]

Pour compiler un programme QuickBASIC à partir de la ligne de commande DOS et le lien avec Fastgraph, utilisez les commandes de la Colombie-Britannique et LINK:

 BC [/ O] <source_file>;
       LINK [/ E] <object_file> ,, NUL, FGQB;

L'option / O sur la commande BC est recommandée car elle crée des fichiers EXE qui ne nécessitent pas le module run-time QuickBASIC. L'option de liaison / E est pas obligatoire mais va produire un fichier EXE plus petit si spécifié. Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît se référer à la Microsoft QuickBASIC: Programmation dans le manuel BASIC.

 Tous les exemples de programmes restants dans le Guide de l'utilisateur Fastgraph sont écrits

dans le langage de programmation C. Toutefois, lorsque vous installez Fastgraph pour Microsoft QuickBASIC, la procédure d'installation copie les versions de base des exemples de programmes dans le répertoire \ FG \ EXEMPLES.

 Chapitre 1: Introduction 19


Microsoft QuickC

 Vous pouvez compiler et lier les programmes Microsoft QuickC directement à partir du DOS

ligne de commande ou de l'environnement de programmation QuickC. Dans les deux cas, QuickC crée toujours des programmes en mode réel. Les bibliothèques Fastgraph suivants sont compatibles avec QuickC:

 FGS.LIB en mode réel petit modèle bibliothèque générale
    FGM.LIB en mode réel moyen modèle bibliothèque générale
    FGL.LIB en mode réel grand modèle bibliothèque générale
    FGMSCS.LIB en mode réel petit modèle bibliothèque auxiliaire
    FGMSCM.LIB en mode réel moyen modèle bibliothèque auxiliaire
    FGMSCL.LIB en mode réel grand modèle bibliothèque auxiliaire
 Pour créer des applications Fastgraph dans l'environnement de programmation QuickC,

vous devez vous assurer que les options de compilation correspondent à l'un des modèles de la mémoire disponible de Fastgraph (petites, moyennes ou grandes), puis créer un fichier make qui comprend les noms de bibliothèque Fastgraph correspondants.

 Pour compiler un programme QuickC à partir de la ligne de commande DOS et le lien avec

Fastgraph, utilisez la commande QCL. Voici des exemples de commandes QCL pour compiler un programme QuickC et de le lier avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compilateur ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D. L'option / E lieur ne sont pas nécessaires, mais produira un fichier EXE plus petit si spécifié.

 Petit modèle de mémoire:
       QCL / AS <source_file> / link FGS.LIB [FGMSCS.LIB] [/ E]
 Moyen modèle de mémoire:
       QCL / AM <source_file> / link FGM.LIB [FGMSCM.LIB] [/ E]
 Grand modèle de mémoire:
       QCL / AL <source_file> / link FGL.LIB [FGMSCL.LIB] [/ E]
 Pour plus d'informations sur les fichiers, faire des modèles de mémoire, ou d'autres

compilation et options de liens, s'il vous plaît consulter le manuel du kit Microsoft QuickC Tool. Guide de l'utilisateur 20 Fastgraph


Microsoft Visual Basic pour DOS

 Vous pouvez compiler et lier Microsoft Visual Basic pour les programmes DOS directement

à partir de la ligne de commande DOS ou à partir de l'environnement de programmation Visual Basic. Dans les deux cas, Visual Basic crée toujours des programmes en mode réel. Les bibliothèques Fastgraph suivants sont compatibles avec Visual Basic:

 FGVBDOS.LIB bibliothèque autonome pour Visual Basic
    FGVBDOS.QLB bibliothèque rapide pour Visual Basic
 Pour créer des applications Fastgraph dans la programmation Visual Basic

environnement, il suffit de spécifier le nom de la bibliothèque rapide FGVBDOS lors du démarrage de Visual Basic:

 VBDOS / LFGVBDOS [<source_file>]

Lors de l'utilisation de l'environnement de programmation, vous pouvez obtenir un message d'erreur "Out of Memory" ou "Out of String Space" en essayant de construire un fichier EXE ou exécuter une application dans l'environnement. Si cela se produit, vous devez spécifier l'option / S sur la ligne de commande VBDOS pour augmenter la quantité de mémoire disponible pour votre application. Si vous avez la mémoire EMS ou XMS installé sur votre système, il est également utile de préciser le / E ou / X options pour faire des portions du résident de l'environnement de programmation en EMS ou XMS. Pour plus d'informations sur ces options, reportez-vous à l'annexe B du Microsoft Guide du programmeur Visual Basic.

 Pour compiler un programme Visual Basic à partir de la ligne de commande DOS et le lier

avec Fastgraph, utilisez les commandes de la Colombie-Britannique et LINK:

 BC [/ O] <source_file>;
       LINK [/ E] <object_file> ,, NUL, FGVBDOS;

L'option / O sur la commande BC est recommandée car elle crée des fichiers EXE qui ne nécessitent pas le module Visual Basic exécution. L'option de liaison / E est pas obligatoire mais va produire un fichier EXE plus petit si spécifié. Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît se référer à la Microsoft Guide du programmeur Visual Basic.

 Lors de la liaison Visual Basic pour les programmes DOS qui appellent le monde Fastgraph

routines espace ou logiciel caractères (qui est, une des routines énumérées à l'annexe D), vous pouvez avoir besoin d'augmenter le nombre de segments disponibles à l'éditeur de liens. Utilisez le / SEG: n option sur la commande LINK pour ce faire. La valeur par défaut de n est de 128 segments; habituellement une valeur légèrement plus grande, comme 144, sera suffisant.

 Tous les exemples de programmes restants dans le Guide de l'utilisateur Fastgraph sont écrits

dans le langage de programmation C. Toutefois, lorsque vous installez Fastgraph pour Visual Basic, la procédure d'installation copie les versions de base des exemples de programmes dans le répertoire \ FG \ EXEMPLES.

 Chapitre 1: Introduction 21


Microsoft Visual C ++

 Microsoft Visual C ++ peut créer en mode réel et en mode 16 bits protégé

applications. Pour le mode protégé, il prend en charge le Phar Lap 286 | Dos-Extender (deux SDK et Lite versions) et les systèmes DOS / 16M extender Rational. Les bibliothèques Fastgraph suivants sont compatibles avec Visual C ++:

 FGS.LIB en mode réel petit modèle bibliothèque générale
    FGM.LIB en mode réel moyen modèle bibliothèque générale
    FGL.LIB en mode réel grand modèle bibliothèque générale
    FGMSCS.LIB en mode réel petit modèle bibliothèque auxiliaire
    FGMSCM.LIB en mode réel moyen modèle bibliothèque auxiliaire
    FGMSCL.LIB en mode réel grand modèle bibliothèque auxiliaire
    FG16.LIB 16 bits en mode protégé bibliothèque générale
    FG16MSC.LIB 16 bits en mode protégé bibliothèque auxiliaire
    Bibliothèque de support d'extension FG16DPMI.LIB 16 bits DPMI compatible DOS
    FG16PHAR.LIB Phar Lap 286 | Dos-Extender Bibliothèque de support
 Les programmes sont compilés et liés à partir de la ligne de commande DOS en utilisant la CL

commander. Voici des exemples de commandes CL pour compiler un programme Visual C ++ et en le reliant avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compilateur ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D. Dans les exemples de mode réel, l'option de liaison / E est pas obligatoire mais va produire un fichier EXE plus petit si spécifié.

 Mode réel, petit modèle de mémoire:
       CL / AS <source_file> / link FGS.LIB [FGMSCS.LIB] [/ E]
 Mode réel, modèle de support de mémoire:
       CL / AM <source_file> / lien FGM.LIB [FGMSCM.LIB] [/ E]
 Mode réel, grand modèle de mémoire:
       CL / AL <source_file> / link FGL.LIB [FGMSCL.LIB] [/ E]
 mode 16 bits protégé, Phar Lap 286 SDK ou extender Lite:
       CL / AL / Lp <source_file> / link FG16.LIB FG16PHAR.LIB [FG16MSC.LIB]

Pour créer des programmes en mode C ++ protégé visuels utilisant les systèmes DOS / 16M extender Rational, s'il vous plaît se référer au Guide de l'utilisateur DOS / 16M.

 Pour plus d'informations sur les modèles de mémoire ou autre compilation et liaison

les options, s'il vous plaît se référer au Guide de l'utilisateur Visual C ++ en ligne de commande Utilitaires, Guide de Microsoft C & C ++ User Phar Lap à 286 | Dos-Extender, ou le Guide de l'utilisateur DOS / 16M. Guide de l'utilisateur 22 Fastgraph


32-bit Edition de Microsoft Visual C

 Comme son nom l'indique, 32-bit Edition de Microsoft Visual C est strictement

32 bits compilateur en mode protégé. Il prend en charge le Lap TNT Phar | Dos-Extender SDK et Phar Lap TNT | Dos-Extender Lite. La bibliothèque Fastgraph suivante est compatible avec l'édition 32 bits de Visual C ++:

 FG32VC.LIB bibliothèque PM 32-bit 32-bit Edition de Microsoft Visual C

FG32VC.LIB comprend Phar fonctions support Lap de Fastgraph normalement trouvés dans la bibliothèque FG32PHAR.LIB.

 Il existe deux méthodes de base de la création de 32 bits en mode protégé executables

avec 32-bit Edition de Visual C. La première méthode compile et lie le programme en une seule commande et utilise 32 bits linker Microsoft:

 CL <source_file> / link /stub:\TNT\BIN\GOTNT.EXE FG32VC.LIB

La deuxième méthode compile et lie le programme dans les commandes séparées et utilise de 386 Phar Lap | utilitaire lien:

 CL / c <source_file>
       386LINK <fichier_obj> @ MSVC32.DOS -lib FG32VC -nomap -onecase

Le Lap linker Phar a des problèmes avec le monde des routines spatiales Fastgraph. Si votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D, vous devez utiliser la version 32 bits linker Microsoft.

 Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît

reportez-vous au C de Phar Lap / Guide de l'utilisateur C de TNT Dos-Extender.

 Chapitre 1: Introduction 23


Puissance C

 Puissance C est un compilateur de ligne de commande en mode réel bon marché.  Le suivant

bibliothèques Fastgraph sont compatibles avec Power C:

 FGS.MIX Petit modèle bibliothèque générale
    FGM.MIX modèle moyen bibliothèque générale
    FGL.MIX Grand modèle bibliothèque générale
    FGPCS.MIX Petit modèle de bibliothèque auxiliaire
    FGPCM.MIX modèle moyen bibliothèque auxiliaire
    FGPCL.MIX Grand modèle de bibliothèque auxiliaire
 Pour compiler un programme Power C à partir de la ligne de commande DOS et le lien avec

Fastgraph, utilisez le PC et les commandes PCL. Voici un exemple des séquences de commandes pour compiler un programme Power C et la liaison avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compiler- ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D.

 Petit modèle de mémoire:
       PC / ms <source_file>
       PCL <mix_file>; FGS [; FGPCS]
 Moyen modèle de mémoire:
       PC / mm <source_file>
       PCL <mix_file>; MGF [; FGPCM]
 Grand modèle de mémoire:
       PC / ml <source_file>
       PCL <mix_file>; FGL [; FGPCL]

Pour plus d'informations sur les modèles de mémoire ou autre compilation et options de liaison, s'il vous plaît se référer au manuel Power C, publié par Mix Software, Inc. Guide de l'utilisateur 24 Fastgraph


Turbo C et C ++ turbo

 Turbo C et Turbo C ++ peuvent créer en mode réel et en mode 16 bits protégé

applications. Pour le mode protégé, seuls les systèmes DOS / 16M extender Rational est pris en charge. Vous pouvez compiler et lier les programmes directement à partir de la ligne de commande DOS ou de l'environnement de développement Turbo C / C ++ intégré (IDE). Les bibliothèques Fastgraph suivants sont compatibles avec Turbo C / C ++:

 FGS.LIB en mode réel petit modèle bibliothèque générale
    FGM.LIB en mode réel moyen modèle bibliothèque générale
    FGL.LIB en mode réel grand modèle bibliothèque générale
    FGTCS.LIB en mode réel petit modèle bibliothèque auxiliaire
    FGTCM.LIB en mode réel moyen modèle bibliothèque auxiliaire
    FGTCL.LIB en mode réel grand modèle bibliothèque auxiliaire
    FG16.LIB 16 bits en mode protégé bibliothèque générale
    FG16BC.LIB 16 bits en mode protégé bibliothèque auxiliaire
    Bibliothèque de support d'extension FG16DPMI.LIB 16 bits DPMI compatible DOS
 Pour créer des applications Fastgraph dans le Turbo C / C ++ IDE, le compilateur

les options doivent correspondre à l'un des modèles de mémoire disponibles de Fastgraph (petites, moyennes ou grandes). Vous devez également créer un fichier de projet qui comprend le nom de chaque C, CPP, et le fichier LIB requis par votre application (reportez-vous à votre Turbo C ou Turbo C ++ manuels pour des informations sur les fichiers de projet). Les dossiers de projet ne sont nécessaires que lorsque vous utilisez l'IDE.

 Vous pouvez également compiler et lier les programmes de la ligne de commande DOS en utilisant

la commande TCC. Voici des exemples de commandes TCC pour compiler un programme Turbo C ou Turbo C ++ et en le reliant avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compilateur ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D.

 Mode réel, petit modèle de mémoire:
       TCC -ms <source_file> FGS.LIB [FGTCS.LIB]
 Mode réel, modèle de support de mémoire:
       TCC -MM <source_file> FGM.LIB [FGTCM.LIB]
 Mode réel, grand modèle de mémoire:
       TCC -ml <source_file> FGL.LIB [FGTCL.LIB]

Pour créer des programmes en mode Turbo C / C ++ protégées utilisant les systèmes DOS / 16M extender Rational, s'il vous plaît se référer au Guide de l'utilisateur DOS / 16M.

 Pour plus d'informations sur les modèles de mémoire ou autre compilation et liaison

les options, s'il vous plaît se référer au Guide de l'utilisateur Turbo C, Turbo Guide de référence C, ou le Guide de l'utilisateur DOS / 16M.

 Chapitre 1: Introduction 25


Turbo Pascal

 Turbo Pascal peut construire des programmes en mode réel directement à partir de la commande DOS

ligne ou de l'environnement de développement intégré Turbo Pascal (IDE).

 Pour créer des applications Fastgraph dans le Turbo Pascal IDE, il suffit de commencer la

IDE comme vous le feriez pour tout autre programme Pascal, en vérifiant que les fichiers d'unités Fastgraph résider dans l'un des répertoires listés dans "Unité Répertoires" l'option de l'IDE.

 Vous pouvez également compiler des programmes Turbo Pascal de la ligne de commande DOS

en utilisant la commande TPC, comme indiqué ici:

 TPC <source_file>

Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît se référer au Guide de l'utilisateur Turbo Pascal.

 Tous les exemples de programmes restants dans le Guide de l'utilisateur Fastgraph sont écrits

dans le langage de programmation C. Toutefois, lorsque vous installez Fastgraph pour Turbo Pascal, la procédure d'installation copie les versions Pascal des exemples de programmes dans le répertoire \ FG \ EXEMPLES. Guide de l'utilisateur 26 Fastgraph


WATCOM C / C ++ WATCOM C32 pour DOS

 WATCOM C / C ++ et WATCOM C32 pour DOS les deux sont de 16 bits en mode réel et 32 ​​bits

compilateurs en mode protégé (pour plus de simplicité, nous allons utiliser le WATCOM terme C / C ++ pour faire référence aux compilateur). Les deux compilateurs soutiennent le DOS / 4G, DOS / G4G et DOS / G4G Professional DOS extendeurs de Rational Systems (DOS / G4G est fourni avec les deux compilateurs), ainsi que le Lap TNT Phar | Dos-Extender SDK. Les bibliothèques Fastgraph suivantes sont compatibles avec les compilateurs Watcom:

 FGS.LIB en mode réel petit modèle bibliothèque générale
    FGM.LIB en mode réel moyen modèle bibliothèque générale
    FGL.LIB en mode réel grand modèle bibliothèque générale
    FGWCS.LIB en mode réel petit modèle bibliothèque auxiliaire
    FGWCM.LIB en mode réel moyen modèle bibliothèque auxiliaire
    FGWCL.LIB en mode réel grand modèle bibliothèque auxiliaire
    FG32.LIB 32 bits en mode protégé bibliothèque générale
    FG32WC.LIB 32 bits en mode protégé bibliothèque auxiliaire
    Bibliothèque de support d'extension FG32DPMI.LIB 32 bits DPMI compatible DOS
    FG32PHAR.LIB Phar Lap TNT | Bibliothèque de support Dos-Extender
 Les programmes sont compilés et liés à partir de la ligne de commande DOS en utilisant la WCL

ou commandes WCL386. Voici par exemple les commandes pour compiler un programme WATCOM C / C ++ et en le reliant avec Fastgraph. Les bibliothèques auxiliaires spécifiques compilateur (FGWCS, FGWCM, FGWCL et FG32WC) ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D.

Mode réel, petit modèle de mémoire:

 WCL / ms <source_file> FGS.LIB [FGWCS.LIB]

Mode réel, modèle de support de mémoire:

 WCL / mm <source_file> FGM.LIB [FGWCM.LIB]

Mode réel, grand modèle de mémoire:

 WCL / ml <source_file> FGL.LIB [FGWCL.LIB]

mode 32 bits protégé, tout extender Systems DOS / 4G Rational:

 WCL386 / l = dos4g <source_file> FG32.LIB FG32DPMI.LIB [FG32WC.LIB]

mode protégé 32 bits, Phar Lap TNT | Dos-Extender:

 WCL386 / l = PharLap <source_file> FG32.LIB FG32PHAR.LIB [FG32WC.LIB]
 Pour plus d'informations sur la compilation et l'autre des options de liaison, s'il vous plaît

reportez-vous à la WATCOM C / C de Guide, Phar Lap de C de l'utilisateur / C ++ Guide d'utilisation de TNT Dos-Extender, ou le manuel de l'utilisateur DOS / 4G.

 Chapitre 1: Introduction 27


Zortech C ++

 Zortech C ++ crée des applications en mode réel.  La Fastgraph suivante

bibliothèques sont compatibles avec Zortech C ++:

 FGS.LIB en mode réel petit modèle bibliothèque générale
    FGM.LIB en mode réel moyen modèle bibliothèque générale
    FGL.LIB en mode réel grand modèle bibliothèque générale
    FGZCS.LIB en mode réel petit modèle bibliothèque auxiliaire
    FGZCM.LIB en mode réel moyen modèle bibliothèque auxiliaire
    FGZCL.LIB en mode réel grand modèle bibliothèque auxiliaire
 Les programmes sont compilés et liés à partir de la ligne de commande DOS en utilisant la ZTC

commander. Voici des exemples de commandes ZTC pour compiler un programme Zortech C ++ et en le reliant avec Fastgraph. Les noms de bibliothèques auxiliaires spécifiques compilateur ne doivent être inclus lorsque votre programme utilise l'une des routines Fastgraph énumérées à l'annexe D.

 Petit modèle de mémoire:
       ZTC -ms <source_file> FGS.LIB [FGZCS.LIB]
 Moyen modèle de mémoire:
       ZTC -MM <source_file> FGM.LIB [FGZCM.LIB]
 Grand modèle de mémoire:
       ZTC -ml <source_file> FGL.LIB [FGZCL.LIB]

Pour plus d'informations sur les modèles de mémoire ou autre compilation et options de liaison, s'il vous plaît se référer aux manuels fournis avec le compilateur de votre Zortech C. Guide de l'utilisateur 28 Fastgraph


Fastgraph / Light Video Pilote

 Comme mentionné précédemment, l'exécution de tout programme créé avec Fastgraph / Light

exige un programme externe appelé le pilote Fastgraph / Light Vidéo. Le pilote vidéo est une fin et rester programme résident (TSR) qui fournit une interface entre votre programme et Fastgraph.

 Pour charger le pilote vidéo, entrez la commande FGDRIVER à la commande DOS

prompt (en supposant que FGDRIVER.EXE est dans le répertoire courant, ou le répertoire \ FG est dans votre spécification de chemin DOS). Le pilote affichera un message indiquant si oui ou non il chargé avec succès. Après avoir chargé le pilote, il suffit d'exécuter un programme créé avec Fastgraph / Light comme vous le feriez pour tout autre programme. Si vous essayez d'exécuter un programme qui utilise Fastgraph / Light sans premier chargement du pilote vidéo, le message "pilote vidéo Fastgraph / Light pas installé" apparaît.

 Vous ne devez pas charger le pilote avant d'exécuter chaque programme, juste une fois

par le démarrage du système (en fait, le pilote affichera un message "déjà chargé" si vous essayez de charger plus d'une fois). Si vous souhaitez décharger le pilote vidéo, il suffit d'entrer FGDRIVER / U à l'invite de commande DOS. L'opération de déchargement ne fonctionnera complètement que si le pilote vidéo a été le dernier TSR chargé. S'il n'a pas été le dernier TSR, le conducteur sera toujours décharger, mais la mémoire qu'il utilise ne seront pas relâchés au DOS.



Chapitre 2


Guide de PC et PS / 2 Modes vidéo 30 Fastgraph utilisateur


aperçu

 Dans le PC et PS / 2 mondes, les modes vidéo déterminent la façon dont l'information

apparaît sur l'écran d'affichage de l'ordinateur. Les modes vidéo disponibles ont différentes résolutions, différents attributs de caractère ou pixel, différentes structures de mémoire vidéo, et d'autres différences matérielles inhérentes. Cependant, on n'a pas besoin d'une connaissance approfondie de ces internes de vidéo, parce Fastgraph gère les détails nécessaires.

 Le PC et PS / 2 modes vidéo peuvent être séparés en deux classes principales: Texte

modes et modes graphiques. Dans les modes de texte, l'écran d'affichage est divisé en cellules de caractères. Par défaut, il y a 25 lignes et 40 ou 80 colonnes de cellules, et dans chaque cellule, nous pouvons stocker de 256 caractères dans le caractère de PC jeu IBM. Chaque personnage a un attribut associé qui détermine des choses telles que la couleur de premier plan, sa couleur de fond, et si le voyant de caractère ou non. Dans les modes graphiques, l'écran d'affichage est divisé en éléments d'image ou pixels. En fonction du mode vidéo, le nombre de rangées de pixels est compris entre 200 et 768, tandis que le nombre de colonnes varie entre 320 et 1.024. Chaque pixel a une valeur associée, qui détermine la couleur du pixel. Le nombre de cellules de caractères ou de pixels disponibles est appelé la résolution de l'écran.

 L'adaptateur d'affichage (carte graphique) et l'affichage vidéo (moniteur)

qui lui est connecté à déterminer les modes vidéo disponibles sur un système donné. Le tableau suivant résume les caractéristiques du PC et PS / 2 modes vidéo qui Fastgraph soutient.

 Mode Nombre de Supporté Supporté
   No. Type Résolution Couleurs Adaptateurs Affiche
 0 T 40x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    1 T 40x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    2 T 80x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    3 T 80x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    4 G 320x200 4 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    5 G 320x200 4 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    6 G 640x200 2/16 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    7 T 80x25 b / w MDA, HGC, EGA, VGA, SVGA Monochrome
    9 G 320x200 16 Tandy 1000, PCjr RGB
   11 G 720x348 b / w HGC Monochrome
   12 G 320x200 b / w HGC Monochrome
   13 G 320x200 16 EGA, VGA, SVGA RGB, ECD, VGA, SVGA
   14 G 640x200 16 EGA, VGA, SVGA RGB, ECD, VGA, SVGA
   15 G 640x350 b / w EGA, VGA, SVGA Mono, VGA, SVGA
   16 G 640x350 16/64 EGA, VGA, SVGA ECD, VGA, SVGA
   17 G 640x480 2 / 256K VGA, MCGA, SVGA VGA, SVGA
   18 G 640x480 16 / 256K VGA, SVGA VGA, SVGA
   19 G 320x200 256 / 256K VGA, MCGA, SVGA VGA, SVGA
   20 G 320x200 256 / 256K VGA, SVGA VGA, SVGA
   21 G 320x400 256 / 256K VGA, SVGA VGA, SVGA
   22 G 320x240 256 / 256K VGA, SVGA VGA, SVGA
   23 G 320x480 256 / 256K VGA, SVGA VGA, SVGA
   24 G 640x400 256 / 256K SVGA SVGA
   25 G 640x480 256 / 256K SVGA SVGA
   26 G 800x600 256 / 256K SVGA SVGA
                                     Chapitre 2: PC et PS / 2 Modes vidéo 31


 27 G 1024x768 256 / 256K SVGA SVGA
   28 G 800x600 16 / 256K SVGA SVGA
   29 G 1024x768 16 / 256K SVGA SVGA
 Quelques notes sur le format et les abréviations utilisées dans ce tableau sont en

commande. Dans la colonne "type", "T", un mode texte et «G» désigne un mode graphique. Une seule valeur dans la colonne "nombre de couleurs" désigne le nombre de couleurs disponibles en ce que le mode vidéo. Dans les modes de texte, une paire de nombres tels que 16/8 signifie que chaque caractère affiché peut avoir l'une des 16 couleurs de premier plan et l'un des 8 couleurs de fond. Dans les modes graphiques, une paire de nombres tels que 16/64 signifie 16 couleurs peuvent être affichées simultanément à partir d'une collection, ou une palette, de 64. Le "b / w" figurant dans les modes monochromes signifie "noir et blanc". Caractères ou pixels dans ces modes vidéo ne sont pas vraiment avoir des couleurs associées, mais plutôt avoir des attributs d'affichage tels que clignotant ou des intensités différentes.

 La signification des abréviations dans les «cartes prises en charge» et

"Affiche" pris en charge les colonnes sont:

 CGA Couleur Graphics Adapter
    ECD écran couleur améliorée
    EGA Adaptateur graphique amélioré
    HGC Hercules Carte graphique
    Tableau MCGA Graphics Multi-couleur
    MDA Monochrome Display Adapter
    Affichage RGB Rouge-Vert-Bleu Couleur
    SVGA SuperVGA
    Video Graphics Array VGA

L'utilisation du terme "VGA" dans la colonne "d'affichage supporté" fait référence à un affichage analogique, comme un moniteur VGA ou Multisync. Le terme «SVGA» se réfère explicitement à un moniteur SuperVGA ou un adaptateur.

 Les IBM PS / 2 systèmes ne disposent pas d'un adaptateur et l'affichage traditionnel

combinaison. Au lieu de cela, le matériel vidéo dans ces systèmes est appelé le sous-système vidéo. Le modèle 25 et modèle 30 ont un sous-système vidéo basé sur MCGA, tandis que d'autres modèles disposent d'un sous-système vidéo basé VGA. Du point de vue de Fastgraph, le sous-système vidéo PS / 2 ne diffère pas d'une carte VGA ordinaire et moniteur.

 Le reste de ce chapitre donne un aperçu des plus importants

caractéristiques et restrictions de chaque mode vidéo. La première section traite des modes de texte, tandis que la section suivante abordera les modes graphiques les.


Modes de texte

 Il y a cinq modes texte vidéo dans le PC IBM et PS / 2 famille.  quatre d'entre

ces modes (0, 1, 2 et 3) sont conçus pour les écrans couleur, tandis que le mode (7) restant est conçu pour les écrans monochromes. Tous les modes de texte ont été introduites avec l'IBM PC.

 Dans les modes de texte, l'écran est divisé en cellules de caractères.  Il y a deux

octets de mémoire vidéo associés à chaque cellule de caractère - un octet pour la valeur ASCII du caractère, et un autre pour l'attribut d'affichage du personnage. La quantité de mémoire vidéo nécessaire pour stocker un écran d'informations (appelée une page vidéo) est donc Guide de 32 Fastgraph utilisateur


 number_of_columns x NUMBER_OF_ROWS x 2

Tous les modes de texte utilisent 25 lignes, donc pour les modes 40 colonnes (0 et 1) la taille d'une page vidéo est de 2000 octets, et pour les modes 80 colonnes (2, 3 et 7) la taille d'une page vidéo est de 4000 octets.

 Mode Nombre de Supporté Supporté
   No. Type Résolution Couleurs Adaptateurs Affiche
 0 T 40x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    1 T 40x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    2 T 80x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    3 T 80x25 16/8 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
    7 T 80x25 b / w MDA, HGC, EGA, VGA, SVGA Monochrome
 Le reste de cette section décrit les modes texte vidéo dans plus

détail.

Mode 0

 Mode 0 est un 40-colonne de 25 rangs en mode texte couleur.  Elle est souvent appelée

Mode incolore car il a été conçu pour être utilisé avec des écrans de télévision ou composites (par opposition aux écrans RVB). Lorsqu'il est utilisé avec ces types de moniteurs, les 16 disponibles "couleurs" apparaissent des nuances distinctes de gris. Lorsqu'il est utilisé avec un moniteur RGB, le mode 0 est identique à tous égards au mode 1. L'utilisation de moniteurs composites ou de télévision que PC écrans vidéo a pratiquement disparu aujourd'hui. En conséquence, le mode 0 est utilisé peu fréquemment.

Mode 1

 Mode 1 est un 40-colonne de 25 rangs en mode texte couleur.  Il est pris en charge à travers

tous les adaptateurs vidéo et affichage couleur combinaisons dans le PC et PS / 2 familles. Caractères affichés en mode 1 ont un attribut d'affichage associé qui définit la couleur de premier plan du personnage, sa couleur de fond, et si oui ou non il clignote. Seize couleurs de premier plan et huit couleurs de fond sont disponibles.

Mode 2

 Mode 2 est un 80-colonne de 25 rangs en mode texte couleur.  mode 0 Comme, il est

souvent appelé un mode incolore car il a été conçu pour être utilisé avec des écrans de télévision ou composites (par opposition aux écrans RVB). Lorsqu'il est utilisé avec ces types de moniteurs, les 16 disponibles "couleurs" apparaissent des nuances distinctes de gris. Lorsqu'il est utilisé avec un moniteur RGB, le mode 2 est identique à tous égards au mode 3. L'utilisation de moniteurs composites ou de télévision que PC écrans vidéo a pratiquement disparu aujourd'hui. En conséquence, le mode 2 est utilisé peu fréquemment.

Mode 3

 Mode 3 est un 80-colonne de 25 rangs en mode texte couleur.  Il est la vidéo par défaut

mode pour les systèmes qui utilisent tout type d'écran couleur. Ce mode est supporté sur toutes les combinaisons de carte vidéo et d'affichage des couleurs dans le PC et PS / 2 familles. Les caractères affichés en mode 3 ont un attribut d'affichage associé qui définit la couleur de premier plan du personnage, sa couleur de fond, et

 Chapitre 2: PC et PS / 2 Modes vidéo 33


si oui ou non il clignote. Seize couleurs de premier plan et huit couleurs de fond sont disponibles.

Mode 7

Mode 7 est le 80-colonne de 25 rangs en mode texte monochrome. Il est la valeur par défaut

mode vidéo pour des systèmes qui utilisent un écran monochrome. Pour utiliser ce mode, vous devez disposer d'un adaptateur Monochrome Display (MDA), Hercules Carte graphique (HGC), ou un adaptateur graphique amélioré (EGA) connecté à un écran monochrome. La plupart des adaptateurs VGA et d'affichage SVGA fournissent également un mode d'émulation qui vous permet en mode 7 utiliser avec des écrans analogiques. Les caractères affichés en mode 7 ont un attribut d'affichage associé qui définit si le caractère est invisible, normal, gras, souligné, inversé, clignotant, ou une combinaison de ceux-ci.


Modes graphiques

Il y a 13 modes standards graphiques vidéo disponibles dans le PC IBM et

PS / 2 famille. Fastgraph fournit un support pour 11 des 13 modes (modes 8 et 10, spécifiques à la PCjr et Tandy 1000 systèmes, ne sont pas pris en charge). En plus de ces 13 modes, Fastgraph prend en charge six modes SuperVGA graphiques (modes 24 à 29), quatre modes VGA étendus (modes 20 à 23), et deux modes vidéo pour la carte graphique Hercules (modes 11 et 12). Les sections suivantes décrivent ces modes graphiques dans plus de détails. Les discussions comprennent un aperçu de l'organisation de la mémoire vidéo dans chaque mode, mais on n'a pas besoin d'une connaissance de ce sujet à utiliser Fastgraph.


CGA Modes graphiques

Modes 4, 5, et 6 sont conçus pour être utilisés avec l'adaptateur graphique couleur

(CGA) et pour cette raison sont appelés les modes CGA natifs. Ils étaient les seuls modes disponibles avec le PC IBM d'origine graphiques. adaptateurs plus récents graphiques (EGA, VGA, MCGA et SVGA) peuvent émuler le CGA, ce qui signifie que les modes les graphiques CGA sont disponibles sur un PC ou PS système / 2 équipé d'un écran couleur.

Mode Nombre de Supporté Supporté
  No. Type Résolution Couleurs Adaptateurs Affiche
4 G 320x200 4 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
   5 G 320x200 4 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA
   6 G 640x200 2/16 CGA, EGA, VGA, MCGA, SVGA RGB, ECD, VGA, SVGA

Mode 4

Mode 4 est un mode graphique CGA avec une résolution de 320 pixels horizontaux

par 200 pixels verticaux. Chaque pixel peut prendre l'une des quatre couleurs (les couleurs disponibles sont déterminées par lequel l'une des six palettes a été sélectionné), de sorte que chaque pixel nécessite deux bits de mémoire vidéo. Cela signifie que chaque octet de la mémoire vidéo représente quatre pixels. Guide de l'utilisateur 34 Fastgraph


Mode 5

Mode 5 est l'analogue incolore du mode 4. Il a été conçu pour être utilisé avec

moniteurs composites ou de télévision (par opposition aux moniteurs RVB). Lorsqu'il est utilisé avec ces types de moniteurs, les quatre couleurs apparaissent des nuances distinctes de gris. Lorsqu'il est utilisé avec un écran RVB, le mode 5 est essentiellement identique au mode 4. L'utilisation de moniteurs composites ou de télévision que PC écrans vidéo a pratiquement disparu aujourd'hui. En conséquence, le mode 5 est utilisé peu fréquemment.

Mode 6

Mode 6 est un mode graphique CGA avec une résolution de 640 pixels horizontaux

par 200 pixels verticaux. Chaque pixel peut prendre deux états - ou désactiver. La couleur dans laquelle le "sur" pixels apparaissent peut être choisi parmi une palette de 16 couleurs disponibles. Chaque pixel nécessite donc un bit de mémoire vidéo, ce qui signifie que chaque octet de la mémoire vidéo représente huit pixels.


Tandy 1000 et PCjr Modes graphiques

Modes 8, 9 et 10 ne sont disponibles que sur le PCjr et Tandy 1000 series

ordinateurs (ces systèmes prennent également en charge les modes 4, 5 et 6). Modes 8 et 10 ne sont pas largement utilisés, et pour cette raison Fastgraph ne les supporte pas.

Mode Nombre de Supporté Supporté
  No. Type Résolution Couleurs Adaptateurs Affiche
8 G 160x200 16 Tandy 1000, PCjr RGB
   9 G 320x200 16 Tandy 1000, PCjr RGB
  10 G 640x200 4 Tandy 1000, PCjr RGB

9 Mode

Mode 9 est un mode graphique et 1000 Tandy PCjr avec une résolution de 320

pixels horizontaux par 200 pixels verticaux. Chaque pixel peut prendre l'une des 16 couleurs, de sorte que chaque pixel nécessite quatre bits de la mémoire vidéo. Cela signifie que chaque octet de la mémoire vidéo représente deux pixels. Le Tandy 1000 et PCjr utilisent de la mémoire à accès aléatoire standard (RAM) comme mémoire vidéo.


Hercules Modes graphiques

Les modes 11 et 12 sont utilisés avec la carte graphique Hercules (HGC) et un

affichage monochrome. En tant que tel, ils ne sont pas de vrais modes vidéo IBM, mais à cause de la popularité de la HGC, Fastgraph fournit un support pour cet adaptateur.

Mode Nombre de Supporté Supporté
  No. Type Résolution Couleurs Adaptateurs Affiche
11 G 720x348 b / w HGC Monochrome
  12 G 320x200 b / w HGC Monochrome   
                                    Chapitre 2: PC et PS / 2 Modes vidéo 35


mode 11

Mode 11 est un vrai mode graphique Hercules avec une résolution de 720

pixels horizontaux par 348 pixels verticaux. Chaque pixel peut prendre deux états - ou désactiver. Chaque pixel nécessite donc un bit de mémoire vidéo, ce qui signifie que chaque octet de la mémoire vidéo représente huit pixels.

mode 12

Mode 12 est un mode graphique Hercules logiciel simulé avec une

résolution de 320 pixels horizontaux par 200 pixels verticaux. Son but est de fournir une résolution qui est disponible avec tous les autres adaptateurs d'affichage graphique.

Ce mode convertit toutes les coordonnées de l'espace 320x200 (appelé virtuelle

coordonnées) dans le système de coordonnées 720x348 (appelé coordonnées physiques). Il le fait en utilisant deux pixels physiques pour chaque pixel virtuel et scan de doubler les lignes virtuelles impaires. Enfin, les décalages sont ajoutés aux coordonnées physiques résultant de centrer la zone d'image sur l'écran. Cela crée une zone de l'image délimitée horizontalement par des coordonnées physiques et 40 679 et verticalement par les coordonnées physiques 24 et 323.


EGA Modes graphiques

Modes 13 à 16 ont été introduites avec l'adaptateur graphique amélioré

(EGA) et pour cette raison sont appelés les modes EGA natifs. adaptateurs VGA et SVGA apportent également un soutien pour ces modes, mais la MCGA ne fonctionne pas. L'EGA IBM originale ne contenait 64K octets de mémoire vidéo, mais la mémoire peut être ajoutée en 64K incréments pour remplir entièrement l'adaptateur avec 256K octets de mémoire vidéo.

Mode Nombre de Supporté Supporté
  No. Type Résolution Couleurs Adaptateurs Affiche
13 G 320x200 16 EGA, VGA, SVGA RGB, ECD, VGA, SVGA
  14 G 640x200 16 EGA, VGA, SVGA RGB, ECD, VGA, SVGA
  15 G 640x350 b / w EGA, VGA, SVGA Mono, VGA, SVGA
  16 G 640x350 16/64 EGA, VGA, SVGA ECD, VGA, SVGA

13 Mode

Mode 13 est un mode EGA graphique avec une résolution de 320 horizontale

pixels par 200 pixels verticaux. Chaque pixel peut prendre l'une des 16 couleurs, de sorte que chaque pixel nécessite quatre bits de la mémoire vidéo. Dans ce mode, la mémoire vidéo est organisée en quatre plans de bits. Chaque adresse de mémoire vidéo fait référence en fait quatre octets, un dans chaque plan. En d'autres termes, chaque octet de mémoire vidéo fait référence à huit pixels, stockées un bit par avion.

mode 14

Mode 14 est un mode EGA graphique avec une résolution de 640 horizontale

pixels par 200 pixels verticaux. Chaque pixel peut prendre l'une des 16 couleurs, de sorte que chaque pixel nécessite quatre bits de la mémoire vidéo. Dans ce mode, la mémoire vidéo est organisée en quatre plans de bits. Chaque adresse de mémoire vidéo référence fait Guide de l'utilisateur 36 Fastgraph


quatre octets, un dans chaque plan. En d'autres termes, chaque octet de mémoire vidéo fait référence à huit pixels, stockées un bit par avion.

mode 15

Mode 15 est un mode graphique monochrome EGA avec une résolution de 640

pixels horizontaux par 350 pixels verticaux. Chaque pixel peut prendre l'un des 4 attributs d'affichage, de sorte que chaque pixel nécessite deux bits de mémoire vidéo. Dans ce mode, la mémoire vidéo est organisée en quatre plans de bits, dont deux sont désactivés. Chaque adresse de mémoire vidéo fait référence en fait deux octets, un dans chaque plan est activé. En d'autres termes, chaque octet de mémoire vidéo fait référence à huit pixels, stockées un bit par avion.

16 Mode

Mode 16 est un mode EGA graphique avec une résolution de 640 horizontale

pixels par 350 pixels.1 vertical Chaque pixel peut supposer une des 16 couleurs (16 couleurs peuvent être sélectionnés à partir d'une palette de 64 couleurs), de sorte que chaque pixel nécessite quatre bits de mémoire vidéo. Dans ce mode, la mémoire vidéo est organisée en quatre plans de bits. Chaque adresse de mémoire vidéo fait référence en fait quatre octets, un dans chaque plan. En d'autres termes, chaque octet de mémoire vidéo fait référence à huit pixels, stockées un bit par avion.


VGA et MCGA Modes graphiques

Modes 17, 18, et 19 ont été introduits avec la vidéo MCGA et VGA

sous-systèmes des IBM PS / 2 ordinateurs. Depuis l'introduction du PS / 2, d'autres fabricants ont développé des cartes VGA qui peuvent être utilisés avec la famille de PC. adaptateurs VGA et SVGA supportent tous les trois de ces modes, mais le MCGA ne supporte pas le mode 18. Modes 17 et 18 sont appelés modes VGA natifs.

Mode Nombre de Supporté Supporté
  No. Type Résolution Couleurs Adaptateurs Affiche
17 G 640x480 2 / 256K VGA, MCGA, SVGA VGA, SVGA
  18 G 640x480 16 / 256K VGA, SVGA VGA, SVGA
  19 G 320x200 256 / 256K VGA, MCGA, SVGA VGA, SVGA

mode 17

Mode 17 est un connecteur VGA et le mode graphique MCGA avec une résolution de 640

pixels horizontaux par 480 pixels verticaux. Chaque pixel peut prendre deux états - ou désactiver. La couleur dans laquelle le "sur" et pixels "off" apparaissent peut être choisi parmi une palette de 262.144 couleurs disponibles. Chaque pixel nécessite donc un bit de mémoire vidéo, ce qui signifie que chaque octet de la mémoire vidéo représente huit pixels. Sur les systèmes VGA et SVGA, la mémoire vidéo est organisé comme quatre plans de bits et le mode 17 est mis en œuvre en permettant un de ces avions.


____________________

(1) En mode 16, la taille de la page vidéo est en fait 640 par 400 pixels, bien que

la résolution d'écran est de 640 par 350. Les 50 dernières rangées de pixels (350 à 399) sur chaque page vidéo ne sont pas affichés, mais sont disponibles pour le stockage hors-écran.

Chapitre 2: PC et PS / 2 Modes vidéo 37


mode 18

Mode 18 est un mode graphique VGA natif avec une résolution de 640 horizontale

pixels par 480 pixels verticaux. Chaque pixel peut prendre l'une des 16 couleurs (16 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite quatre bits de mémoire vidéo. Dans ce mode, la mémoire vidéo est organisée en quatre plans de bits. Chaque adresse de mémoire vidéo fait référence en fait quatre octets, un dans chaque plan. En d'autres termes, chaque octet de mémoire vidéo fait référence à huit pixels, stockées un bit par avion.

mode 19

Mode 19 est un connecteur VGA et le mode graphique MCGA avec une résolution de 320

pixels horizontaux par 200 pixels verticaux. Chaque pixel peut prendre l'une des 256 couleurs (256 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite huit bits de mémoire vidéo. Cela signifie que chaque octet de la mémoire vidéo représente un pixel.


VGA étendue Modes (XVGA) Graphiques

Modes 20 à 23 sont les modes VGA ou XVGA graphiques étendues.  Bien que

ces modes vidéo ne sont pas des modes VGA standard, ils vont travailler sur un VGA ou un adaptateur compatible SVGA registres ont. Ces modes vidéo sont particulièrement populaires pour le développement du jeu, car ils offrent la page redimensionnement vidéo, tandis que le mode 256 couleurs standard ne fonctionne pas. Mode 20 est la version XVGA du mode 19, tandis que le mode 21 utilisations scan doubler pour atteindre un affichage de 400 lignes. Mode 22 est ce qu'on appelle le mode "X" et est attrayante parce qu'il a un rapport 1: 1 d'aspect. Mode 23 est identique au mode 22, mais il utilise doublement scan pour obtenir un affichage de 480 lignes.

Mode Nombre de Supporté Supporté
  No. Type Résolution Couleurs Adaptateurs Affiche
20 G 320x200 256 / 256K VGA, SVGA VGA, SVGA
  21 G 320x400 256 / 256K VGA, SVGA VGA, SVGA
  22 G 320x240 256 / 256K VGA, SVGA VGA, SVGA
  23 G 320x480 256 / 256K VGA, SVGA VGA, SVGA

20 Mode

Mode 20 est un mode XVGA graphique avec une résolution de 320 horizontale

pixels par 200 pixels verticaux. Chaque pixel peut prendre l'une des 256 couleurs (256 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite huit bits de mémoire vidéo. Cela signifie que chaque octet de la mémoire vidéo représente un pixel. Ce mode offre la même résolution et nombre de couleurs que le mode 19, mais sa mémoire vidéo est organisée comme une série de quatre plans de bits. Chaque quatrième pixel est stocké dans le même plan (soit un pixel dont la coordonnée horizontale x est dans le plan x réside modulo 4).

mode 21

 Mode 21 est un mode graphique couleur XVGA avec une résolution de 320

pixels horizontaux par 400 pixels verticaux. À l'exception de la résolution, son organisation de mémoire vidéo est identique au mode 20. Guide de l'utilisateur 38 Fastgraph


mode 22

 Mode 22 est un mode graphique couleur XVGA avec une résolution de 320

pixels horizontaux par 240 pixels verticaux. Ceci est la soi-disant mode "X" rendu célèbre par Michael Abrash dans le Journal de Dr. Dobb. À l'exception de la résolution, l'organisation de la mémoire vidéo est identique au mode 20.

mode 23

 Mode 23 est un mode graphique couleur XVGA avec une résolution de 320

pixels horizontaux par 480 pixels verticaux. À l'exception de la résolution, l'organisation de la mémoire vidéo est identique au mode 20.


SuperVGA Modes (SVGA) Graphiques

 Modes 24 à 29 sont les modes SuperVGA ou SVGA graphiques.  Si vous avez

fait du travail avec des cartes SVGA, vous savez probablement que différents fabricants utilisent des numéros différents pour référencer les modes SVGA vidéo. Par exemple, le numéro de mode 640x480 graphiques 256 couleurs est 62 hex sur les cartes ATI, 5D hex sur les cartes Trident et 2F hex sur Tseng Labs cartes. le noyau SVGA de Fastgraph, décrit en détail dans le chapitre suivant, gère les détails de SVGA générale des numéros de mode vidéo de cartographie Fastgraph (24 à 29) aux numéros des cartes SVGA pris en charge le mode vidéo spécifiques chipset.

 Mode Nombre de Supporté Supporté
   No. Type Résolution Couleurs Adaptateurs Affiche
 24 G 640x400 256 / 256K SVGA SVGA
   25 G 640x480 256 / 256K SVGA SVGA
   26 G 800x600 256 / 256K SVGA SVGA
   27 G 1024x768 256 / 256K SVGA SVGA
   28 G 800x600 16 / 256K SVGA SVGA
   29 G 1024x768 16 / 256K SVGA SVGA

mode 24

 Mode 24 est un mode graphique SuperVGA avec une résolution de 640 horizontale

pixels par 400 pixels verticaux. Chaque pixel peut prendre l'une des 256 couleurs (256 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite huit bits de mémoire vidéo. Cela signifie que chaque octet de mémoire vidéo représente un pixel, donc au moins 256K de mémoire vidéo est nécessaire pour ce mode. Notez qu'un bon nombre de cartes SVGA ne supportent pas ce mode vidéo.

mode 25

 Mode 25 est un mode graphique SuperVGA avec une résolution de 640 horizontale

pixels par 480 pixels verticaux. Il est probablement le mode le plus populaire graphique SVGA. Chaque pixel peut prendre l'une des 256 couleurs (256 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite huit bits de mémoire vidéo. Cela signifie que chaque octet de mémoire vidéo représente un pixel, donc au moins 512K de mémoire vidéo est nécessaire pour ce mode.

 Chapitre 2: PC et PS / 2 Modes vidéo 39


mode 26

 Mode 26 est un mode graphique SuperVGA avec une résolution de 800 horizontale

pixels par 600 pixels verticaux. Chaque pixel peut prendre l'une des 256 couleurs (256 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite huit bits de mémoire vidéo. Cela signifie que chaque octet de mémoire vidéo représente un pixel, donc au moins 512K de mémoire vidéo est nécessaire pour ce mode.

mode 27

 Mode 27 est un mode graphique SuperVGA avec une résolution de 1024 horizontale

pixels par 768 pixels verticaux. Chaque pixel peut prendre l'une des 256 couleurs (256 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite huit bits de mémoire vidéo. Cela signifie que chaque octet de mémoire vidéo représente un pixel, donc au moins 768K de mémoire vidéo est nécessaire pour ce mode.

mode 28

 Mode 28 est un mode graphique SuperVGA avec une résolution de 800 horizontale

pixels par 600 pixels verticaux. Chaque pixel peut prendre l'une des 16 couleurs (16 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite quatre bits de mémoire vidéo. Dans ce mode, la mémoire vidéo est organisée en quatre plans de bits. Chaque adresse de mémoire vidéo fait référence en fait quatre octets, un dans chaque plan. En d'autres termes, chaque octet de mémoire vidéo fait référence à huit pixels, stockées un bit par avion. Au moins 256K de mémoire vidéo est nécessaire pour utiliser ce mode.

mode 29

 Mode 29 est un mode graphique SuperVGA avec une résolution de 1024 horizontale

pixels par 768 pixels verticaux. Chaque pixel peut prendre l'une des 16 couleurs (16 couleurs peuvent être sélectionnées à partir d'une palette de 262.144 couleurs), de sorte que chaque pixel nécessite quatre bits de mémoire vidéo. Dans ce mode, la mémoire vidéo est organisée en quatre plans de bits. Chaque adresse de mémoire vidéo fait référence en fait quatre octets, un dans chaque plan. En d'autres termes, chaque octet de mémoire vidéo fait référence à huit pixels, stockées un bit par avion. Au moins 512K de mémoire vidéo est nécessaire pour utiliser ce mode. Guide de l'utilisateur 40 Fastgraph



chapitre 3


Initialisation Guide de l'utilisateur Vidéo Environnement 42 Fastgraph


aperçu

 Avant Fastgraph peut effectuer toutes les opérations du texte ou des graphiques vidéo, vous

doit sélectionner un mode vidéo dans lequel votre programme sera exécuté. Une partie importante de cette sélection dépend de votre programme sera exécuté en mode texte, un mode graphique, ou les deux. Les deux premières sections de ce chapitre discutent de l'initialisation vidéo nécessaire pour les modes de texte et de graphiques standard, tandis que la dernière section traite de la configuration supplémentaire nécessaire pour SuperVGA (SVGA) modes graphiques.


Mise en place d'un mode texte

 Lorsque vous écrivez un programme qui utilise uniquement des modes de texte, vous devez déterminer si

le programme sera exécuté sur les systèmes monochromes, des systèmes de couleurs, ou les deux. En général, il n'y a aucune raison d'exclure un type de système, car la programmation supplémentaire nécessaire pour soutenir à la fois est assez trivial.

 La fg_setmode routine Fastgraph établit un mode vidéo et initialise

paramètres internes de Fastgraph pour ce mode. Cette routine a un seul argument entier dont la valeur est une vidéo numéro de mode entre 0 et 29. Sa valeur peut aussi être -1, ce qui indique Fastgraph d'utiliser le mode vidéo actuel. Spécification d'un argument fg_setmode de -1 est souvent utile dans les programmes qui utilisent uniquement les modes vidéo de texte.

 Lorsque vous établissez un mode vidéo texte, la ROM BIOS curseur de texte est fait

visible, ce qui est souvent indésirable. La fg_cursor routine Fastgraph contrôle la visibilité du curseur de texte. La routine de fg_cursor a un seul argument entier qui spécifie la visibilité du curseur. Si sa valeur est 0, le curseur est rendu invisible; si sa valeur est 1, le curseur est rendu visible.

 À ce stade, un exemple peut aider à clarifier les choses.  Nous allons commencer par un

variation célèbre "Bonjour, monde" programme de Kernighan et Ritchie qui montre comment initialiser Fastgraph pour les 80 colonnes en mode texte couleur (mode 3) et désactiver le curseur en mode texte. Il utilise deux routines Fastgraph que nous avons pas encore discuté, fg_setcolor et fg_text. Pour l'instant, il suffira de savoir que fg_setcolor (15) rend le texte ultérieur apparaissent en blanc, et fg_text affiche les caractères qui lui sont transmis.

 Exemple 3-1.
 #include <fastgraf.h>
                       void main (void);
 void main ()
                       {
                          fg_initpm ();
                          fg_setmode (3);
                          fg_cursor (0);
 fg_setcolor (15);
                          fg_text ( "Bonjour, monde.", 13);
                       }
                          Chapitre 3: Initialisation de l'environnement Vidéo 43


 Si vous exécutez par exemple 3-1, notez le texte affiché par le programme apparaît

dans le coin supérieur gauche de l'écran. Sur la ligne ci-dessous présente, l'invite DOS apparaît, en attendant votre prochaine commande DOS. En outre, si votre système utilise le pilote ANSI.SYS pour définir les attributs de l'écran (par exemple avec le programme de SA de Norton), vous devriez également remarquer que l'invite DOS apparaît dans les couleurs définies par l'écran attributs - le reste de l'écran est vide .

 Un retour plus gracieux au DOS est nécessaire.  Dans l'exemple 3-2, nous allons utiliser le

Fastgraph fg_reset routine. Cette routine efface l'écran, et si le pilote ANSI.SYS est chargé, fg_reset restaure également tous les attributs d'écran précédemment définis. Nous avons également inclus un appel à la routine fg_waitkey Fastgraph attendre une touche avant de quitter. Si nous ne faisons pas cela, nous ne serions jamais voir la sortie du programme.

 Exemple 3-2.
 #include <fastgraf.h>
                       void main (void);
 void main ()
                       {
                          fg_initpm ();
                          fg_setmode (3);
                          fg_cursor (0);
 fg_setcolor (15);
                          fg_text ( "Bonjour, monde.", 13);
                          fg_waitkey ();
 fg_reset ();
                       }


 Depuis des exemples 3-1 et 3-2 utilisent spécifiquement mode vidéo 3, ils ne seraient pas

travailler sur un système monochrome. Idéalement, nous aimerions utiliser fg_setmode (3) pour les systèmes de couleurs et fg_setmode (7) pour les systèmes monochromes. Pour ce faire, nous avons besoin d'un moyen de déterminer si le programme est exécuté sur un système de couleur ou sur un système monochrome. L'exemple suivant illustre un moyen facile de faire cela.

 Exemple 3-3 utilise la routine fg_testmode Fastgraph pour déterminer si le

Le système de l'utilisateur appuiera le numéro de mode vidéo spécifié comme premier argument (le second argument est le nombre de pages vidéo nécessaire, qui sera 1 pour tous les exemples de cette section). La routine fg_testmode renvoie une valeur de 1 (comme valeur de fonction) si le mode vidéo demandé peut être utilisé, et il renvoie la valeur 0 sinon. Le programme voit d'abord si un mode texte couleur 80 colonnes est disponible (mode 3), et si oui, il sélectionne ce mode. Si le mode de couleur ne sont pas disponibles, il vérifie si le mode de texte monochrome est disponible (mode 7), et si oui, il choisit le mode monochrome. Si aucun mode est disponible, le programme suppose le système de l'utilisateur dispose d'un écran 40 colonnes, émet un message indiquant le programme nécessite un affichage de 80 colonnes, puis quitte.

 Exemple 3-3.
 #include <fastgraf.h>
                  #include <stdio.h>
                  #include <stdlib.h>

Guide de l'utilisateur 44 Fastgraph


 void main (void);
 void main ()
                  {
                     int old_mode;
 fg_initpm ();
                     fg_getmode old_mode = ();
 if (fg_testmode (3,1))
                        fg_setmode (3);
                     else if (fg_testmode (7,1))
                        fg_setmode (7);
                     autre {
                        printf ( "Ce programme nécessite \ n");
                        printf ( "un affichage de 80 colonnes. \ n");
                        sortie (1);
                        }
                     fg_cursor (0);
 fg_setcolor (15);
                     fg_text ( "Bonjour, monde.", 13);
                     fg_waitkey ();
 fg_setmode (old_mode);
                     fg_reset ();
                  }


 Exemple 3-3 illustre également une autre procédure utile.  C'est recommandé,

en particulier dans les modes graphiques, pour restaurer le mode vidéo d'origine et de l'écran des attributs avant qu'un programme retourne au DOS. Nous avons déjà vu comment la routine fg_reset restaure les attributs de l'écran, mais comment pouvons-nous restaurons le mode vidéo original? La fg_getmode routine Fastgraph renvoie le mode vidéo actuel comme valeur de fonction. Si nous appelons fg_getmode avant d'appeler fg_setmode, nous pouvons sauver la valeur de retour de fg_getmode et le transmettre à fg_setmode juste avant le programme se termine.

 Vous pouvez également utiliser une autre Fastgraph routine, fg_bestmode, afin de déterminer si

un mode vidéo avec une résolution spécifique est disponible sur le système de l'utilisateur. La routine de fg_bestmode nécessite trois arguments entiers: une résolution horizontale, une résolution verticale, et le nombre de pages vidéo nécessaires. Comme sa valeur de fonction, fg_bestmode renvoie le numéro de mode vidéo qui offre le plus de capacités pour la résolution et le nombre de pages demandées. Il renvoie une valeur de -1 si aucun mode vidéo disponible offre aux critères demandés.

 Par exemple, si nous avons besoin d'un mode texte 80x25, nous pouvons utiliser la fonction

appeler fg_bestmode (80,25,1) pour choisir le "meilleur" mode vidéo disponible qui offre cette capacité. Dans les modes de texte, le terme signifie mieux pour donner la préférence à un mode de texte de couleur sur un mode texte monochrome. Exemple 3-4 remplit la même fonction que dans l'exemple 3-3, mais elle utilise plutôt que fg_bestmode fg_testmode.

 Exemple 3-4.
 #include <fastgraf.h>
                  #include <stdio.h>
                          Chapitre 3: Initialisation de l'environnement Vidéo 45


 #include <stdlib.h>
                  void main (void);
 void main ()
                  {
                     int old_mode;
                     int new_mode;
 fg_initpm ();
                     fg_getmode old_mode = ();
                     new_mode = fg_bestmode (80,25,1);
 if (new_mode <0) {
                        printf ( "Ce programme nécessite \ n");
                        printf ( "un affichage de 80 colonnes. \ n");
                        sortie (1);
                        }
 fg_setmode (new_mode);
                     fg_cursor (0);
 fg_setcolor (15);
                     fg_text ( "Bonjour, monde.", 13);
                     fg_waitkey ();
 fg_setmode (old_mode);
                     fg_reset ();
                  }


Modes de texte de 43 lignes et 50 lignes

 Lors de l'utilisation d'un mode texte de 80 colonnes sur un système équipé d'un EGA, VGA,

MCGA, ou SVGA d'affichage vidéo et l'adaptateur, vous pouvez étendre la taille de l'écran de 25 lignes à 43 ou 50 lignes. Alors que tous les systèmes offrent des modes de texte 25 systèmes en ligne EGA, offrent également des modes 43 de ligne, les systèmes MCGA offrent également des modes de 50 lignes, et des systèmes VGA et SVGA offrent à la fois des modes de 43 lignes et de 50 lignes. Le mode 43-ligne ne sont pas disponibles sur les systèmes EGA équipés d'un affichage RGB. Si vous étendez la taille de l'écran à 43 ou 50 lignes, la taille des caractères physiques est réduit proportionnellement de façon toutes les lignes apparaissent à l'écran.

 La routine de fg_setlines définit le nombre de lignes de texte par écran.  Il

a un seul argument entier dont la valeur doit être 25, 43 ou 50. Si vous passez toute autre valeur à fg_setlines, ou passez une valeur non prise en charge par la configuration vidéo du système hôte, fg_setlines ne fait rien. En outre, appelant fg_setlines rend le curseur de texte visible. Une autre routine Fastgraph, fg_getlines, retourne comme valeur de fonction du nombre de lignes de texte actuellement en vigueur. Vous pouvez également utiliser fg_getlines dans les modes graphiques vidéo.

 Exemple 3-5 illustre l'utilisation des fg_setlines et fg_getlines

routines. Le programme établit d'abord le mode texte de couleur 80 colonnes (cela définit la taille de l'écran à sa 25 ligne par défaut) et rend le curseur de texte invisible. Il affiche ensuite les mots «première ligne» dans le coin supérieur gauche de l'écran. Ensuite, le programme vérifie si un EGA avec affichage amélioré est disponible, et si oui, change l'écran à 43 lignes (mode vidéo 16 est Guide de l'utilisateur seulement 46 Fastgraph


disponible sur les systèmes EGA équipés d'un affichage amélioré). Ensuite, le programme vérifie si un VGA, MCGA, ou SVGA est disponible, et si oui change l'écran à 50 lignes (mode vidéo 17 est disponible uniquement sur ces systèmes). Enfin, le programme restaure le mode vidéo original, restaure le nombre de lignes par écran à son réglage d'origine, et restaure l'écran d'origine attributs avant de quitter.

 Exemple 3-5.
 #include <fastgraf.h>
                        void main (void);
 void main ()
                        {
                           lignes int;
                           int old_lines;
                           int old_mode;
 fg_initpm ();
                           fg_getlines old_lines = ();
                           fg_getmode old_mode = ();
                           fg_setmode (3);
                           fg_cursor (0);
 fg_setcolor (15);
                           fg_text ( "première ligne", 10);
                           fg_waitkey ();
 if (fg_testmode (16,0)) {
                              fg_setlines (43);
                              fg_cursor (0);
                              fg_waitkey ();
                              }
 if (fg_testmode (17,0)) {
                              fg_setlines (50);
                              fg_cursor (0);
                              fg_waitkey ();
                              }
 fg_setmode (old_mode);
                           (fg_setlines old_lines);
                           fg_reset ();
                        }


L'établissement d'un mode graphique

 Les étapes pour établir un mode graphique sont similaires à l'établissement d'un

mode texte. Cependant, il y a plus de restrictions depuis certains systèmes ne peuvent pas supporter tous les modes graphiques vidéo. Par exemple, un programme ne peut pas fonctionner en mode 13 sur un système CGA, ni une exécution du programme en mode 9 sur quoi que ce soit, sauf un système Tandy 1000 ou PCjr pouvait.

 Chapitre 3: Initialisation de l'environnement Vidéo 47


 Pour les programmes graphiques, il peut suffire d'écrire un programme à exécuter dans un

mode vidéo spécifique, mais il est souvent plus souhaitable d'écrire un programme qui se déroulera dans l'un des plusieurs modes vidéo. Cela est particulièrement vrai pour les produits commerciaux, car ils devraient idéalement fonctionner sur autant de configurations vidéo différents que possible.

 Fastgraph comprend une fg_automode nommée routine qui détermine la

graphiques mode vidéo qui offre le plus de fonctionnalités pour la configuration matérielle de la vidéo de l'utilisateur. Par exemple, les ordinateurs Tandy 1000 de la série prennent en charge les trois modes CGA (4, 5 et 6) et 16 couleurs Tandy en mode 320x200 1000 (9). Parmi ces modes, le mode 9 offre le plus de fonctionnalités à partir d'un point de vue graphique, donc fg_automode retournera une valeur de 9 lorsqu'il est exécuté sur un ordinateur Tandy 1000. Le tableau suivant résume les numéros de mode vidéo renvoyés par fg_automode pour les combinaisons adaptateur-affichage donné. Pour maintenir la compatibilité avec les versions antérieures de Fastgraph, fg_automode ne considère pas les modes graphiques VGA étendus (modes 20 à 23) ou les modes (modes 24 à 29) lors de la sélection d'un mode vidéo SVGA graphiques.


 afficher
                      adaptateur mono RGB ECD VGA
 MDA 7 0 7 7
                         HGC 11 0 0 11
                         CGA 0 4 0 0
                         EGA 15 13 16 0
                         VGA 17 17 17 18
                        MCGA 17 17 17 19
                       Tandy 7 9 0 0
                        PCjr 7 9 0 0


 Exemple 3-6 montre comment utiliser fg_automode pour déterminer les graphiques "meilleurs"

Mode pour le matériel vidéo de l'utilisateur. Dans un mode graphique, le terme signifie la meilleure résolution la plus élevée, suivie par le nombre de couleurs disponibles. Le programme affiche un message qui inclut le numéro de mode vidéo sélectionné.

 Exemple 3-6.
 #include <fastgraf.h>
                   #include <stdio.h>
                   void main (void);
 void main ()
                   {
                      int old_mode;
                      int new_mode;
                      chaîne char [4];
 fg_initpm ();
                      fg_getmode old_mode = ();
                      fg_automode new_mode = ();
                      fg_setmode (new_mode);
 fg_setcolor (15);
                      fg_text ( «Je suis en cours d'exécution en mode", 20); 

Guide de l'utilisateur 48 Fastgraph


 sprintf (string, "% d.", new_mode);
                      fg_text (string, 3);
                      fg_waitkey ();
 fg_setmode (old_mode);
                      fg_reset ();
                   }


 Pour les programmes simples comme par exemple 3-6, différentes résolutions d'écran peut

pas être un problème. Cependant, dans des programmes graphiques plus complexes, il est souvent souhaitable d'écrire un programme pour une résolution d'écran fixe. Une pratique courante consiste à élaborer des programmes graphiques pour exécuter en mode 4 (pour les CGA), 9 (Tandy 1000 ou PCjr), 12 (Hercules), 13 (EGA, VGA ou SVGA), et 19 ou 20 (MCGA, VGA, ou SVGA). La raison de la sélection de ces cinq modes est qu'ils utilisent tous la même résolution 320x200 et fonctionne sur tout PC IBM ou PS / 2 avec des capacités graphiques.

 Exemple 3-7 remplit la même fonction que dans l'exemple 3-6, mais il utilise

fg_bestmode au lieu de fg_automode de limiter le programme aux modes graphiques 320x200. Pour cette résolution, la routine de fg_bestmode va d'abord vérifier la disponibilité du mode 20, suivi de modes 19, 13, 9, 4 et 12. Si fg_bestmode détermine pas le mode 320x200 graphique est disponible (indiqué par une valeur de retour de -1), le programme imprime un message et des sorties d'information. Dans le cas contraire, il sélectionne le mode fg_bestmode vidéo propose et continue.

 Exemple 3-7.
 #include <fastgraf.h>
    #include <stdio.h>
    #include <stdlib.h>
    void main (void);
 void main ()
    {
       int old_mode;
       int new_mode;
       chaîne char [4];
 fg_initpm ();
       fg_getmode old_mode = ();
       new_mode = fg_bestmode (320,200,1);
 if (new_mode <0) {
          printf ( "Ce programme nécessite un mode 320 de 200 graphiques. \ n");
          sortie (1);
          }
 fg_setmode (new_mode);
 fg_setcolor (15);
       fg_text ( «Je suis en cours d'exécution en mode", 20);
       sprintf (string, "% d.", new_mode);
       fg_text (string, 3);
       fg_waitkey (); 
                          Chapitre 3: Initialisation de l'environnement Vidéo 49


 fg_setmode (old_mode);
       fg_reset ();
    }


 Si un programme se déroulera dans les modes vidéo spécifiques, vous pouvez envisager

en utilisant la routine de fg_testmode au lieu de fg_bestmode pour vérifier la disponibilité de ces modes vidéo. Vous pouvez également vouloir utiliser fg_testmode pour changer la priorité du mode vidéo utilisé par fg_bestmode. Par exemple, le mode 13 (EGA) est plus rapide que le mode 19 (MCGA), de sorte que vous voudrez peut-être envisager de donner la priorité EGA sur MCGA, surtout si votre programme ne pas utiliser plus de 16 couleurs.

 Exemple 3-8 est similaire à l'exemple 3-7, mais il ne fonctionnera que dans le

320x200 modes graphiques EGA, MCGA, et CGA (modes vidéo 13, 19 et 4, respectivement). Le programme utilise fg_testmode pour sélectionner son mode vidéo. Notez l'ordre des appels à fg_testmode donne la priorité EGA sur MCGA et MCGA préséance sur CGA.

 Exemple 3-8.
 #include <fastgraf.h>
       #include <stdio.h>
       #include <stdlib.h>
       void main (void);
 void main ()
       {
          int old_mode;
          chaîne char [4];
 fg_initpm ();
          fg_getmode old_mode = ();
 if (fg_testmode (13,1))
             fg_setmode (13);
          else if (fg_testmode (19,1))
             fg_setmode (19);
          else if (fg_testmode (4,1))
             fg_setmode (4);
          autre {
             printf ( "Ce programme nécessite un EGA, MCGA, CGA ou \ n.");
             sortie (1);
             }
 fg_setcolor (15);
          fg_text ( «Je suis en cours d'exécution en mode", 20);
          sprintf (string, "% d.", getMode ());
          fg_text (string, 3);
          fg_waitkey ();
 fg_setmode (old_mode);
          fg_reset ();
       }

Guide de l'utilisateur 50 Fastgraph

SuperVGA Modes graphiques

 Contrairement aux générations précédentes de cartes graphiques, il n'y avait pas de vidéo

norme en place lorsque différentes entreprises ont commencé à développer des cartes SVGA. En conséquence, ils ont mis en œuvre des fonctionnalités améliorées SVGA en fonction de leurs propres caractéristiques basées sur différentes puces de contrôleur vidéo. Chaque telle mise en œuvre est appelé un chipset. Bien que chaque chipset offre généralement la même organisation de mémoire vidéo et les résolutions d'écran courantes, les caractéristiques SVGA- tels que le mode d'initialisation, la commutation de banque, et réglage de l'adresse de début d'affichage diffèrent radicalement entre les chipsets. En d'autres termes, le code écrit pour un SVGA chipset spécifique ne fonctionnera pas sur un autre chipset, même à la même résolution. Voilà pourquoi de nombreux fournisseurs de logiciels offrent différents pilotes SVGA pour leurs produits.

 le noyau SVGA intégré de Fastgraph rend ces différences obscures

entre SVGA chipsets transparent, sans la nécessité pour les conducteurs externes. Cela signifie, par exemple, si vous écrivez une application pour le 1024 768 256 couleurs en mode graphique SVGA, il fonctionnera sans modifications sur tout chipset SVGA soutenu qui offre cette résolution. Le noyau SVGA prend en charge les chipsets répertoriés dans le tableau ci-dessous. Une entrée "Y" signifie que le chipset supporte le mode vidéo, et un "N" signifie qu'il ne fait pas. Les deux dernières lignes du tableau montrent la quantité minimale de mémoire vidéo requis pour soutenir chaque mode et les numéros de mode vidéo correspondant de Fastgraph.

 -------- -------- 256 couleurs - 16 couleurs -

SVGA chipset 640x400 640x480 800x6001024x768 800x6001024x768 Ahead type "A" YYYNYY Ahead type "B" YYYYYY ARK Logic série 1000/2000 YYYYYY ATI 18800 YYYNYN ATI 18800-1 YYYNYY ATI 28800 / mach32 / mach64 YYYYYY Avance Logic 2000 série YYYYYY Chips & Technologies 82c451 YNNNYN Chips & technologies 82c452 YYNNYY Chips & technologies 82c453 YYYYYY Chips & Tech 64xxx / 655xx YYYYYY Cirrus Logic 5400/6200/7540 NYYYYY Cirrus Logic 6400 série YYYYYY Genoa 6000 YYYNYY Matrox MGA-2064W (Millennium) YYYYYN NCR 77C22 / 77C32 YYYYYY Oak OTI- 067 NYYNYY Oak OTI-077 NYYYYY Oak OTI-087 YYYNYY Paradise PVGA1a YYNNYN Paradise WD90C00 / 10/24 YYNNYY Paradise WD90C11 / 30 / 31/33 YYYYYY Realtek 3100 séries YYYYYY S3 NYYYYY SiS YYYYYY Trident 8800 YYYNYY Trident 8900/9000 YYYYYY Tseng ET3000 NYYNYY Tseng ET4000 YYYYYY Video7 YYYYYY vidéo RAM minimum nécessaire 256K 512K 512K 256K 512K 1MB Fastgraph de numéro de mode 24 25 26 27 28 29

 Chapitre 3: Initialisation de l'environnement Vidéo 51


Le noyau SVGA cartes des numéros de mode vidéo de Fastgraph (24 à 29) pour les numéros de mode spécifiques le chipset. Par exemple, le mode 256 couleurs SVGA 640x480 est 62 hex sur une carte ATI, 5D hex sur une carte Trident et 2F hex sur une carte Tseng, mais il est toujours en mode 25 du point de vue Fastgraph. Comme nous ajoutons constamment de soutien pour les nouveaux chipsets SVGA, s'il vous plaît consulter le fichier READ.ME de Fastgraph pour la liste de chipset actuel. Le fichier READ.ME répertorie également les problèmes connus et les limites avec les différents chipsets.

 La Video Electronics Standards Association (VESA de) a pris la

tâche complexe d'améliorer la compatibilité des logiciels de cartes SVGA de différentes entreprises. La plupart des cartes SVGA vendus aujourd'hui comprennent la compatibilité VESA, soit directement dans la ROM ou par l'intermédiaire des pilotes logiciels chargeables fournis avec la carte. En plus de soutenir les chipsets spécifiques, SVGA le noyau de Fastgraph prend en charge toutes les cartes SVGA avec une compatibilité VESA. Notez que VESA est pas un chipset, mais une interface au niveau du BIOS entre une application (le noyau SVGA dans ce cas) et les fonctions spécifiques au chipset. Bien que la norme VESA actuelle couvre tous les modes graphiques six SVGA Fastgraph soutient, ces modes ne sont disponibles que si le chipset sous-jacent les prend en charge également.

 Lorsque vous utilisez la compatibilité VESA, le BIOS VESA gère tout chipset spécifique

des fonctions telles que le changement de banque. Les frais généraux imposés par le BIOS rend généralement le VESA modes plus lent que d'utiliser directement des fonctions spécifiques du chipset. Pour cette raison, vous pouvez spécifier si vous voulez donner la priorité au code spécifique chipset ou le BIOS VESA. priorité spécifique à Chipset signifie que le noyau SVGA utilisera uniquement le BIOS VESA si aucun chipset SVGA pris en charge est trouvé. A l'inverse, VESA priorité signifie que le noyau utilisera uniquement les fonctions spécifiques si le chipset ne VESA BIOS est trouvé.

 Avant d'utiliser un mode graphique SVGA, vous devez utiliser le fg_svgainit

routine pour initialiser le noyau SVGA (fg_svgainit doit être appelée avant fg_setmode, fg_bestmode ou fg_testmode). Il y a trois façons d'initialiser le noyau SVGA avec fg_svgainit:

 * Code autodetect le chipset SVGA, priorité du chipset spécifique
    * Autodetect le chipset SVGA, la priorité au BIOS VESA
    * Utiliser un chipset SVGA désigné

L'argument de la routine fg_svgainit est une valeur entière entre 0 et 34 qui spécifie la méthode d'initialisation à utiliser. En passant de 0 à fg_svgainit utilise la première méthode, dans laquelle le noyau recherches SVGA pour tous pris en charge les chipsets avant de vérifier si un BIOS VESA est présent. Cela signifie que le noyau SVGA utilisera uniquement les fonctions VESA si fg_svgainit ne trouve pas l'un des chipsets pris en charge. Passant 1 à fg_svgainit effectue également une autodetect chipset, mais dans ce cas, le noyau sur SVGA recherche un BIOS VESA, puis à travers la liste des chipsets pris en charge. Cela signifie code spécifique chipset ne sera utilisée que lorsque aucun VESA BIOS est trouvé. Vous pouvez également initialiser le noyau SVGA pour un chipset spécifique en passant une valeur comprise entre 2 et 34 à fg_svgainit. Le tableau suivant résume les codes fg_svgainit d'initialisation.

 Code chipset
         0 autodetect (avec priorité spécifique au chipset)
         1 autodetect (avec VESA priorité)
         "A" type 2 Ahead
         "B" type 3 Ahead

Guide de l'utilisateur 52 Fastgraph

         4 ATI 18800 5 ATI 18800-1 6 ATI 28800/38800 7 Chips & Technologies 82c451 / 455 / 456/457 8 Chips & technologies 82c452 9 Chips & Technologies 82c450 / 453 10 Gênes série 6000 11 Oak OTI-067 12 Paradise PVGA1a 13 Paradise WD90C00 / WD90C10 / WD90C24 14 Paradise WD90C11 / WD90C30 / WD90C31 / WD90C33 15 Trident 8800 16 Trident 8900/9000 17 Tseng ET3000 18 Tseng ET4000 19 Video7 20 Cirrus Logic 5400/6200/7540 série 21 S3 22 NCR 77C22 / 77C32 23 Oak OTI- 077 24 Oak OTI-087 25 Oak OTI-087 (Diamond Viper BIOS) 26 Cirrus Logic 6400 série 27 Avance Logic série 2000 28 ARK Logic 1000/2000 29 ATI 68800 (mach32) 30 ATI 88800 (mach64) 31 Chips & Technologies 64000 / 65500 série 32 Realtek 3100 série 33 Matrox MGA-2064W (Millennium) 34 SiS 
 Pour les demandes de détection automatique, fg_svgainit retourne une valeur comprise entre 1 et 32

correspondant au chipset SVGA trouvé. Si la valeur de retour est 1, cela signifie un BIOS VESA sera utilisé. Une valeur comprise entre 2 et 32 ​​signifie un chipset SVGA spécifique (comme indiqué dans le tableau ci-dessus) sera utilisée. Si aucun VESA BIOS ou soutenu chipset SVGA se trouve, fg_svgainit retourne zéro. Dans ce cas, les modes SVGA graphiques de Fastgraph ne sont pas disponibles.

 Lorsque vous demandez l'initialisation d'un chipset spécifique, fg_svgainit

renvoie toujours la valeur qui lui est passé. Il ne vérifie pas si ce chipset est effectivement présent, cette fonction doit être utilisée judicieusement.

 Exemple 3-9 est un programme simple qui vérifie si une carte SVGA est présent,

et si oui, affiche le nom du chipset SVGA. Il affiche également la façon dont la mémoire vidéo beaucoup est présent sur la carte SVGA et le numéro de version de SVGA le noyau de Fastgraph.

 Exemple 3-9.
           #include <fastgraf.h>
           #include <stdio.h>
           void main (void);
           char * Description [] = {
              "ne peut être déterminé",
              "VESA",
              "Ahead A",
              "Ahead B",
              "ATI 18800",
              "ATI 18800-1",
                          Chapitre 3: Initialisation de l'environnement Vidéo 53
              "ATI 28800/38800",
              "Chips & Technologies 82c451 / 455 / 456/457",
              "Chips & Technologies 82c452",
              "Chips & Technologies 82c450 / 453",
              "Gênes 6000",
              "Oak OTI-067",
              "Paradise PVGA1a",
              "Paradise WD90C00 / WD90C10",
              "Paradise WD90C11 / WD90C30 / WD90C31 / WD90C33",
              "Trident 8800",
              "Trident 8900/9000",
              "Tseng ET3000",
              "Tseng ET4000",
              "Video7",
              "Cirrus Logic 5400/6200/7540 série",
              "S3",
              "NCR 77C22 / 77C32",
              "Oak OTI-077",
              "Oak OTI-087",
              "Oak OTI-087 (Diamond Viper BIOS)",
              "Cirrus Logic 6400",
              "Avance Logic série 2000»,
              "ARK Logic 1000/2000",
              "ATI 68800 (mach32)",
              "ATI 88800 (mach64)",
              "Série Chips & Technologies 64000/65500",
              "Realtek série 3100",
              "Matrox MGA-2064W (Millennium)",
              "SiS"
           };
           void main ()
           {
              int id, majeur, mineur;
              fg_initpm ();
              id = fg_svgainit (0);
              printf ( "SVGA chipset:% s \ n", description [id]);
              printf ( "mémoire vidéo:% d kilooctets \ n", fg_memory ());
              fg_svgaver (et majeur, et mineur);
              printf ( ". SVGA Version:% d% 2.2d \ n", majeur, mineur);
           }

Cet exemple fg_svgainit utilise pour détecter SVGA chipset de l'utilisateur automatiquement. Il initialise le noyau SVGA donc code spécifique chipset est donné la priorité sur VESA (passant 1 au lieu de 0 à fg_svgainit donnerait VESA priorité). Notez que le programme ne crée pas un mode graphique SVGA - il utilise juste la valeur de retour de fg_svgainit pour identifier le chipset est présent.

 Exemple 9.3 comporte également deux autres sous-programmes pertinents pour la Fastgraph

kernel SVGA. La fonction fg_memory renvoie la quantité de mémoire vidéo (en kilo-octets) résidant sur la carte vidéo de l'utilisateur. Par exemple, la valeur de retour fg_memory est de 1.024 pour une carte 1MB SVGA. Une autre routine, fg_svgaver, retourne les numéros majeurs et mineurs pour le noyau SVGA, similaire à la routine de fg_version mentionné au chapitre 1. Notez que le numéro de version du noyau SVGA est pas le même que le numéro de version Fastgraph.

 Une autre fonction utile est fg_svgastat, qui renvoie des informations sur

l'état actuel de SVGA le noyau de Fastgraph. La fonction retourne un masque de bits dans lequel le bit 0 est défini si le noyau SVGA a été initialisé avec succès, et le bit 1 sera fixé si le noyau utilise le BIOS VESA. Guide de l'utilisateur Autres 54 Fastgraph


les bits fg_svgastat fournissent des informations sur la disponibilité des pages vidéo étendues et si oui ou non le chipset actif prend en charge lecture séparée et d'écrire les banques. Nous allons discuter de ces caractéristiques dans les chapitres suivants.

 Notre prochain exemple, 3-10, est une version SVGA d'exemple 3-8.  Ce programme

initialise le noyau SVGA de sorte que VESA aura préséance sur le code spécifique le chipset. Il appelle ensuite fg_testmode pour trouver un mode graphique SVGA 256 couleurs pris en charge, premier mode 27 (1024 par 768), alors le mode 26 (800x600), et enfin le mode 25 (640x480) essayer. Vérification des modes dans cette séquence assure le programme utilisera la plus haute résolution disponible, étant donné SVGA chipset de l'utilisateur (pas tous les chipsets supportent toutes les résolutions) et la quantité de mémoire vidéo présente (mode 27 nécessite 1MB de RAM vidéo, les modes 26 et 25 nécessité 512K ).

 Si les trois appels fg_testmode échouent dans l'exemple 3-10, le programme affiche

un message et sort approprié. Ce serait le cas si le programme était exécuté sur un système non-SVGA, exécuter sur un SVGA chipset non pris en charge sans compatibilité VESA, ou si la carte SVGA n'a pas au moins 512K de mémoire vidéo (modes 25, 26, et 27 ont tous besoin d'au moins 512K). Dans les deux premiers cas, la fonction fg_svgainit aurait pas initialisé le noyau SVGA, donc fg_testmode échouerait lors de la vérification de la disponibilité d'un mode graphique SVGA. Voilà pourquoi il est pas nécessaire de vérifier la valeur de retour de fg_svgainit dans ce cas.

 Exemple 3-10.
 #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main (void);
 void main ()
             {
                int old_mode;
                chaîne char [4];
 fg_initpm ();
                fg_getmode old_mode = ();
                fg_svgainit (1);
 if (fg_testmode (27,1))
                   fg_setmode (27);
                else if (fg_testmode (26,1))
                   fg_setmode (26);
                else if (fg_testmode (25,1))
                   fg_setmode (25);
                autre {
                   printf ( "Ce programme nécessite un SVGA»);
                   printf ( "avec au moins 512K de mémoire vidéo \ n.");
                   sortie (1);
                   }
 fg_setcolor (15);
                fg_text ( «Je suis en cours d'exécution en mode", 20);
                sprintf (string, "% d.", fg_getmode ());
                fg_text (string, 3);
                fg_waitkey (); 
                          Chapitre 3: Initialisation de l'environnement Vidéo 55


 fg_setmode (old_mode);
                fg_reset ();
             }


 Bien que la spécification VESA définit une interface de programmation commune pour

fonctions SVGA spécifiques chipset, nous devons nous rappeler que VESA est juste que - une spécification. Certains fabricants fournissent des pilotes VESA ou implémentations de BIOS qui réalisent la spécification complète VESA avec seulement de légères dégradations de performance. D'autres ne sont pas aussi bien, avoir des problèmes avec quoi que ce soit au-delà des fonctions rudimentaires de mode de l'initialisation et la commutation de la banque, sans parler des problèmes de performance.

 D'autres problèmes peuvent se produire avec les quelques cartes SVGA qui ne sont pas complètement

suivre les numéros de mode vidéo prédéfinis par le fabricant du chipset et enregistrer des définitions. Bien que le noyau SVGA permet à ces problèmes lorsqu'ils sont connus, il est tout simplement pas possible de soutenir toutes les cartes SVGA problématique. Pour compliquer les choses, certaines de ces cartes vidéo gênants ne présentent des problèmes dans certaines révisions, ce qui signifie deux cartes apparemment identiques se comporter différemment. Heureusement, ces cartes problématiques sont de loin l'exception.

 Si vous développez un produit SVGA pour la distribution générale, nous

recommandons d'utiliser le code spécifique de chipset Fastgraph par défaut, mais aussi de fournir un moyen de remplacer le code spécifique à chipset et utiliser le support VESA. Le plus souvent, cela se fait par la reconnaissance d'un commutateur de ligne de commande ou en utilisant un fichier de configuration spécifique à l'application. Certains programmeurs même prendre un peu plus loin en incluant un moyen d'éviter la procédure de autodetection SVGA et initialiser SVGA le noyau de Fastgraph pour un chipset spécifique. Cela pourrait être important si votre produit fonctionnera sur les systèmes portables, qui ont parfois SVGA sous-systèmes vidéo qui ne répondent pas aux demandes de autodetection aussi fiable que leurs homologues de bureau.

 Un autre point important à considérer lors de l'écriture d'applications SVGA est le

la compatibilité entre la carte vidéo et le moniteur. Pratiquement tous les moniteurs SVGA prises aujourd'hui ne pose aucun problème à l'appui de la bande passante requise par l'un des modes graphiques SVGA de Fastgraph. Cependant, certains moniteurs (plus particulièrement anciens moniteurs de multisync) ne peuvent pas supporter les modes de résolution supérieurs tels que 800x600 et 1024 par 768. Les contrôles du noyau SVGA si la carte SVGA prend en charge la résolution demandée, mais il ne vérifie pas si la combinaison carte / moniteur ne .


Résumé de la vidéo Initialisation Routines

 Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

 FG_AUTOMODE détermine le mode graphique vidéo qui offre le plus

fonctionnalités pour la configuration de l'affichage et l'adaptateur de l'utilisateur. La valeur retourne permet de déterminer une valeur appropriée pour passer à la routine de fg_setmode.

 FG_BESTMODE est similaire à fg_automode, mais il exclut les modes vidéo que

ne proposent pas les exigences de résolution et page vidéo spécifiées. Guide de l'utilisateur 56 Fastgraph


 FG_CURSOR rend le texte en mode curseur visible ou invisible.  Cette routine

n'a aucun effet lorsqu'il est utilisé dans un mode graphique.

 FG_GETLINES retourne le nombre de lignes de texte par écran pour le courant

mode vidéo.

 FG_GETMODE renvoie le mode vidéo actuel.  Il est généralement l'un des

premières routines Fastgraph appelé dans un programme. La valeur retournée par fg_getmode peut être utilisé pour restaurer le mode vidéo original lorsqu'un programme transfère le contrôle de retour au DOS.

 FG_MEMORY renvoie la quantité de mémoire vidéo présente (en kilo-octets) sur

La carte SVGA de l'utilisateur. Cette routine est significative seulement après initialisation avec succès le noyau SVGA avec fg_svgainit.

 FG_RESET est généralement la dernière routine Fastgraph appelé dans un programme.  Il

fonctionne uniquement en mode texte vidéo. Lorsque le pilote ANSI.SYS est pas chargé, fg_reset efface simplement l'écran. Lorsque ANSI.SYS est chargé, fg_reset restaure également tous les attributs d'écran précédemment définis.

 FG_SETLINES étend un mode 80 colonnes texte à 25, 43, ou 50 lignes par

écran. Cette routine est seulement significatif lors de l'exécution de 80 colonnes modes de texte sur EGA, VGA ou MCGA systèmes (dans d'autres cas, il ne fait rien).

 FG_SETMODE établit un mode vidéo et initialise Fastgraph INTERNE

paramètres pour ce mode vidéo. Il doit être appelé avant toute routine Fastgraph qui effectue une sortie vidéo. Un programme peut appeler fg_setmode autant de fois que nécessaire pour basculer entre les différents modes vidéo.

 FG_SVGAINIT initialise SVGA le noyau de Fastgraph et exécute le chipset

initialisation SVGA spécifique. Cette routine doit être appelée avant l'établissement d'un mode graphique SVGA avec fg_setmode.

 FG_SVGASTAT renvoie des informations sur l'état actuel de Fastgraph de

kernel SVGA.

 FG_SVGAVER retourne majeurs et mineurs numéros de version du noyau SVGA.
 FG_TESTMODE détermine si oui ou non un mode vidéo spécifié (avec

nombre donné de pages vidéo) est disponible sur le système de l'utilisateur.



Chapitre 4


Guide de systèmes de coordonnées 58 Fastgraph utilisateur


aperçu

 Fastgraph utilise trois systèmes de coordonnées pour effectuer le texte et les graphiques

sortie - espace de caractère, l'espace de l'écran, et de l'espace mondial. l'espace de caractères est utilisé en mode texte et éventuellement pour l'affichage des chaînes de caractères dans les modes graphiques. l'espace de l'écran est le système de coordonnées de base pour graphiques modes vidéo et utilise les coordonnées de périphériques physiques de l'écran. Viewports sont une extension de l'espace de l'écran qui vous permettent d'affecter un système basé entier coordonnée alternative à rectangulaire sous-ensembles de l'écran. Enfin, l'espace du monde est un user- définissable système de coordonnées pour les modes graphiques qui utilise des valeurs flottantes. L'espace de système de coordonnées ne sont pas disponibles dans Fastgraph / Lumière.


Espace de caractères

 Le système de coordonnées utilisé pour les caractères d'affichage est appelé caractère

espace. Fastgraph utilise l'espace de caractères pour afficher des caractères dans les deux modes texte et des graphiques vidéo (vous pouvez également utiliser l'espace de l'écran pour afficher les caractères dans les modes graphiques). un espace de caractère peut être considéré comme une grille de rangées et de colonnes, chaque cellule de la grille de maintien d'un caractère. Chaque cellule est identifiée par ses propres coordonnées (ligne, colonne) entiers. Les lignes et les colonnes sont numérotées à partir de zéro; l'origine est toujours le coin supérieur gauche de l'écran. Par exemple, dans le 80-colonne en modes 25 rangs texte (2, 3 et 7), la valeur par défaut (ligne, colonne) les coordonnées de l'écran coins sont présentés dans le schéma suivant.


 (0,0) (0,79)


 (24,0) (24,79)


Le nombre de lignes et de colonnes dépend du mode vidéo, comme indiqué dans le tableau suivant. Pour les modes graphiques, le tableau comprend également la largeur et la hauteur en pixels d'une cellule de caractère.

 Mode de Nombre de Nombre de Char.  Carboniser.
                         Colonnes Nombre de lignes Widthheight
 0 40 25
                            1 40 25
                            2 80 25
                            3 80 25
                            4 40 25 8 8
                            5 40 25 8 8
                            6 80 25 8 8
                            7 80 25
                            9 40 25 8 8
                           11 80 25 9 14
                           12 40 25 8 8
                           13 40 25 8 8
                           14 80 25 8 8
                           15 80 25 8 14
                                          Chapitre 4: Systèmes de coordonnées 59


 16 80 25 8 14
                           17 80 30 8 16
                           18 80 30 8 16
                           19 40 25 8 8
                           20 40 25 8 8
                           21 40 50 8 8
                           22 40 30 8 8
                           23 40 60 8 8
                           24 80 25 8 16
                           25 80 30 8 16
                           26 100 37 8 16
                           27 128 48 8 16
                           28 100 37 8 16
                           29 128 48 8 16
 Fastgraph comporte deux routines, et fg_getmaxx fg_getmaxy que,

retournent respectivement le nombre maximum de colonnes et de lignes en mode texte. Exemple 4-1 montre ces deux routines dans un mode texte. Le programme utilise fg_getmaxx et fg_getmaxy pour obtenir les colonnes et de lignes nombre maximum en mode 3. Il affiche ensuite ces valeurs (79 et 24).

 Exemple 4-1.
 #include <fastgraf.h>
                    #include <stdio.h>
                    void main (void);
 void main ()
                    {
                       int max_col;
                       int max_row;
                       Mode int;
 fg_initpm ();
                       mode = fg_getmode ();
                       fg_setmode (3);
 fg_getmaxx max_col = ();
                       fg_getmaxy max_row = ();
 fg_setmode (mode);
                       fg_reset ();
 printf ( "Last col =% d \ n", max_col);
                       printf ( "Dernière rangée =% d \ n", max_row);
                    }


Espace d'écran

 l'espace de l'écran est l'un des deux systèmes de coordonnées disponibles dans les graphiques

modes. Il utilise les coordonnées physiques de l'appareil. L'espace écran peut être considérée comme une grille de rangées et de colonnes, chaque unité de la grille de maintien d'un pixel. Chaque pixel est identifié par ses propres coordonnées (x, y) entiers. Les rangées de pixels et les colonnes sont numérotées à partir de zéro; l'origine est toujours le guide de l'utilisateur supérieure 60 Fastgraph


coin gauche de l'écran. Par exemple, dans les modes les graphiques 320x200, le (x, y) les coordonnées de l'écran coins sont présentés dans le schéma suivant.


 (0,0) (319,0)


 (0199) (319199)


 Le Fastgraph routines fg_getmaxx et fg_getmaxy reviennent le maximum x et

Y coordonnées écran lorsqu'il est utilisé dans un mode graphique, comme le montre l'exemple 4-2. Le programme utilise fg_getmaxx et fg_getmaxy pour obtenir le maximum de coordonnées x et y dans le mode 256 couleurs graphique standard VGA / MCGA (mode 19). Il affiche ensuite ces valeurs (319 et 199).

 Exemple 4-2.
 #include <fastgraf.h>
                      #include <stdio.h>
                      void main (void);
 void main ()
                      {
                         int maxx;
                         int maxy;
                         Mode int;
 fg_initpm ();
                         mode = fg_getmode ();
                         fg_setmode (19);
 maxx = fg_getmaxx ();
                         maxy = fg_getmaxy ();
 fg_setmode (mode);
                         fg_reset ();
 printf ( "(% d,% d) \ n", maxx, maxy);
                      }


viewports

 Viewports fournissent système de coordonnées pour un autre entier non

le référencement de pixels. Fastgraph comprend des routines pour créer une fenêtre, retourner les limites de viewport, et convertir les coordonnées viewport à leurs valeurs d'espace d'écran.

 Une définition de la fenêtre se compose de ses extrêmes dans «l'espace de la fenêtre» et

les limites dans l'espace de l'écran correspondant. La routine fg_setview définit une fenêtre. Ses quatre premiers paramètres représentent le minimum x, maximum x, y au minimum, et les coordonnées maximales de viewport y, et ses quatre derniers paramètres représentent les valeurs d'espace d'écran de pixels correspondants définissant la taille et l'emplacement physique de la fenêtre. Par exemple, l'appel

 Chapitre 4: Systèmes de coordonnées 61


 fg_setview (100,739,100,499,0,159,0,99);

créerait une fenêtre 640x400 dans le coin supérieur gauche d'un écran 320x200. Les coordonnées du viewport varieraient 100-739 horizontalement et 100-499 verticalement. En d'autres termes, la fenêtre de coordonnées (100,100) tracerait au pixel de l'espace de l'écran (0,0). Le schéma suivant illustre cette fenêtre. Les coordonnées de l'espace de la fenêtre apparaissent en caractères gras, tandis que les autres valeurs sont les coordonnées équivalentes de l'espace de l'écran.

 (100,100) (739,100)
 (0,0) (159,0) (319,0)


 (0,99) (159,99)
 (100,499) (739,499)


 (0199) (319199)


La routine de fg_getview de Fastgraph renvoie les limites de la fenêtre actuelle et les limites de l'espace de l'écran correspondant, tel que défini dans l'appel le plus récent à fg_setview.

 Une fois que vous avez défini une fenêtre, l'fg_xview et les fonctions de fg_yview

traduire les coordonnées viewport à leurs équivalents de l'espace de l'écran. Les valeurs traduites peuvent ensuite être transmis à toute routine Fastgraph qui attend les coordonnées de l'espace de l'écran. Par exemple, la routine de fg_rect de Fastgraph dessine un rectangle rempli dans l'espace de l'écran. Si vous voulez remplir la fenêtre définie ci-dessus avec la couleur 10 pixels, vous pouvez le faire comme suit:

 fg_setcolor (10);
      fg_rect (fg_xview (100), fg_xview (739), fg_yview (100) fg_yview (499));
 Exemple 4-3 montre une simple utilisation de fenêtres dans la norme

/ MCGA mode 256 graphiques couleur 320x200 VGA. Après avoir rempli l'écran avec blanc (couleur 15) pixels, il met en place une fenêtre dans le quadrant supérieur gauche de l'écran et fg_rect utilise pour le remplir avec bleu clair (couleur 9) pixels. Il définit ensuite trois nouvelles fenêtres dans les autres quadrants de l'écran, le remplissage de même le quadrant supérieur droit avec vert clair (couleur 10) de pixels, le quadrant inférieur gauche avec cyan clair (couleur 11) de pixels, et enfin le quadrant inférieur droit avec la lumière rouge ( 12) la couleur des pixels. Notez comment les mêmes coordonnées de viewport sont utilisés pour remplir la fenêtre dans chaque cas; seuls les changements de position de la fenêtre.

 Exemple 4-3.
 #include <fastgraf.h>
      void main (void);
 void main ()
      {
         Mode int; 

Guide de l'utilisateur 62 Fastgraph


 fg_initpm ();
         mode = fg_getmode ();
         fg_setmode (19);
         fg_setcolor (15);
         fg_rect (0,319,0,199);
         fg_waitkey ();
 fg_setview (0,639,0,399,0,159,0,99);
         fg_setcolor (9);
         fg_rect (fg_xview (0), fg_xview (639), fg_yview (0), fg_yview (399));
         fg_waitkey ();
 fg_setview (0,639,0,399,160,319,0,99);
         fg_setcolor (10);
         fg_rect (fg_xview (0), fg_xview (639), fg_yview (0), fg_yview (399));
         fg_waitkey ();
 fg_setview (0,639,0,399,0,159,100,199);
         fg_setcolor (11);
         fg_rect (fg_xview (0), fg_xview (639), fg_yview (0), fg_yview (399));
         fg_waitkey ();
 fg_setview (0,639,0,399,160,319,100,199);
         fg_setcolor (12);
         fg_rect (fg_xview (0), fg_xview (639), fg_yview (0), fg_yview (399));
         fg_waitkey ();
 fg_setmode (mode);
         fg_reset ();
      }


 Pour faire un viewport un "vrai" viewport, il est souvent souhaitable d'établir

écrêtage des limites à des extrêmes de la viewport. De cette façon, les fonctions de Fastgraph qui prennent en charge l'écrêtage dessinera seulement au sein de la fenêtre elle-même. L'appel suivant à fg_setclip établira les limites d'écrêtage souhaitées:

 fg_setclip (fg_xview (100), fg_xview (739), fg_yview (100) fg_yview (499));

La routine fg_setclip sera décrite plus en détail dans le chapitre 6.


World Space

 l'espace du monde est l'autre disponible système de coordonnées dans les modes graphiques.

Il utilise les coordonnées de virgule flottante définis par l'utilisateur. Fastgraph traduit coordonne l'espace du monde en coordonnées de périphériques physiques (espace de l'écran), et à cause de cela, il est un peu plus lent que d'utiliser l'espace de l'écran. l'espace du monde peut être considéré comme un plan cartésien norme étendant à partir du coin inférieur gauche de l'écran. L'espace mondial orientation verticale est donc inversé par rapport à l'espace de l'écran et les fenêtres.

 Tout programme qui utilise les coordonnées de l'espace mondial doit d'abord initialiser

internes paramètres spatiaux mondiaux de Fastgraph. La fg_initw routine Fastgraph est

 Chapitre 4: Systèmes de coordonnées 63


prévue à cet effet. La routine de fg_initw n'a pas d'arguments et doit être appelée avant toute autre routine qui utilise les coordonnées spatiales du monde.

 La prochaine étape dans l'utilisation de l'espace mondial est d'utiliser la routine Fastgraph

fg_setworld pour définir les coordonnées de l'espace mondial des bords de l'écran. La routine de fg_setworld a quatre arguments en virgule flottante - le minimum coordonnée x (bord gauche), le maximum coordonnée x (bord droit), le minimum coordonnée y (bord inférieur), et le maximum coordonnée y (bord supérieur). Par exemple, si vous définissez les coordonnées de l'espace du monde avec la déclaration

 fg_setworld (-10.0,10.0,0.0,2.5);

(x, y) les coordonnées des coins de l'écran seraient définis comme indiqué dans le schéma suivant.


 (-10.0,2.5) (10.0,2.5)


 (-10.0,0.0) (10.0,0.0)


Fastgraph comprend une fg_getworld routine qui renvoie les extrêmes de l'espace du monde, tels que définis dans l'appel le plus récent à fg_setworld.

 Exemple 4-4 utilise fg_setworld et fg_getworld pour illustrer un intéressant

application de l'espace mondial. Ce programme appelle un autre rafraîchissement routine nommée (non représenté) qui efface l'écran et en tire une certaine image en utilisant les coordonnées spatiales du monde. Le programme dessine l'image, attend une frappe, réduit l'espace du monde par un facteur de deux dans chaque direction, puis attire à nouveau l'image. Cela produit un effet de zoom dans lequel l'image apparaît deux fois plus grande que l'on était à l'origine.

 Exemple 4-4.
 #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main (void);
             redraw void (void);
 void main ()
             {
                int new_mode, old_mode;
                à double xmin, xmax, ymin, ymax;
 fg_initpm ();
                fg_getmode old_mode = ();
                fg_automode new_mode = ();
 if (new_mode == 0) {
                   printf ( "Ce programme nécessite des graphiques \ n.");
                   sortie (1);
                   }

Guide de l'utilisateur 64 Fastgraph


 fg_setmode (new_mode);
                fg_initw ();
 fg_setworld (0.0,40.0,0.0,30.0);
                redessiner ();
                fg_waitkey ();
 fg_getworld (& xmin, & xmax, & ymin, ymax &);
                fg_setworld (0.0, 0.5,0.0 * xmax, ymax * 0,5);
                redessiner ();
                fg_waitkey ();
 fg_setmode (old_mode);
                fg_reset ();
             }


Routines de conversion

 Parfois, il est nécessaire de convertir les coordonnées entre l'espace de caractère,

l'espace de l'écran, et de l'espace mondial. Fastgraph comprend huit routines de conversion, quatre pour les coordonnées x et quatre pour les coordonnées y, pour effectuer ces conversions. Ces routines renvoient la traduction de coordonnées que leur valeur de fonction.

 Les fg_xalpha et fg_yalpha routines convertissent les coordonnées de l'espace écran pour

espace de caractère. La routine de fg_xalpha convertit un espace de coordonnées x écran à la colonne d'espace de caractère qui contient les coordonnées. De même, la routine de fg_yalpha convertit un espace d'écran coordonnée y à l'espace rangée de caractères qui contient les coordonnées.

 Les fg_xconvert et fg_yconvert routines convertissent espace de caractère

coordonnées à l'espace de l'écran. La routine de fg_xconvert convertit une colonne d'espace de caractère à l'espace de l'écran de coordonnées de son pixel gauche. De même, la routine de fg_yconvert convertit un espace rangée de caractères à l'espace de l'écran de coordonnées de son sommet (numéro le plus bas) pixel.

 Les fg_xscreen et fg_yscreen routines convertir les coordonnées de l'espace monde

l'espace de l'écran. La routine de fg_xscreen translatés coordonnées x, tandis que la routine fg_yscreen traduit les coordonnées y. A l'inverse, les fg_xworld et fg_yworld routines convertir les coordonnées d'espace d'écran à l'espace mondial. La routine de fg_xworld translatés coordonnées x, tandis que la routine fg_yworld traduit les coordonnées y.


Résumé de coordonner Routines

 Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

 FG_GETMAXX retourne le maximum coordonnée x dans l'espace de l'écran lorsqu'il est utilisé dans

un mode graphique. Elle retourne le numéro de colonne maximale dans l'espace de caractère lorsqu'il est utilisé dans un mode texte.

 Chapitre 4: Systèmes de coordonnées 65


 FG_GETMAXY retourne le maximum coordonnée y dans l'espace de l'écran lorsqu'il est utilisé dans

un mode graphique. Il retourne le numéro de ligne maximale dans l'espace de caractère lorsqu'il est utilisé dans un mode texte.

 FG_GETVIEW renvoie les limites de la fenêtre actuelle et leur espace d'écran

équivalents, tel que défini dans l'appel le plus récent à fg_setview.

 FG_GETWORLD renvoie les limites de l'espace mondial actuel, tel que défini dans la

plus récent appel à fg_setworld.

 FG_INITW initialise paramètres internes de Fastgraph pour l'espace mondial.

Cette routine doit être appelée une fois, avant toute autre routine qui utilise coordonnées du monde.

 FG_SETVIEW définit une fenêtre avec les extrêmes spécifiées au

position spécifiée de l'espace de l'écran.

 FG_SETWORLD définit les coordonnées d'espace du monde qui correspondent à la

bords physiques de l'écran.

 Coordonnées FG_XALPHA et FG_YALPHA convertir l'espace de l'écran à caractère

espace.

 FG_XCONVERT et FG_YCONVERT convertir les coordonnées d'espace de caractères à l'écran

espace.

 Coordonnées FG_XSCREEN et FG_YSCREEN convertir l'espace du monde à l'écran

espace.

 Coordonnées FG_XVIEW et FG_YVIEW converti viewport à l'espace de l'écran.
 Coordonnées FG_XWORLD et FG_YWORLD convertir l'espace de l'écran à l'espace mondial. 

Guide de l'utilisateur 66 Fastgraph



Chapitre 5


L'utilisation du Guide de couleur 68 Fastgraph utilisateur


aperçu

 L'utilisation de la couleur est un élément important de tout texte ou des graphiques

application. Ce chapitre explique la couleur qu'il applique au texte et les modes graphiques. Il décrit également les palettes et la vidéo DAC enregistre pour les modes graphiques vidéo qui offrent cette fonctionnalité. Enfin, une explication de couleurs virtuelles de Fastgraph est fourni.


Modes de texte

 La couleur à long terme ne sont pas vraiment correct en mode texte, car chaque caractère

la cellule a un attribut associé qui contrôle l'apparence du personnage dans cette cellule. La signification de l'attribut diffère de couleur et monochrome mode texte.


Modes de texte Couleur

 En couleur mode texte (modes 0, 1, 2 et 3), l'attribut détermine un

couleur de premier plan de caractère (la couleur du personnage lui-même), sa couleur d'arrière-plan (la couleur de cette partie de la cellule de caractère non couvert par le caractère), et si oui ou non il clignote. Seize couleurs de premier plan (numérotés de 0 à 15) sont disponibles, mais seulement huit couleurs de fond (numérotés de 0 à 7) sont disponibles. Les couleurs attribuées à ces valeurs sont répertoriées dans le tableau suivant.

 le numéro de couleur couleur
 0 noir 8 gris foncé
                        1 bleu 9 bleu clair
                        2 vert 10 vert clair
                        3 cyan cyan clair 11
                        4 rouge 12 rouge clair
                        5 magenta 13 magenta clair
                        6 brun 14 jaune
                        7 gris 15 blanc

Au début, il peut sembler que les chiffres ont été arbitrairement assignés aux couleurs. Après vérification, cependant, il devient évident que c'est pas le cas. Chaque numéro de couleur est une quantité de quatre bits de la forme IRGB, avec I représentant l'intensité, R la composante rouge, G la composante verte, et B la composante bleue. Si le bit correspondant est égal à 1, cela signifie que l'intensité ou la composante de couleur est réglée. Par exemple, rouge normale serait représenté par le motif binaire IRGB 0100, qui est de 4 décimales, le nombre de couleurs pour le rouge.

 La routine fg_setattr définit l'attribut de texte actuel.  Une seul fois

fg_setattr est appelé, Fastgraph affiche tout le texte ultérieur utilisant cet attribut. Le premier argument de fg_setattr définit la couleur de premier plan, qui doit être un entier compris entre 0 et 15. Son second argument définit la couleur d'arrière-plan, qui doit être compris entre 0 et 7. Son troisième argument détermine si le voyant de couleur de premier plan (1 signifie qu'il clignote , 0 signifie qu'il ne fait pas). Par exemple, la déclaration

 fg_setattr (14,1,0); 
                                            Chapitre 5: L'utilisation de la couleur 69


spécifie le texte qui suit sera affiché avec un premier plan jaune (14) sur un fond bleu (1) et ne clignote pas (0).

 Une autre routine Fastgraph, fg_setcolor, peut également définir des attributs de texte.

La routine fg_setcolor emballe les trois valeurs passées à fg_setattr en un seul argument, comme indiqué ici:

 les bits d'attribut
 0-3 couleur de premier plan
                            la couleur d'arrière-plan 4-6
                             7 clignotant

Par exemple, appeler fg_setcolor avec un argument de 30 (1E hex) équivaut à appeler fg_setattr avec des arguments de 14, 1 et 0.

 La routine Fastgraph fg_getcolor renvoie l'attribut de texte actuel, comme

définis dans l'appel le plus récent à fg_setattr ou fg_setcolor. La routine de fg_getcolor n'a pas d'arguments et renvoie l'attribut comme valeur de fonction. La valeur retournée est codée en utilisant le même schéma pour faire passer un attribut de texte à fg_setcolor.


Mode texte Monochrome

 Dans le mode de texte monochrome (mode 7), les couleurs ne sont évidemment pas disponibles.

L'attribut détermine la place si un caractère est invisible, normal, bold, inversé, ou certaines combinaisons de ceux-ci. Le tableau suivant montre les valeurs attribuées aux caractéristiques d'affichage disponibles.

 fond plan caractéristique
 0 0 invisible
                        0 7 renversé
                        1 0 souligné
                        7 0 normale
                        9 0 souligné gras
                       15 0 gras

En outre, vous pouvez activer ou désactiver à clignoter pour chacune de ces combinaisons. Toute combinaison de valeurs de premier plan et d'arrière-plan qui ne figurent pas dans le tableau ci-dessus donne une caractéristique d'affichage normal.

 Comme dans les modes de couleur, la Fastgraph routines fg_setattr et fg_setcolor

définir l'attribut de texte actuel. Par exemple, la déclaration

 fg_setattr (0,7,1);

spécifie le texte qui suit sera affiché en vidéo inverse (0,7) et clignote (1). Le même attribut peut être défini en appelant fg_setcolor avec un argument de 240 (F0 hex). La routine de fg_getcolor est également disponible et fonctionne comme il le fait dans les modes de texte de couleur. Guide de l'utilisateur 70 Fastgraph


Modes graphiques

 Dans un mode graphique, chaque pixel a une valeur de couleur associée que

détermine la couleur dans laquelle le pixel est affiché. Le nombre de couleurs disponibles dépend du mode vidéo et peut être obtenue grâce à la fonction fg_colors. Certains modes graphiques ont aussi des registres ou vidéo palette DAC enregistre pour fournir des capacités de couleurs supplémentaires, telles que le choix d'un ensemble de couleurs à partir d'une plus grande palette de couleurs. Les exemples de programmes présentés dans cette section montrent l'utilisation de la couleur dans les modes graphiques vidéo spécifiques.

 Les paragraphes suivants discuteront de l'utilisation de la couleur dans chaque graphique

mode vidéo. Dans ces discussions, il y aura plusieurs références à un groupe de couleurs appelé le jeu de couleurs standard. Ceci est un ensemble de 16 couleurs communes à un grand nombre des modes graphiques vidéo (et aux modes de texte de couleur). Les couleurs du jeu de couleurs standard sont listés dans le tableau suivant.

 le numéro de couleur couleur
 0 noir 8 gris foncé
                        1 bleu 9 bleu clair
                        2 vert 10 vert clair
                        3 cyan cyan clair 11
                        4 rouge 12 rouge clair
                        5 magenta 13 magenta clair
                        6 brun 14 jaune
                        7 gris 15 blanc
 À ce stade, nous devons comprendre la différence entre la couleur des termes

nombre et valeur de couleur. Numéro de couleur se réfère au nombre qui définit une couleur dans le jeu de couleurs standard (par exemple, le vert est le numéro de la couleur 2). La valeur de couleur correspond à la valeur réelle d'un pixel dans la mémoire vidéo, qui détermine finalement la couleur dans laquelle le pixel est affiché. La valeur de couleur est parfois juste appelé la couleur.

 Dans chaque mode graphique, mémoire vidéo est effacée lorsque la fg_setmode

routine est appelée. Cela signifie que tous les pixels sont initialement configurés pour la valeur de couleur 0, qui par défaut est noir. Pour cette raison, la valeur de la couleur 0 est souvent appelée la couleur de fond dans les modes graphiques vidéo.

 La routine de fg_setcolor de Fastgraph définit la couleur dans laquelle la suite

les opérations graphiques sont effectuées. Cette couleur est appelée la couleur actuelle. Selon le mode vidéo, la couleur actuelle peut faire référence à une valeur de couleur (en modes graphiques CGA et Hercules), un registre de palette (en Tandy, EGA et modes graphiques VGA), ou un registre vidéo DAC (en modes 256 couleurs) . La routine fg_setcolor prend un seul argument entier qui spécifie la couleur. Lorsque fg_setmode est appelée, elle définit la couleur actuelle à 0. La Fastgraph fg_getcolor routine retourne la couleur courante, tel que défini dans l'appel le plus récent à fg_setcolor. La routine de fg_getcolor n'a pas d'arguments et retourne la couleur actuelle comme valeur de fonction.


Modes couleur CGA

 Les modes de couleur CGA (modes 4 et 5) ont six ensembles de couleurs disponibles,

appelées palettes, numérotées de 0 à 5. Chaque palette se compose de quatre couleurs,

 Chapitre 5: L'utilisation de la couleur 71


numérotés de 0 à 3. Dans chaque palette, la couleur de fond (valeur de couleur 0) peut être choisi parmi le jeu de couleurs standard, mais les 3 autres couleurs sont fixes. Le tableau suivant indique les couleurs fixes attribuées à chaque palette.


 palette 0 palette 1 palette 2
 couleur cyan 1 lumière de lumière cyan lumineux vert
           couleur 2 lumière lumière rouge rouge magenta clair
           couleur 3 jaune blanc blanc
 palette 3 palette 4 palette 5
Couleur 1 cyan cyan vert
          couleur 2 rouge rouge magenta
          couleur 3 gris brun gris


Palette 1, avec un fond noir, est la palette par défaut lorsque vous sélectionnez le mode 4. Palette 2, avec un fond noir, est la palette par défaut lorsque vous sélectionnez le mode 5.

Les modes de couleur CGA ont une zone frontalière appelée overscan entre la

espace de pixel adressable et les bords physiques de l'écran. La zone overscan est toujours affiché dans la couleur de fond, quelle que soit la CGA palette est utilisée.

Dans les modes de couleur CGA, fg_setcolor définit la couleur actuelle en faisant référence

une des quatre valeurs de couleur. La routine fg_palette sélectionne l'un des six palettes et définit la couleur de fond de cette palette. Le premier argument de fg_palette est un nombre entier compris entre 0 et 5 qui indique le numéro de la palette. Le second argument est un entier compris entre 0 et 15 qui définit la couleur d'arrière-plan, en utilisant les numéros de couleurs dans le jeu de couleurs standard.

Exemple 5-1 illustre l'utilisation de fg_palette et fg_setcolor en mode 4.

Après avoir établi le mode vidéo, le programme sélectionne la palette 0 et rend la couleur bleue de fond (numéro de couleur 1). Il fait alors la couleur dans la palette 3 0 (jaune) la couleur actuelle et affiche le mot «Bonjour». Enfin, il restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-1.
#include <fastgraf.h>
                          void main (void);
void main ()
                           {
                             Mode int;
fg_initpm ();
                             mode = fg_getmode ();
                             fg_setmode (4);
fg_palette (0,1);
                             fg_setcolor (3);
                             fg_text ( "Bonjour", 5); 

Guide de l'utilisateur 72 Fastgraph


fg_waitkey ();
fg_setmode (mode);
                             fg_reset ();
                           }


Mode de CGA Deux-Color

Le CGA mode deux couleurs (mode 6) a une couleur d'arrière-plan fixe (valeur de couleur

0) et une couleur de premier plan (valeur de couleur définie par l'utilisateur 1). La couleur de fond est toujours noir. La couleur de premier plan est blanc par défaut, mais peut être modifiée à l'une des couleurs dans le jeu de couleurs standard. Il convient de mentionner que le changement de couleur de premier plan fonctionne sur de véritables adaptateurs CGA, mais il y a très peu d'adaptateurs EGA, VGA, SVGA et qui mettent en œuvre correctement changeant la couleur de premier plan dans leur mode d'émulation 6.

En mode 6, fg_setcolor définit la couleur actuelle en faisant référence à l'un des

les deux valeurs de couleur. La routine fg_palette définit la couleur de premier plan réel (qui est, la couleur des pixels dont la couleur est la valeur 1). Par souci de cohérence avec les autres modes graphiques, fg_palette a deux arguments, mais le premier est pas utilisé. Le second argument est un entier compris entre 0 et 15 qui définit la couleur de premier plan, en utilisant les numéros de couleurs dans le jeu de couleurs standard.

Exemple 5-2 illustre l'utilisation de fg_palette et fg_setcolor en mode 6.

Après avoir établi le mode vidéo, le programme rend le jaune de couleur de premier plan (numéro de couleur 14). Il fait alors la couleur 1 la couleur actuelle et affiche le mot «Bonjour». Enfin, il restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-2.
#include <fastgraf.h>
                          void main (void);
void main ()
                           {
                             Mode int;
fg_initpm ();
                             mode = fg_getmode ();
                             fg_setmode (6);
fg_palette (0,14);
                             fg_setcolor (1);
                             fg_text ( "Bonjour", 5);
                             fg_waitkey ();
fg_setmode (mode);
                             fg_reset ();
                          }   
                                           Chapitre 5: L'utilisation de la couleur 73


Tandy et modes PCjr

Le mode PCjr graphique supporté Tandy 1000 ou (mode 9) a 16 couleurs

valeurs, numérotées de 0 à 15. Chaque valeur de couleur fait référence à l'un des 16 registres palette définissables par l'utilisateur, souvent simplement appelé palettes, également numérotées de 0 à 15. Les valeurs attribuées aux registres de palette déterminer les couleurs dans lesquelles les pixels sont affichés. Par exemple, si vous affectez palette registre 2 la valeur de rouge, puis pixels dont la couleur est la valeur 2 sera rouge.

Chaque palette peut prendre l'une des couleurs 16 dans le jeu de couleurs standard.

Par défaut, les valeurs attribuées aux 16 palettes correspondent aux couleurs de même numéro dans le jeu de couleurs standard. En d'autres termes, la palette 0 est attribuée la valeur pour le noir, la palette 1 est affectée à la valeur pour le bleu, et ainsi de suite.

En mode 9, fg_setcolor définit la couleur actuelle en faisant référence à l'un des

les 16 registres de palette. La routine fg_palette définit la couleur réelle affectée à un registre spécifique de la palette. Le premier argument de fg_palette est un nombre entier compris entre 0 et 15 indiquant le numéro de la palette. Le second argument est un entier compris entre 0 et 15 qui définit la valeur de la palette (la couleur attribuée à la palette), en utilisant les numéros de couleurs IRGB dans le jeu de couleurs standard.

Vous pouvez également utiliser la fg_setrgb routine Fastgraph pour définir la couleur

affecté à un registre spécifique de la palette. Alors que fg_palette fait cela en utilisant un certain nombre de couleurs à partir du jeu de couleurs standard, fg_setrgb définit un registre de palette en utilisant des composants de couleur rouge, vert et bleu, plus une composante d'intensité. Le premier argument de fg_setrgb est un entier compris entre 0 et 15 qui spécifie le numéro de registre de palette. Les trois arguments restants sont chacun des nombres entiers compris entre -1 et 1, respectivement, qui spécifient les composantes de couleur rouge, vert et bleu pour ce registre de palette. Les significations des composantes de couleur sont les suivantes:

-1 = Bit de couleur et peu d'intensité sont fixés
    0 = bit de couleur est remise à zéro
    1 = bit de couleur est réglé

Comme il n'y a qu'un seul bit d'intensité dans les valeurs en mode 9 couleurs, en spécifiant -1 pour l'un des composants de couleur RVB produit une couleur intense. Par exemple, le cyan clair de couleur est le numéro de la couleur 11 dans le jeu de couleurs standard, et il est produit en combinant le vert et le bleu et le réglage du bit d'intensité. Cela signifie l'une de ces quatre états


fg_palette (1,11);
                           fg_setrgb (1,0, -1,1);
                           fg_setrgb (1,0,1, -1);
                           fg_setrgb (1,0, -1, -1);


pourrait être utilisé pour définir la palette registre 1 cyan clair en mode 9.

Exemple 5-3 illustre l'utilisation de fg_palette et fg_setcolor en mode 9.

Après avoir établi le mode vidéo, le programme définit la palette 0 à être bleu (1) et la palette 1 à être jaune (14). Notez que la définition de la palette 0 modifie le Guide de l'utilisateur 74 Fastgraph


Couleur de fond. Il fait alors la couleur 1 la couleur actuelle et affiche le mot «Bonjour». Après avoir attendu pendant une séquence de touches, le programme change la couleur de "Bonjour" en changeant la palette 1 à blanc (15). Enfin, il restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-3.
#include <fastgraf.h>
                          void main (void);
void main ()
                           {
                             Mode int;
fg_initpm ();
                             mode = fg_getmode ();
                             fg_setmode (9);
fg_palette (0,1);
                             fg_palette (1,14);
fg_setcolor (1);
                             fg_text ( "Bonjour", 5);
                             fg_waitkey ();
fg_palette (1,15);
                             fg_waitkey ();
fg_setmode (mode);
                             fg_reset ();
                           }


mode de Hercules

Le mode graphique Hercules (mode 11) a une couleur d'arrière-plan fixe (couleur

valeur 0) et une couleur de premier plan fixe (valeur de couleur 1). La couleur de fond est toujours noir, et la couleur de premier plan dépend de l'affichage monochrome utilisé (généralement il est vert, ambre ou blanc).

La routine fg_setcolor définit la valeur de couleur actuelle en faisant référence

une des deux valeurs de couleur. La routine de fg_palette n'a aucun effet en mode 11.

Exemple 5-4 illustre l'utilisation de fg_setcolor en mode 11. Après

établir le mode vidéo, le programme rend la couleur 1, la couleur actuelle et affiche le mot «Bonjour». Il restaure ensuite le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-4.
#include <fastgraf.h>
                          void main (void);
void main ()
                          {   
                                           Chapitre 5: L'utilisation de la couleur 75


Mode int;
fg_initpm ();
                             mode = fg_getmode ();
                             fg_setmode (11);
fg_setcolor (1);
                             fg_text ( "Bonjour", 5);
                             fg_waitkey ();
fg_setmode (mode);
                             fg_reset ();
                           }


Hercules mode basse résolution

Le Hercules (mode 12) graphiques basse résolution a quatre couleurs

valeurs, numérotées de 0 à 3. La couleur de fond est toujours noir, les couleurs 1 et 2 sont une intensité normale, et la couleur 3 est pleine intensité. Couleurs 1 et 2 à la fois produire des couleurs d'intensité normale, mais ils le font avec des motifs de pixels différents - couleur 1 tourne sur les pixels physiques impaires, tandis que la couleur 2 tourne sur les pixels physiques paires. L'aspect des couleurs 1 à 3 dépend de l'affichage monochrome utilisé (en général, il est vert, ambre ou blanc).

La routine fg_setcolor définit la valeur de couleur actuelle en faisant référence

une des quatre valeurs de couleur. La routine de fg_palette n'a aucun effet en mode 12.

Exemple 5.5 démontre l'utilisation de fg_setcolor en mode 12. Après

établir le mode vidéo, le programme rend la couleur 3 la couleur actuelle et affiche le mot «Bonjour». Il restaure ensuite le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-5.
#include <fastgraf.h>
                          void main (void);
void main ()
                           {
                             Mode int;
fg_initpm ();
                             mode = fg_getmode ();
                             fg_setmode (12);
fg_setcolor (3);
                             fg_text ( "Bonjour", 5);
                             fg_waitkey ();
fg_setmode (mode);
                             fg_reset ();
                          }   

Guide de l'utilisateur 76 Fastgraph


EGA Modes 200-Line

Les modes 200 en ligne EGA graphiques (modes 13 et 14) ont 16 valeurs de couleur,

numérotés de 0 à 15. Chaque valeur de couleur fait référence à l'un des 16 registres palette définissables par l'utilisateur, souvent appelé simplement palettes, également numérotées de 0 à 15. Les valeurs attribuées aux registres de palette déterminent les couleurs dans lesquelles les pixels sont affichés. Par exemple, si vous affectez palette registre 2 la valeur de rouge, puis pixels dont la couleur est la valeur 2 sera rouge.

Chaque palette peut prendre l'une des couleurs 16 dans le jeu de couleurs standard.

Par défaut, les valeurs attribuées aux 16 palettes correspondent aux couleurs de même numéro dans le jeu de couleurs standard. En d'autres termes, la palette 0 est attribuée la valeur pour le noir, la palette 1 est affectée à la valeur pour le bleu, et ainsi de suite.

Dans les modes 13 et 14, fg_setcolor définit la couleur actuelle en faisant référence

l'un des 16 registres de palette disponibles. La routine fg_palette définit la couleur réelle affectée à un registre spécifique de la palette. Le premier argument de fg_palette est un nombre entier compris entre 0 et 15 indiquant le numéro de la palette. Le second argument est un entier qui définit la valeur de la palette (la couleur attribuée à la palette). Bien que les couleurs réelles sont prises à partir du jeu de couleurs standard, la structure binaire d'une valeur de palette est différent du format IRGB utilisé dans le jeu de couleurs standard. Dans les modes 13 et 14, la structure binaire d'une valeur de palette est IxRGB; bit 3 est ignoré. Les valeurs de la palette en mode 13 et le mode 14 qui correspondent à l'ensemble de couleurs standard sont donc:

couleur de valeur de couleur de valeur
0 noir 16 gris foncé
                       1 bleu 17 bleu clair
                       2 vert 18 vert clair
                       3 cyan cyan 19 lumière
                       4 rouge 20 rouge clair
                       5 magenta 21 magenta clair
                       6 brun 22 jaune
                       7 gris 23 blanc
Vous pouvez également utiliser la fg_setrgb routine Fastgraph pour définir la couleur

affecté à un registre spécifique de la palette. Alors que fg_palette fait cela en utilisant un certain nombre de couleurs à partir du jeu de couleurs standard, fg_setrgb définit un registre de la palette en utilisant rouge, vert et bleu des composantes de couleur, plus une composante d'intensité. Le premier argument de fg_setrgb est un entier compris entre 0 et 15 qui spécifie le numéro de registre de palette. Les trois arguments restants sont chacun des nombres entiers compris entre -1 et 1, respectivement, qui spécifient les composantes de couleur rouge, vert et bleu pour ce registre de palette. Les significations des composantes de couleur sont les suivantes:

-1 = Bit de couleur et peu d'intensité sont fixés
    0 = bit de couleur est remise à zéro
    1 = bit de couleur est réglé

Comme il n'y a qu'un seul bit d'intensité en mode 13 et 14 des valeurs de couleur spécifiant -1 pour l'une des composantes de couleur RVB produit une couleur intense. Par exemple, le cyan clair est représenté par la valeur de couleur 19, et il est

Chapitre 5: L'utilisation de la couleur 77


produit en combinant le vert et le bleu et le réglage du bit d'intensité. Cela signifie l'une de ces quatre états


fg_palette (1,19);
                           fg_setrgb (1,0, -1,1);
                           fg_setrgb (1,0,1, -1);
                           fg_setrgb (1,0, -1, -1);


pourrait être utilisé pour définir la palette registre 1 cyan clair dans les modes 13 et 14.

La fg_setcolor routine Fastgraph définit la valeur de couleur (qui est, le

numéro de palette) dans lequel les opérations graphiques qui suivent sont réalisées. La routine fg_setcolor prend un seul argument entier qui spécifie cette couleur. Lorsque fg_setmode est appelée, elle définit la valeur de couleur à 0. La Fastgraph fg_getcolor routine renvoie la valeur de couleur actuelle, tel que défini dans l'appel le plus récent à fg_setcolor. La routine de fg_getcolor n'a pas d'arguments et retourne la couleur actuelle comme valeur de la fonction.

Exemple 6.5 démontre l'utilisation de fg_palette et en mode fg_setcolor

13. Après avoir établi le mode vidéo, le programme définit la palette 0 à être bleu (1) et la palette 1 à être jaune (22). Notez que la définition de la palette 0 change la couleur de fond. Il fait alors la couleur 1 la couleur actuelle et affiche le mot «Bonjour». Après avoir attendu pendant une séquence de touches, le programme change la couleur de "Bonjour" en changeant la palette 1 à blanc (23). Enfin, il restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-6.
#include <fastgraf.h>
                          void main (void);
void main ()
                           {
                             Mode int;
fg_initpm ();
                             mode = fg_getmode ();
                             fg_setmode (13);
fg_palette (0,1);
                             fg_palette (1,22);
fg_setcolor (1);
                             fg_text ( "Bonjour", 5);
                             fg_waitkey ();
fg_palette (1,23);
                             fg_waitkey ();
fg_setmode (mode);
                             fg_reset ();
                          }   

Guide de l'utilisateur 78 Fastgraph


Monochrome Mode EGA

Le mode (mode 15) monochrome EGA graphique assigne les attributs d'affichage à

ses quatre valeurs de couleurs, numérotées de 0 à 3. Chaque valeur de couleur fait référence à l'un des quatre registres de palette définies par l'utilisateur, souvent appelées simplement palettes, numérotées 0, 1, 4, et 5. Cette étrange résultats de numérotation à partir de la désactivation de deux des quatre vidéo plans de bits de mémoire en mode 15. les valeurs attribuées aux registres de palette déterminent l'attribut d'affichage de pixel. Par exemple, si vous affectez palette registre 1 la valeur de gras, puis pixels dont la valeur est 1 sera en gras.

En mode 15, fg_setcolor définit la couleur actuelle (en fait, un affichage

attribuer) en faisant référence à l'une des quatre entrées de la palette. La routine fg_palette définit l'attribut d'affichage réel attribué à un registre spécifique à une palette. Le premier argument de fg_palette est un entier qui spécifie le numéro de palette. Le second argument est un entier qui définit la valeur de la palette (l'attribut d'affichage attribué à la palette). Pour chaque registre de la palette, le tableau suivant indique la valeur de la palette par défaut et son attribut d'affichage associé.

affichage de la palette de la palette
                         attribut de valeur numérique
0 0 invisible
                            1 8 normale
                            4 24 gras
                            5 24 gras
Exemple 5-7 illustre l'utilisation de fg_palette et en mode fg_setcolor

15. Après avoir établi le mode vidéo, le programme fait la couleur 4 (en fait, la palette 4, qui est en gras par défaut) la couleur actuelle et affiche le mot «Bonjour». Après avoir attendu pendant une séquence de touches, le programme change l'attribut d'affichage de "Bonjour" en changeant la palette 4 à intensité normale (valeur de la palette 8). Enfin, il restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-7.
#include <fastgraf.h>
                          void main (void);
void main ()
                           {
                             Mode int;
fg_initpm ();
                             mode = fg_getmode ();
                             fg_setmode (15);
fg_setcolor (4);
                             fg_text ( "Bonjour", 5);
                             fg_waitkey ();
fg_palette (4,8);
                             fg_waitkey (); 
                                           Chapitre 5: L'utilisation de la couleur 79


fg_setmode (mode);
                             fg_reset ();
                           }


Enhanced Mode EGA

L'EGA mode amélioré (mode 16) graphique a 16 valeurs de couleurs, numérotées de 0

à 15. Chaque valeur de couleur fait référence à l'un des 16 registres définissables par l'utilisateur palette, souvent simplement appelés palettes, également numérotées de 0 à 15. Les valeurs attribuées aux registres de palette déterminer les couleurs dans lesquelles les pixels sont affichés. Par exemple, si vous affectez palette registre 2 la valeur de rouge, puis pixels dont la couleur est la valeur 2 sera rouge.

Chaque palette peut prendre l'une des 64 couleurs disponibles.  Par défaut, le

valeurs attribuées aux 16 palettes correspondent aux couleurs de même numéro dans le jeu de couleurs standard. En d'autres termes, la palette 0 est attribuée la valeur pour le noir, la palette 1 est affectée à la valeur pour le bleu, et ainsi de suite. Il y a quelques adaptateurs EGA-compatibles qui ne correctement assignent pas les couleurs par défaut pour les 16 registres de la palette, il est donc une bonne pratique de le faire explicitement en mode 16.

En mode 16, fg_setcolor définit la valeur de couleur actuelle en faisant référence

l'un des 16 registres de palette. La routine fg_palette définit la couleur réelle affectée à un registre spécifique de la palette. Le premier argument de fg_palette est un nombre entier compris entre 0 et 15 indiquant le numéro de la palette. Le second argument est un entier qui définit la valeur de la palette (la couleur attribuée à la palette). La structure binaire d'une valeur de palette est différent du format IRGB utilisé dans le jeu de couleurs standard. En mode 16, la structure binaire d'une valeur de palette est une quantité de 6 bits de la forme RGBRGB, où les lettres minuscules représentent les faible intensité (1/3 intensité) des composantes de couleur, et les lettres majuscules représentent l'intensité normale ( 2/3 intensité) des composants de couleur. Le mode 16 valeurs de la palette qui correspondent à l'ensemble de couleurs standard sont:

couleur de valeur de couleur de valeur
0 noir 56 gris foncé
             1 bleu 57 bleu clair
             2 vert 58 vert clair
             3 cyan cyan clair 59
             4 rouge 60 rouge clair
             5 magenta 61 magenta clair
            20 brun 62 jaune
             7 gris 63 blanc
Les composantes d'intensité normale en mode 16 produisent la même normale

couleurs d'intensité que dans les autres modes graphiques 16 couleurs. De même, la combinaison des intensités faibles et normales en mode 16 produit les couleurs de haute intensité des autres modes. La seule exception à cette règle est le brun par défaut, formé à partir du motif de bits 010100 (20 décimal). Cette valeur produit un plus vrai brun que la valeur 6 décimales, ce qui est vraiment un vert olive. Guide de l'utilisateur 80 Fastgraph


Les valeurs de la palette utilisées en mode 16 sont des quantités de 6 bits, ce qui signifie

il y a 64 couleurs différentes disponibles en mode 16. Ce groupe de 64 couleurs se compose des couleurs 16 dans le jeu de couleur standard plus 48 couleurs supplémentaires qui ne sont pas disponibles dans tous les autres modes EGA. Cependant, parce que les registres de palette EGA détiennent des quantités de 4 bits, seuls 16 de ces couleurs peuvent être affichées en même temps. En d'autres termes, le mode EGA amélioré offre la possibilité d'afficher 16 couleurs simultanées à partir d'un groupe de 64.

Vous pouvez également utiliser la fg_setrgb routine Fastgraph pour définir la couleur

affecté à un registre spécifique de la palette. Alors que fg_palette fait cela en utilisant une valeur comprise entre 0 et 63, fg_setrgb définit un registre de la palette en utilisant rouge, vert et bleu des composantes de couleur. Le premier argument de fg_setrgb est un entier compris entre 0 et 15 qui spécifie le numéro de registre de palette. Les trois arguments restants sont chacun des nombres entiers compris entre 0 et 3 qui indiquent respectivement les intensités tiers des composantes de couleur rouge, vert et bleu pour ce registre de palette. Par exemple, la couleur cyan est représenté par la valeur dans le tableau 3 ci-dessus, et il est produit en combinant une intensité normale (2/3 intensité) vert et bleu. Cela signifie soit des états


fg_palette (1,3);
                            fg_setrgb (1,0,2,2);


pourraient être utilisés pour définir la palette 1 en tant que registre cyan.

Exemple 5-8 illustre l'utilisation de fg_palette et en mode fg_setcolor

16. Il utilise la routine fg_rect Fastgraph (discuté dans le chapitre suivant) pour dessiner des rectangles d'une taille spécifiée. Après avoir établi le mode vidéo, le programme utilise une boucle pour dessiner 16 rectangles de taille égale, un dans chacune des valeurs de couleur 16. Dans la même boucle, le programme fg_palette utilise pour changer chaque palette au noir. La boucle while qui suit effectue quatre itérations. Les premiers changements d'itération 0-0 palette, la palette 1: 1, et ainsi de suite. Par conséquent, les 16 rectangles apparaissent dans les valeurs de la palette 0 à 15. Les rectangles restent dans ces couleurs jusqu'à ce que est la clé est enfoncée pour commencer la prochaine itération. Les deuxièmes variations d'itération 0-16 palette, la palette 1 à 17, et ainsi de suite. Cela rend les 16 rectangles apparaissent dans les valeurs de la palette 16 à 31. Iterations trois et quatre sont similaires, de sorte que l'effet global du programme est d'afficher toutes les 64 couleurs, 16 à la fois. Enfin, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-8.
#include <fastgraf.h>
              void main (void);
COULEURS #define 16
              #define WIDTH 40
void main ()
               {
                  la base int;
                 Couleur int;
                 int minx, maxx;
                 Mode int; 
                                           Chapitre 5: L'utilisation de la couleur 81


fg_initpm ();
                 mode = fg_getmode ();
                 fg_setmode (16);
base = 0;
                 minx = 0;
                 maxx = WIDTH - 1;
pour (couleur = 0; couleur <COLORS; couleur ++) {
                    fg_palette (couleur, 0);
                    fg_setcolor (couleur);
                    fg_rect (minx, maxx, 0349);
                    minx = maxx + 1;
                    maxx = maxx + WIDTH;
                     }
tandis que (base <COLORS * 4) {
                    pour (couleur = 0; color <COLORS; couleur ++)
                       fg_palette (couleur, base + couleur);
                    base + = COULEURS;
                    fg_waitkey ();
                     }
fg_setmode (mode);
                 fg_reset ();
               }


VGA et MCGA Two-Mode couleur

Le VGA et le mode MCGA deux couleurs (mode 17) a une couleur d'arrière-plan (couleur

valeur 0) et une couleur de premier plan (valeur de couleur 1). Chaque valeur de couleur fait référence à l'un des deux registres de palette définissables par l'utilisateur, souvent simplement appelés palettes, également numérotées 0 et 1. Chaque registre de la palette à son tour fait référence à l'un des 16 18 bits registres vidéo CAD définissables par l'utilisateur, numérotés de 0 à 15. Les valeurs affecté aux registres de palette et vidéo registres CAD déterminer les couleurs dans lesquelles les pixels sont affichés. Par exemple, si la palette registre 1 contient la valeur 3, et la vidéo registre DAC 3 contient la valeur de couleur pour le rouge, puis pixels dont la valeur est la couleur 1 (qui est, les pixels de premier plan) sera rouge.

Par défaut, la palette registre 0 références vidéo CAD inscrivez 0, et

palette registre 1 références de registre vidéo DAC 1. En outre, la vidéo DAC registre 0 contient initialement la valeur de couleur pour le noir, tandis que les autres registres du CAD 15 vidéo (1 à 15) contiennent la valeur de couleur pour le blanc. Cela signifie des pixels de fond (valeur de couleur 0) sont en noir par défaut, tandis que les pixels de premier plan (valeur de couleur 1) sont blancs.

Les valeurs vidéo DAC 18 bits se composent de trois 6-bit rouge, vert et bleu

des composantes de couleur. Par conséquent, chaque composante de couleur est un nombre entier compris entre 0 et 63; valeurs croissantes produisent des couleurs plus intenses. Les composantes de couleur par défaut pour les DAC enregistrent 0 sont rouges = 0, bleu = 0, et vert = 0, ce qui produit du noir. Les valeurs par défaut pour les autres registres du CAD sont rouge = 63, bleu = 63, et vert = 63, qui produit du blanc. Étant donné que les registres vidéo DAC 18 bits sont longues, chaque DAC peut spécifier l'un des 262.144 (2 ** 18) couleurs. Cependant, parce que les registres de palette détiennent des quantités de 1 bit, seulement deux de ces couleurs peuvent être affichées au Guide de l'utilisateur 82 Fastgraph


le même temps. En d'autres termes, le mode 17 fournit la possibilité d'afficher simultanément deux couleurs à partir d'un groupe de 262.144.

En mode 17, fg_setcolor définit la couleur actuelle en faisant référence à l'un des

les deux registres de palette. La routine fg_palette définit la valeur d'un registre de la palette en faisant référence à l'un des 16 registres vidéo du CAD. Autrement dit, fg_palette spécifie la vidéo DAC registre qu'une palette registre des références. Le premier argument de fg_palette est soit 0 ou 1 et indique le numéro de palette. Le second argument est un entier compris entre 0 et 15 qui spécifie la vidéo registre DAC pour cette palette.

La fg_setrgb routine Fastgraph définit la valeur d'une vidéo registre DAC

en mode 17. Le premier argument de fg_setrgb est un entier compris entre 0 et 15 qui spécifie le numéro de registre du CAD. Les trois arguments restants sont chacun des nombres entiers compris entre 0 et 63 qui indiquent respectivement les composantes de couleur rouge, vert et bleu pour ce registre DAC.

Exemple 5-9 illustre l'utilisation de fg_palette, fg_setrgb, et

fg_setcolor en mode 17. Après avoir établi le mode vidéo, le programme définit DAC registre 0 à être bleu (rouge = 0, vert = 0, bleu = 42) et le registre DAC 1 à être jaune (rouge = 63, vert = 63, bleu = 21). Notez que la définition du CAD registre 0 change la couleur de fond, car la palette 0 références DAC registre 0. Le programme fait alors la couleur 1 la couleur actuelle (palette 1 références encore DAC registre 1) et affiche le mot «Bonjour» en jaune. Après avoir attendu pendant une séquence de touches, le programme change la couleur de "Bonjour" en faisant référence palette 1 DAC registre 15 (qui contient encore sa valeur par défaut, blanc). Enfin, il restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-9.
#include <fastgraf.h>
                         void main (void);
void main ()
                          {
                            Mode int;
fg_initpm ();
                            mode = fg_getmode ();
                            fg_setmode (17);
fg_setrgb (0,0,0,42);
                            fg_setrgb (1,63,63,21);
fg_setcolor (1);
                            fg_text ( "Bonjour", 5);
                            fg_waitkey ();
fg_palette (1,15);
                            fg_waitkey ();
fg_setmode (mode);
                            fg_reset ();
                         }   
                                           Chapitre 5: L'utilisation de la couleur 83


VGA / SVGA Modes 16-Color

Les modes 16 couleurs VGA et SVGA (modes 18, 28 et 29) ont 16 couleurs

valeurs, numérotées de 0 à 15. Chaque valeur de couleur fait référence à l'un des 16 palettes registres définissables par l'utilisateur, souvent simplement appelés palettes, également numérotées de 0 à 15. Chaque registre de palette à son tour fait référence à l'un des 16 18 bits registres vidéo CAD définissables par l'utilisateur, également numérotés de 0 à 15. les valeurs attribuées aux registres de palette et vidéo registres CAD déterminent les couleurs dans lesquelles les pixels sont affichés. Par exemple, si la palette registre 1 contient la valeur 3, et la vidéo registre DAC 3 contient la valeur de couleur pour le rouge, puis pixels dont la valeur est la couleur 1 sera rouge.

Par défaut, chacun des 16 registres de palette des références de la vidéo DAC

inscrivez-vous du même nombre. En outre, le 16 DAC vidéo enregistre respectivement contiennent les valeurs de couleur pour les couleurs 16 dans le jeu de couleurs standard.

Les valeurs vidéo DAC 18 bits se composent de trois 6-bit rouge, vert et bleu

des composantes de couleur. Par conséquent, chaque composante de couleur est un nombre entier compris entre 0 et 63; valeurs croissantes produisent des couleurs plus intenses. La valeur par défaut RGB composantes de couleur pour les 16 registres vidéo du CAD sont:

couleur couleurs RVB DAC DAC RGB
0 0 0 0 noir 8 21 21 21 gris foncé
        blue 1 0 0 42 bleu 9 21 21 63 lumière
        2 0 42 0 vert 10 21 63 21 vert clair
        3 0 42 42 cyan cyan clair 11 21 63 63
        4 42 0 0 rouge 12 63 21 21 lumière rouge
        5 42 0 42 magenta 13 63 21 63 magenta clair
        6 42 21 0 brun 14 63 63 21 jaune
        7 42 42 42 gris 15 63 63 63 blanc

Étant donné que les registres vidéo DAC 18 bits sont longues, chaque DAC peut spécifier l'un des 262.144 (2 ** 18) couleurs. Cependant, parce que les registres de palette détiennent des quantités de 4 bits, seuls 16 de ces couleurs peuvent être affichées en même temps. En d'autres termes, le mode 18 fournit la possibilité d'afficher 16 couleurs simultanées à partir d'un groupe de 262.144.

Dans la couleur 16 modes VGA et SVGA, fg_setcolor, fg_palette, et

fg_setrgb se comportent exactement comme dans le mode 17 à une exception près: il y a 16 registres de palette au lieu de seulement deux. Exemple 5-9 illustre l'utilisation de ces routines en mode 17, mais il serait également fonctionner en mode 18, 28, ou 29 si l'appel à fg_setmode ont été modifiés en conséquence.


Modes de 256 couleurs

Les modes 256 couleurs (modes 19 à 27) ont 256 valeurs de couleur, numérotée

0 à 255. Chaque valeur de couleur références directement l'un des 256 utilisateur-définissable 18- bits registres vidéo du CAD, également numérotés de 0 à 255. Les valeurs attribuées aux registres vidéo du CAD déterminer les couleurs dans lesquelles les pixels sont affichés. Par exemple, si la vidéo registre DAC 3 contient la valeur de couleur pour le rouge, puis pixels dont la valeur est la couleur 3 sera rouge. Guide de l'utilisateur 84 Fastgraph


Par défaut, les 16 premiers registres vidéo DAC (0 à 15) contiennent la couleur

valeurs pour le jeu de couleurs standard. Les 16 prochains registres du CAD (16 à 31) contiennent les valeurs de couleur pour une échelle de gris d'intensité augmente progressivement. Les prochaines 216 registres du CAD (32 à 247) contiennent trois groupes de 72 couleurs chacune, avec le premier groupe (32 à 103) à haute intensité, le deuxième groupe (104 à 175) à une intensité modérée, et le troisième groupe (176 à 247) à faible intensité. Chaque groupe se compose de trois gammes de réduction de la saturation (blancheur croissante), chaque plage variant de teinte du bleu au rouge au vert. Enfin, les 8 derniers registres du CAD (248 à 255) de alternent entre noir et blanc. Ces données sont résumées dans le tableau suivant.

DACs valeurs par défaut de couleur
0 à 15 jeu de couleur standard
   16-31 échelle de gris d'intensité augmentant progressivement
   32-55 saturation élevée, les couleurs de haute intensité
   56-79 saturation modérée, les couleurs de haute intensité
   80-103 faible saturation, couleurs de haute intensité
   104-127 saturation élevée, les couleurs d'intensité modérée
   128-151 saturation modérée, les couleurs d'intensité modérée
   152-175 faible saturation, couleurs d'intensité modérée
   176-199 saturation élevée, les couleurs de faible intensité
   200-223 saturation modérée, les couleurs de faible intensité
   224-247 faible saturation, couleurs de faible intensité
   248-255 alternent entre noir et blanc
Les valeurs vidéo DAC 18 bits se composent de trois 6-bit rouge, vert et bleu

des composantes de couleur. Par conséquent, chaque composante de couleur est un nombre entier compris entre 0 et 63; valeurs croissantes produisent des couleurs plus intenses. Étant donné que les registres vidéo DAC 18 bits sont longues, chaque DAC peut spécifier l'un des 262.144 (2 ** 18) couleurs. Cependant, parce que les valeurs de couleur sont des quantités de 8 bits, seulement 256 de ces couleurs peuvent être affichées en même temps. En d'autres termes, les modes 19 à 27 fournissent la capacité d'afficher 256 couleurs simultanées à partir d'un groupe de 262.144.

Dans les modes graphiques 256 couleurs, fg_setcolor définit la couleur actuelle par

référençant l'un des 256 registres vidéo du CAD. La routine fg_setrgb définit la couleur réelle d'un registre vidéo DAC. Le premier argument de fg_setrgb est un entier compris entre 0 et 255 qui spécifie le DAC numéro de registre. Les trois arguments restants sont chacun des nombres entiers compris entre 0 et 63 qui indiquent respectivement les composantes de couleur rouge, vert et bleu pour ce registre DAC. Une autre routine Fastgraph, fg_getrgb, renvoie les composantes de couleur pour un registre DAC spécifié. Ses arguments sont les mêmes que pour fg_setrgb, à l'exception des trois derniers arguments (les valeurs de retour) sont passés par référence plutôt que par valeur.

Vous pouvez également utiliser la fg_palette routine Fastgraph pour définir la valeur de

une vidéo registre DAC dans les modes 19 à 27. Le premier argument de fg_palette est un entier compris entre 0 et 255 qui indique le numéro de registre du CAD. Le second argument est un entier compris entre 0 et 63 qui spécifie la valeur de couleur pour ce registre vidéo DAC, en utilisant les mêmes 64 valeurs comme dans le mode amélioré de EGA (mode 16).

Exemple 5-10 illustre l'utilisation de fg_setcolor en mode 19. Le programme

utilise la routine fg_rect Fastgraph pour tracer des lignes verticales. Après avoir établi le mode vidéo, le programme utilise une boucle pour dessiner 256 lignes verticales, une en

Chapitre 5: L'utilisation de la couleur 85


chacune des 256 couleurs (en utilisant les valeurs par défaut du CAD). Enfin, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-10.
#include <fastgraf.h>
               void main (void);
COULEURS #define 256
void main ()
                {
                   la base int;
                  Couleur int;
                  Mode int;
                  int x;
fg_initpm ();
                  mode = fg_getmode ();
                  fg_setmode (19);
x = 0;
pour (couleur = 0; couleur <COLORS; couleur ++) {
                     fg_setcolor (couleur);
                     fg_rect (x, x, 0199);
                      x ++;
                      }
                  fg_waitkey ();
fg_setmode (mode);
                  fg_reset ();
                }


Exemple 5-11 montre un effet intéressant disponible dans les modes vidéo qui

soutenir les registres du CAD. Le programme utilise la routine fg_waitfor Fastgraph (voir le chapitre 16) pour retarder l'exécution du programme. Après avoir établi le mode vidéo, le programme affiche le mot "Bonjour" dans la couleur 103, qui par défaut est un bleu pastel. Il fg_getrgb utilise ensuite pour récupérer les composants de couleur pour cette couleur. La boucle while diminue progressivement les composantes de couleur jusqu'à ce que les trois composantes sont nulles, ce qui rend le mot "Bonjour" en douceur fondu au noir. Enfin, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 5-11.
#include <fastgraf.h>
                   void main (void);
void main ()
                    {
                      int old_mode;
                      int rouge, vert, bleu; 

Guide de l'utilisateur 86 Fastgraph


fg_initpm ();
                      fg_getmode old_mode = ();
                      fg_setmode (19);
fg_setcolor (103);
                      fg_text ( "Bonjour", 5);
                      fg_waitfor (18);
fg_getrgb (103, & rouge, et vert, et bleu);
tandis que (rouge + vert + bleu> 0) {
                         si (rouge> 0) red--;
                         si (vert> 0) green--;
                         si (bleu> 0) blue--;
                         fg_setrgb (103, rouge, vert, bleu);
                         fg_waitfor (1);
                          }
fg_setmode (old_mode);
                      fg_reset ();
                    }


Les fg_setrgb et fg_getrgb routines travaillent avec des registres du CAD.

Si vous souhaitez définir ou récupérer un bloc de registres, consécutifs CAD fg_setdacs et fg_getdacs sont plus efficaces. La routine de fg_setdacs définit les valeurs d'un bloc de registres DAC consécutifs. Son premier argument est l'indice du premier DAC registre pour définir (entre 0 et 255), et son second argument est le nombre de DAC enregistre pour définir (entre 1 et 256). Le troisième argument est un tableau d'octets contenant les composants de couleur RVB pour les registres du CAD étant défini. trois premiers octets du tableau contiennent les composantes rouge, vert et bleu pour la première DAC, les trois suivants pour le deuxième DAC, et ainsi de suite. La taille de ce tableau doit être au moins trois fois la valeur du second argument. Les arguments de fg_getdacs sont les mêmes que ceux pour fg_setdacs, mais le tableau RGB reçoit plutôt les valeurs actuelles des registres du CAD spécifiés. Les deux routines traitent les numéros de registre du CAD d'une manière circulaire (par exemple, la définition de quatre DACs commençant par le numéro 254 va définir DACs 254, 255, 0 et 1).

 Exemple 5-12 est similaire à l'exemple 5-11, mais il efface beaucoup de couleurs

en même temps. Le programme affiche sept astérisques, une dans chacune des couleurs 9 à 15. Il utilise fg_getdacs pour obtenir les paramètres actuels des registres du CAD correspondant; ces valeurs sont stockées dans les RGBvalues ​​de tableau. La boucle while disparaît progressivement les composantes RGB à zéro, à l'aide fg_setdacs pour mettre à jour leurs valeurs, similaire à la méthode de l'exemple 5-11. Cela illustre une façon attrayante de transformer une image en un écran vide.

 Exemple 5-12.
 #include <fastgraf.h>
                      void main (void);
 void main ()
                      {
                         int diminue;
                         int i; 
                                            Chapitre 5: L'utilisation de la couleur 87


 int old_mode;
                         RGBvalues ​​char [21];
 fg_initpm ();
                         fg_getmode old_mode = ();
                         fg_setmode (19);
 for (i = 9; i <= 15; i ++) {
                            fg_setcolor (i);
                            fg_text ( "*", 1);
                            }
 fg_getdacs (9,7, RGBvalues);
                         fg_waitfor (18);
 faire {
                            = Diminution 0;
                            for (i = 0; i <21; i ++)
                               if (RGBvalues ​​[i] 0>) {
                                  RGBvalues ​​[i] -;
                                  = Diminution 1;
                                  }
                            fg_setdacs (9,7, RGBvalues);
                            fg_waitfor (1);
                            }
                         tandis que (diminution);
 fg_setmode (old_mode);
                         fg_reset ();
                      }


Notez que les exemples 5-11 et 5-12 serait également travailler en VGA 16 couleurs et les modes vidéo SVGA aussi longtemps que vous venez d'utiliser les 16 premiers registres vidéo du CAD.


Utilisation de la vidéo Registres du CAD en modes EGA

 Les fg_getdacs et fg_setdacs routines travaillent aussi dans les modes 13, 14, et 16

lorsqu'il est utilisé sur un écran VGA ou SVGA système. Cela vous permet de choisir 16 couleurs à partir d'une palette de 262.144 couleurs, comme dans le mode 18. Si vous essayez d'utiliser ces routines sur un système EGA, les résultats sont imprévisibles. Les applications qui utilisent ces routines doivent donc d'abord assurer qu'ils sont en cours d'exécution sur un VGA ou SVGA système en vérifiant si fg_testmode (18,0) renvoie une valeur non nulle.

 Avant d'essayer d'utiliser fg_getdacs et fg_setdacs dans les modes 13, 14, et 16,

vous devez d'abord être conscient de la relation entre les palettes VGA et registres du CAD. Sur l'EGA, les valeurs de la palette déterminent directement la couleur affichée. Sur le VGA et SVGA, cependant, il existe un niveau supplémentaire d'indirection. VGA et SVGA registres de palette peuvent être considérés comme des pointeurs vers vidéo DAC registres dont les composantes RVB détermine la couleur affichée.

 Chaque registre de la palette dans le 640x480 mode graphique 16 couleurs VGA (mode 18)

souligne d'abord au registre du même numéro de DAC. Nous pouvons donc prétendre n'existe pas indirection car la modification de registre DAC n affecte les pixels dont la valeur de couleur est n (à moins, bien sûr, nous avons changé la valeur du Guide 88 Fastgraph utilisateur


palette registre n). Dans les modes 13, 14, et 16, nous ne pouvons pas ignorer le indirection parce que les registres de palette contiennent des valeurs différentes. En mode 13, par exemple, la palette registre 8 contient la valeur 16 par défaut, et non pas la valeur 8 comme en mode 18.

 La meilleure façon de contourner cette incompatibilité est de définir la palette et le CAD

enregistre explicitement afin qu'ils correspondent aux valeurs de Mode 18. par défaut Il y a deux cas à considérer - l'un pour les modes 13 et 14, et l'autre pour le mode 16.

 Dans les modes 13 et 14, les palettes de 0 à 7 contiennent les valeurs 0 à 7, mais

palettes 8 à 15 contiennent les valeurs 16 à 23. Par conséquent, si vous souhaitez utiliser fg_getdacs et fg_setdacs dans ces modes, vous devez inclure le code suivant après avoir appelé fg_setmode.


 RGBvalues ​​char [3];
                       int i;
 for (i = 8; i <16; i ++) {
                          fg_getdacs (i + 8,1, RGBvalues);
                          fg_setdacs (i, 1, RGBvalues);
                          fg_palette (i, i);
                       }


Ce code va définir les valeurs de DACs 8 à 15 aux valeurs de DACs 16 à 23. Il définit également les palettes 8 à 15 pour pointer vers DACs 8 à 15. Vous pouvez alors ignorer la indirection palette-DAC parce réglage DAC registre n affecte pixels de couleur n.

 En mode 16, la palette 6 est d'abord affecté la valeur 20, et les palettes 8

à 15 sont affectées les valeurs 56 à 63. Tous les autres palettes pointent vers le DAC du même nombre. Par conséquent, si vous souhaitez utiliser fg_getdacs et fg_setdacs en mode 16, vous devez inclure le code suivant après avoir appelé fg_setmode.


 RGBvalues ​​char [3];
                       int i;
 fg_getdacs (20,1, RGBvalues);
                       fg_setdacs (6,1, RGBvalues);
                       fg_palette (6,6);
 for (i = 8; i <16; i ++) {
                          fg_getdacs (i + 48,1, RGBvalues);
                          fg_setdacs (i, 1, RGBvalues);
                          fg_palette (i, i);
                       }


Ce code va définir les valeurs de DAC 6 aux valeurs de DAC 20, et également DACs 8 à 15 aux valeurs de DACs 56 à 63. Il définit également les palettes 6 et 8-15 pour pointer vers les DACs identiquement numérotées. Vous pouvez alors ignorer la indirection palette-DAC parce réglage DAC registre n affecte pixels de couleur n.

 Chapitre 5: L'utilisation de la couleur 89


 Bien que cela puisse sembler tout compliqué au premier abord, il est vraiment pas une fois que vous

comprendre la relation entre les palettes et les DACs. La possibilité de sélectionner des couleurs à partir d'une palette de couleurs 256K au lieu de 16 ou 64 est généralement bien vaut l'effort supplémentaire.


Cartographie couleur RVB

 Si vous développez une application qui fonctionne en 256 couleurs et 16 couleurs

modes graphiques, vous avez probablement remarqué les différences inhérentes à la définition des valeurs de couleur. En fait, les valeurs du registre de la palette même utiliser différentes structures au sein des différents modes 16 couleurs. La fg_maprgb routine Fastgraph permet de simplifier ces différences. Il mappe trois composantes de couleur RVB (chacune entre 0 et 63) en une valeur de palette de 16 couleurs appropriée pour le mode vidéo en cours. Bien sûr, la gamme de couleurs disponibles est beaucoup plus limitée dans les modes 16 couleurs que dans les modes 256 couleurs, de sorte que fg_maprgb doit cartographier les composantes RVB de la couleur disponible la plus proche.

 Exemple 5-13 fonctionne dans un mode graphique 16 couleurs ou 256 couleurs et

illustre l'utilisation de la routine de fg_maprgb. Dans les modes 256 couleurs, le programme utilise simplement fg_setrgb pour définir DAC 1 registre à un bleu pastel (rouge = 45, vert = 49, bleu = 63). Dans les modes de 16 couleurs, cependant, le programme appelle fg_maprgb pour convertir les composantes de couleur en une valeur de la palette dans IRGB, IxRGB ou le format RGBRGB (en fonction du mode vidéo en cours). La valeur de retour de fg_maprgb est passé à fg_palette pour définir la palette registre 1 à la plus proche couleur disponible définie par les composantes RVB spécifiées.

 Exemple 5-13.
 #include <fastgraf.h>
          #include <stdio.h>
          #include <stdlib.h>
          void main (void);
 void main ()
          {
             int new_mode, old_mode;
 fg_initpm ();
             new_mode = fg_bestmode (320,200,1);
             if (new_mode <0 || new_mode == 4 || new_mode == 12) {
                printf ( "Ce programme nécessite un 320 x 200»);
                printf ( "graphiques 16 couleurs ou 256 couleurs en mode \ n.");
                sortie (1);
                }
             fg_getmode old_mode = ();
             fg_setmode (new_mode);
 fg_setcolor (1);
             if (new_mode <= 16)
                fg_palette (1, fg_maprgb (45,49,63));
             autre
                fg_setrgb (1,45,49,63);
             fg_text ( "Bonjour", 5);
             fg_waitkey (); 

Guide de l'utilisateur 90 Fastgraph


 fg_setmode (old_mode);
             fg_reset ();
          }


Définition de tous les registres de la palette

 Fastgraph comprend un fg_palettes de routine qui définit toutes les 16 palette

registres dans les modes graphiques 16 couleurs. Vous pouvez également utiliser fg_palettes pour définir les premières 16 vidéo registres du CAD dans les modes 256 couleurs. Il n'a pas d'effet dans d'autres modes vidéo.

 Utilisation de fg_palettes est beaucoup plus rapide que d'appeler fg_palette 16 fois.  le

argument fg_palettes est un entier tableau 16 de l'élément qui contient les valeurs de couleurs attribuées respectivement aux registres de la palette (ou registres vidéo DAC) 0 à 15. Exemple 5-14 montre comment mettre à zéro les registres de palette (qui est, tous changer au noir ) en mode 13.

 Exemple 5-14.
 #include <fastgraf.h>
              void main (void);
 zéros int [] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 void main ()
              {
                 Mode int;
 fg_initpm ();
                 mode = fg_getmode ();
                 fg_setmode (13);
 fg_palettes (zéros);
 fg_setmode (mode);
                 fg_reset ();
              }


Bien sûr, comme cet exemple est écrit, il semble ne rien faire plus de vider l'écran. Son but est de montrer un exemple de la routine fg_palettes.


Couleurs virtuels

 A cette époque, il devrait être clair que l'utilisation de la couleur est assez spécifique à

chaque mode graphique vidéo. L'une des différences les plus évidentes est le nombre de couleurs disponibles dans chaque mode; elle va de 2 à 256. Par couleurs disponibles, nous entendons le nombre de couleurs qui peuvent être affichées simultanément.

 Pour simplifier la programmation dans les modes graphiques, Fastgraph fournit 256 virtuel

les couleurs. Les couleurs virtuelles sont utilisées dans les modes graphiques vidéo ayant moins de 256 couleurs disponibles. couleurs virtuelles vous permettent d'utiliser 256 indices de couleur

 Chapitre 5: L'utilisation de la couleur 91


dans tous les modes graphiques, même si un mode particulier n'a pas 256 couleurs disponibles.

 Lorsque vous établissez un mode vidéo avec fg_setmode, Fastgraph initialise

tous les indices de couleur virtuels. Elle le fait en reproduisant la couleur des valeurs du mode vidéo à travers les 256 indices de couleur virtuels. Par exemple, les modes de couleurs CGA (4 et 5) présentent des quatre valeurs de couleurs, numérotées de 0 à 3. Dans ces modes, fg_setmode initialise indices de couleur 0, 4, 8, ..., 252-0; des indices de couleur 1, 5, 9, ..., 253-1; des indices de couleur 2, 6, 10, ..., 254-2; et des indices de couleur 3, 7, 11, ..., 255 à 3. De même, dans 16 couleurs modes graphiques les indices de couleur 0, 16, 32, ..., 240 sont mis à 0, et ainsi de suite. En mode vidéo monochrome EGA graphiques (mode 15), les valeurs de couleur sont numérotées de 0, 1, 4, et 5, donc fg_setmode réplique les indices de couleur en groupes de huit, même si il y a seulement quatre couleurs disponibles. Une analyse des séquences de valeurs de couleur révèle une caractéristique souvent utile: par défaut, la couleur virtuelle 0 est des couleurs noires et virtuelles 15 et 255 sont blancs dans tous les modes graphiques vidéo.

 Il est ainsi possible d'écrire un programme multi-mode à l'aide de la même couleur

indices pour chaque mode graphique. Par exemple, un programme qui contient le fg_setcolor de déclaration (5) produirait graphiques ultérieures de couleur 5 (magenta par défaut) lors de l'exécution dans un mode graphique de 16 couleurs. Il serait produire des graphiques suivants dans la couleur 1 (cyan clair par défaut) lors de l'exécution dans un mode couleur CGA. En effet, 1 est la valeur par défaut attribuée à l'index de couleur virtuelle 5 dans les modes de couleur CGA.

 La routine fg_setmode établit des valeurs par défaut pour le 256 virtuel

indices de couleur, mais il pourrait être souhaitable d'affecter d'autres couleurs disponibles pour eux. Pour en revenir à la discussion dans le paragraphe précédent, le numéro de la couleur 2 est magenta clair dans le mode CGA 4 de la palette par défaut. Il serait plus logique si la valeur de la couleur 2 ont été affectés à l'index de couleur virtuelle 5, car cela rendrait les graphiques dessinés dans la couleur 5 de la même couleur en mode 4 comme dans d'autres modes de couleur. La routine fg_defcolor Fastgraph est prévu à cet effet.

 La routine fg_defcolor attribue une valeur de couleur à un indice de couleur virtuelle.

Il dispose de deux arguments: le premier indique l'indice de couleur virtuel (entre 0 et 255), et la seconde spécifie la valeur de couleur (entre 0 et un de moins que le nombre de couleurs disponibles dans le mode vidéo actuel). Par exemple, la déclaration

 fg_defcolor (5,2);

attribuerait la valeur de couleur 2 à l'indice de couleur 5. Une autre routine Fastgraph, fg_getindex, renvoie la valeur actuelle attribuée à un indice de couleur spécifiée. Après l'exécution de l'appel ci-dessus pour fg_defcolor, la déclaration

 color = fg_getindex (5);

stockerait la valeur 2 (la valeur actuelle de l'indice de couleur 5) dans l'entier de couleur variable.

 Nous devons être sûrs de comprendre la différence entre les couleurs et virtuelles

registres de palette. Modification de la valeur d'un registre de la palette change la couleur de tous les pixels déjà dessiné en utilisant cette palette. Modification d'un index de couleur virtuelle ne le fait pas; il ne spécifie pas de graphiques dessinés dans cette couleur à partir de ce point apparaîtra dans la nouvelle couleur. Guide de l'utilisateur 92 Fastgraph


 Exemple 5-15 montre des couleurs virtuelles en mode 4. Après avoir établi

le mode vidéo, le programme utilise fg_defcolor pour définir des indices de couleur virtuels 0 et 255 à 1, qui par défaut est cyan clair en mode 4. Il tire ensuite les caractères en utilisant des indices de couleur 0, 1 et 255, et dans chaque cas, les caractères apparaître dans cyan clair. Enfin, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

 Exemple 5-15.
 #include <fastgraf.h>
                           void main (void);
 void main ()
                           {
                              Mode int;
 fg_initpm ();
                              mode = fg_getmode ();
                              fg_setmode (4);
 fg_defcolor (0,1);
                              fg_defcolor (255,1);
 fg_setcolor (0);
                              fg_text ( "0", 1);
                              fg_setcolor (1);
                              fg_text ( "1", 2);
                              fg_setcolor (255);
                              fg_text ( "255", 4);
                              fg_waitkey ();
 fg_setmode (mode);
                              fg_reset ();
                           }


A Multiple Mode-exemple

 Bien que les capacités de couleur diffèrent entre les modes vidéo pris en charge,

Fastgraph, il est facile d'écrire un programme qui tourne dans de nombreux modes vidéo. Cette section présente un exemple d'un tel programme.

 Exemple 5-16 illustre un programme qui se déroulera dans l'un des Fastgraph de

modes vidéo pris en charge. Le programme demande d'abord le numéro de mode vidéo, vérifie si le numéro de mode est valide, puis vérifie si le mode demandé est disponible sur le système de l'utilisateur. Après avoir fait cela, le programme établit le mode vidéo et exécute son code spécifique en mode. Il affiche ensuite un bref message qui comprend le numéro de mode vidéo dans lequel le programme est en cours d'exécution. Cette information reste à l'écran jusqu'à ce qu'une touche est enfoncée, au moment où le programme restaure les attributs d'origine en mode vidéo et écran avant de revenir à DOS.

 Exemple 5-16.
 #include <fastgraf.h>
                                            Chapitre 5: L'utilisation de la couleur 93


 #include <stdio.h>
      #include <stdlib.h>
      void main (void);
 void main ()
      {
         int mode, old_mode;
         chaîne char [5];
 / * Demandez le numéro de mode vidéo * /
         printf ( "mode vidéo qui?");
         scanf ( "% d", et le mode);
 / * Assurez-vous que la valeur saisie est valide * /
         si (mode <0 || Mode> 29) {
            printf ( "% d est pas un numéro de mode vidéo valide \ n"., mode);
            sortie (1);
            }
 / * Assurez-vous que le mode vidéo demandé est disponible * /
         fg_initpm ();
         if (Mode> 23) fg_svgainit (0);
         if (fg_testmode (mode, 1) == 0) {
            printf ( "Mode d% ne sont pas disponibles sur ce système. \ n", mode);
            sortie (1);
            }
 / * Mettre en place le mode vidéo * /
         fg_getmode old_mode = ();
         fg_setmode (mode);
 / * Effectuer les initialisations spécifiques au mode * /
         if (mode = 3 Mode <|| == 7) / * modes de texte * /
            fg_cursor (0);
 else if (mode == 4 || Mode == 5) {/ * modes de couleur CGA * /
            fg_palette (0,0);
            fg_defcolor (14,3);
            }
 else if (mode == 6) {/ * CGA mode deux couleurs * /
            fg_palette (0,14);
            fg_defcolor (14,1);
            }
 else if (mode == 11) / * Hercules Mode * /
            fg_defcolor (14,1);
 else if (mode == 12) / * Hercules basse résolution en mode * /
            fg_defcolor (14,3);
 else if (mode == 17) {/ * VGA deux couleurs en mode * /
            fg_palette (1,14);
            fg_setrgb (14,63,63,21);
            fg_defcolor (14,1);
            }

Guide de l'utilisateur 94 Fastgraph


 / * Affiche un message qui inclut le numéro de mode vidéo * /
         fg_setcolor (14);
         fg_text ( «Je suis en cours d'exécution en mode", 20);
         sprintf (string, "% d.", mode);
         fg_text (string, 3);
 / * Attendre une touche * /
         fg_waitkey ();
 / * Restaurer le mode vidéo original et attributs de l'écran * /
         fg_setmode (old_mode);
         fg_reset ();
      }


 Exemple 5-16 affiche son message en jaune pour les modes vidéo qui

offrir la couleur. Dans les modes vidéo monochromes, il affiche le message d'intensité normale. Le programme utilise la couleur virtuelle 14, qui par défaut est jaune dans de nombreux modes vidéo; le code spécifique mode dans l'exemple 5-16 rend la couleur jaune 14 dans d'autres modes vidéo. Dans le texte vidéo modes (modes 0 à 3 et 7), le programme utilise fg_cursor pour rendre le curseur invisible. Dans les modes de couleur CGA (modes 4 et 5), le programme utilise fg_palette pour sélectionner une palette CGA qui contient jaune comme la couleur 3 et utilise ensuite fg_defcolor pour affecter la couleur 3 à la couleur virtuelle 14. En CGA mode deux couleurs (mode 6), le programme utilise fg_palette pour faire la couleur 1 jaune, puis utilise fg_defcolor pour affecter la couleur 1 à la couleur virtuelle 14. Dans les modes Hercules (modes 11 et 12), le programme utilise fg_defcolor pour affecter la valeur des pixels d'intensité normale à la couleur 14. Dans VGA mode deux couleurs (mode 17), le programme utilise fg_palette pour affecter la vidéo DAC registre 14 à palette registre 1. Il définit ensuite la vidéo DAC registre 14 pour être jaune avec fg_setrgb et enfin utilise fg_defcolor pour affecter la couleur 1 (qui est, la palette inscrivez-1) à la couleur virtuelle 14. Dans tous les autres modes vidéo, aucune manipulation de couleur est nécessaire parce que la couleur 14 est jaune par défaut.


Résumé des Routines de couleur liés

 Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

 FG_COLORS renvoie le nombre de couleurs disponibles simultanément dans le

mode vidéo actuel. Dans les modes vidéo texte, fg_colors retourne zéro.

 FG_DEFCOLOR attribue une valeur de couleur à un indice de couleur virtuelle.  Cette routine

n'a de sens que dans les modes graphiques vidéo qui ont moins de 256 couleurs disponibles.

 FG_GETCOLOR renvoie l'attribut courant de texte (en mode texte) ou de couleur

index (dans les modes graphiques), tel que spécifié dans l'appel le plus récent à fg_setattr ou fg_setcolor.

 FG_GETDACS extrait les composantes de couleur rouge, vert et bleu pour une

bloc de registres numérotés consécutivement vidéo du CAD. Cette routine est seulement modes significatifs qui utilisent des registres du CAD.

 Chapitre 5: L'utilisation de la couleur 95


 FG_GETINDEX renvoie la valeur de couleur associée à une couleur virtuelle spécifiée

indice. Dans les modes de texte et dans les modes graphiques qui ont 256 couleurs disponibles, cette routine renvoie la valeur qui lui est passé.

 FG_GETRGB renvoie les composantes de couleur rouge, vert et bleu pour une

vidéo spécifié registre DAC. Cette routine n'a de sens que dans les modes qui utilisent des registres du CAD.

 FG_MAPRGB cartes à six bits rouge, vert et bleu des composantes de couleur en un

La valeur de la palette appropriée pour le mode vidéo en cours. Vous pouvez ensuite transmettre cette valeur à fg_palette. Cette routine n'a de sens que dans les modes graphiques vidéo 16 couleurs.

 FG_PALETTE a des fonctions différentes selon les graphiques actuels

mode vidéo. Pour les modes de quatre couleurs CGA, il établit la palette actuelle (de six disponibles) et définit la couleur de fond pour cette palette. Dans le mode deux couleurs CGA, il définit la couleur de premier plan. Pour le Tandy / PCjr, EGA et modes graphiques VGA, il définit la valeur d'un registre unique de la palette. Pour les modes graphiques 256 couleurs, il définit la valeur d'un seul registre vidéo DAC. La routine de fg_palette n'a aucun effet en mode texte ou les modes graphiques Hercules.

 FG_PALETTES définit tous les registres 16 de la palette (en 16 couleurs graphiques

modes) ou les 16 premiers registres vidéo du CAD (en modes graphiques 256 couleurs). La routine de fg_palettes n'a aucun effet en mode texte, les modes graphiques CGA, ou les modes graphiques Hercules.

 FG_SETATTR établit le courant attribut de texte en mode texte vidéo.

Cette routine n'a pas d'effet dans les modes graphiques.

 FG_SETCOLOR établit l'indice de couleur actuelle (qui peut être un virtuel

indice de couleur dans les modes graphiques). En mode texte, fg_setcolor propose une autre méthode pour établir l'attribut texte actuel.

 FG_SETDACS définit les valeurs d'un bloc de vidéo numérotés consécutivement

DAC enregistre en spécifiant leurs rouges, verts et bleus composantes de couleur. Cette routine n'a de sens que dans les modes qui utilisent des registres du CAD.

 FG_SETRGB définit la valeur d'un registre unique de la palette (en Tandy / PCjr

et les modes graphiques EGA) ou registre vidéo DAC (VGA, MCGA et modes SVGA) en spécifiant ses rouges, verts et bleus composantes de couleur. La routine de fg_setrgb n'a aucun effet en mode texte, les modes graphiques CGA, ou les modes graphiques Hercules. Guide de l'utilisateur 96 Fastgraph



Chapitre 6


Guide Fundamentals graphiques 98 Fastgraph utilisateur


aperçu

 Ce chapitre décrit les routines graphiques fondamentales de Fastgraph,

parfois appelée primitives graphiques. Ces routines exécutent des fonctions telles que la compensation de l'écran, le dessin des points, le dessin des lignes pleines et pointillées, le dessin des formes (polygones, cercles, et ellipses) fermé, dessin rectangles (solides, creux et tramé), et le remplissage des régions arbitraires. La plupart de ces routines ont aucun effet en mode texte vidéo, mais il y a quelques exceptions près, et ils seront notées dans les descriptions de ces routines.


Effacement de l'écran

 La fg_erase routine Fastgraph efface la totalité de l'écran dans toute vidéo

mode. En mode texte, fg_erase stocke un caractère d'espace (ASCII 32) avec un attribut de premier plan gris dans chaque cellule de caractère. Dans les modes graphiques, fg_erase définit chaque pixel à zéro. Bien sûr, cela amène chaque pixel à afficher la couleur d'arrière-plan. La routine de fg_erase n'a pas d'arguments.

 La routine de fg_erase définit toujours l'ensemble de l'écran à l'arrière-plan

Couleur. Une autre routine, fg_fillpage, remplit l'écran avec la couleur actuelle. En mode texte, fg_fillpage stocke un caractère solide bloc (ASCII 219) avec l'attribut d'affichage actuel (tel que défini dans l'appel le plus récent à fg_setcolor ou fg_setattr). Dans les modes graphiques, fg_fillpage définit chaque pixel à la couleur actuelle (tel que défini dans l'appel le plus récent à fg_setcolor). Comme fg_erase, fg_fillpage n'a pas d'arguments.


Coupure

 La suppression des graphiques en dehors d'une zone prédéfinie est appelée

coupure. Beaucoup de routines graphiques orientées-de Fastgraph fournissent écrêtage, soit automatiquement, soit par le biais d'une version spéciale de la routine.

 Fastgraph comprend deux routines, fg_setclip et fg_setclipw, pour définir un

région de découpage rectangulaire. La routine fg_setclip définit la zone de découpage dans l'espace de l'écran, tandis que fg_setclipw remplit la même fonction dans l'espace mondial. Chaque routine prend quatre arguments: les x minimum, le maximum de x, le minimum y, et le maximum coordonnée y de la zone de découpage. Les arguments sont des quantités entières pour fg_setclip et flottant quantités de points pour fg_setclipw. Par exemple, la déclaration

 fg_setclip (0,159,0,99);

définirait le quadrant supérieur gauche de l'écran comme la zone de découpage en mode graphique 320x200. La routine de fg_getclip de Fastgraph renvoie les limites d'écrêtage actuels, tels que définis dans l'appel le plus récent à fg_setclip.

 Une zone de découpage implicite égale à la totalité de l'écran est définie dans le cadre

des initialisations de la routine de fg_setmode. Clipping est pas pris en charge pour les modes de texte.

 Chapitre 6: Fundamentals graphiques 99


Points

 La fg_point routine Fastgraph fournit le plus de graphiques de base

opération - la fixation d'un pixel à une couleur spécifiée. La routine de fg_point a deux arguments entiers. Le premier spécifie les x du pixel de coordonnées, et la seconde de sa coordonnée y. Le pixel est dessiné en utilisant la valeur de couleur en cours, tel que spécifié dans l'appel le plus récent à fg_setcolor. Il existe également une version mondiale de l'espace de cette routine, fg_pointw, qui utilise des arguments flottants de point. Les deux routines affichent le pixel que si elle se situe dans la zone de découpage actuel.

 Une autre routine Fastgraph est disponible pour la lecture de la valeur d'un pixel de couleur.

La routine de fg_getpixel a deux arguments entiers qui spécifient le (x, y) les coordonnées du pixel d'intérêt. Si le (x, y) les coordonnées se trouvent en dehors de la zone de découpage, fg_getpixel renvoie -1. Il n'y a pas de version de fg_getpixel mondiale de l'espace, mais vous pouvez lire la valeur de la couleur d'un pixel dans l'espace du monde en appliquant les fonctions de fg_xscreen et fg_yscreen aux coordonnées spatiales du monde et en passant les valeurs obtenues à fg_getpixel.

 Exemple 6-1 utilise fg_point pour dessiner 100 points aléatoires dans des couleurs aléatoires.  Il

utilise également fg_getpixel pour assurer sans deux points sont adjacents. Le programme établit un mode vidéo de graphiques avec fg_automode et fg_setmode. Ensuite, il appelle fg_colors pour déterminer la valeur de couleur maximale pour le mode vidéo sélectionné, puis appelle fg_getmaxx et fg_getmaxy pour obtenir la résolution horizontale et verticale. La partie principale du programme est une boucle while qui génère d'abord une paire aléatoire de coordonnées (x, y) écran. Il appelle ensuite fg_getpixel de vérifier les pixels à (x, y) et les huit positions adjacentes. Si aucune de ces pixels sont fixés, le programme génère une valeur de couleur aléatoire et dessine un point dans cette couleur. Après avoir fait ce 100 fois, le programme attend une touche, restaure les attributs d'origine en mode vidéo et d'écran, puis retourne à DOS.

 Exemple 6-1.
 #include <fastgraf.h>
          #include <stdlib.h>
          void main (void);
 void main ()
          {
             zone int;
             int couleur, couleurs;
             int gauche;
             int new_mode, old_mode;
             int x_range, y_range;
             int x, y;
 fg_initpm ();
             fg_getmode old_mode = ();
             fg_automode new_mode = ();
             fg_setmode (new_mode);
 couleurs = fg_colors ();
             fg_getmaxx x_range = () - 1;
             fg_getmaxy y_range = () - 1;
             gauche = 100; 

Guide de l'utilisateur 100 Fastgraph


 tandis que (à gauche> 0)
             {
                x = (rand ()% x_range) + 1;
                y = (rand ()% y_range) + 1;
 surface = fg_getpixel (x-1, y-1) + fg_getpixel (x, y-1) +
                       fg_getpixel (x + 1, y-1) + fg_getpixel (x-1, y) +
                       fg_getpixel (x, y) + fg_getpixel (x + 1, y) +
                       fg_getpixel (x-1, y + 1) + fg_getpixel (x, y + 1) +
                       fg_getpixel (x + 1, y + 1);
                if (zone == 0)
                {
                   color = rand ()% des couleurs;
                   fg_setcolor (couleur);
                   fg_point (x, y);
                   à gauche--;
                }
             }
             fg_waitkey ();
 fg_setmode (old_mode);
             fg_reset ();
          }


 Parfois, vous voudrez peut-être afficher un pixel en utilisant un "ou exclusif"

opération (habituellement appelée XOR) pour garantir sa visibilité. La couleur d'un pixel dessiné en mode XOR sera c xor p, où c est la couleur courante et p est la couleur du pixel déjà à cette position. Cela signifie une nouvelle couleur du pixel sera différent de l'arrière-plan aussi longtemps que la couleur actuelle est non nul. La fg_pointx routine Fastgraph affiche un pixel de l'espace de l'écran en mode XOR, tandis que fg_pointxw fait la même chose dans l'espace mondial. Leurs paramètres respectifs sont les mêmes que pour fg_point et fg_pointw.


Le Cursor Graphics

 Un grand nombre de routines de graphiques de Fastgraph dépendent de la position du

graphiques curseur comme point de référence. Par exemple, Fastgraph comprend des routines pour tracer des lignes de la position graphique du curseur à une position spécifiée, et les routines d'affichage d'image bitmap discuté au chapitre 10 affichage ou récupérer une image par rapport à la position du curseur graphique. Le curseur graphique est pas un curseur dans le vrai sens; il est tout simplement une paire de (x, y) les coordonnées avec une signification particulière. La routine fg_setmode définit la position graphique curseur sur les coordonnées de l'espace de l'écran (0,0), et fg_initw définit sur les coordonnées spatiales du monde (0.0,0.0).

 Fastgraph comprend quatre routines pour modifier le curseur graphique

position. Les ensembles de routine fg_move elle à une position de l'espace écran absolu, tandis que fg_movew fixe à une position mondiale de l'espace absolu. La routine fg_moverel définit la position graphique du curseur à une position espace de l'écran par rapport à sa position actuelle. La routine de fg_moverw fait la même chose dans l'espace mondial. Chacun de ces routines a deux arguments qui spécifient le (x, y) les coordonnées de la nouvelle position. Pour les routines de l'espace de l'écran, les arguments sont des nombres entiers

 Chapitre 6: Notions de base 101 Graphiques


quantités. Pour les routines spatiales du monde, les arguments sont flottants quantités ponctuelles.

 Vous pouvez obtenir les coordonnées de l'espace de l'écran du curseur graphique

position avec les fg_getxpos et fg_getypos routines. Ces routines ont pas d'arguments et respectivement retourner les coordonnées x et y de la position du curseur graphique que la valeur de la fonction. Pour obtenir les coordonnées de l'espace mondial de la position du curseur graphique, appliquer les fonctions de fg_xworld et fg_yworld aux valeurs de fg_getxpos et fg_getypos retour.


Lignes solides

 Fastgraph comprend huit routines pour tracer des lignes solides.  Tous

tracer des lignes dans la valeur de la couleur actuelle et respecter les limites d'écrêtage. La routine de fg_draw dessine une ligne de la position actuelle du curseur graphique à une position d'espace d'écran absolu, tandis que fg_draww dessine une ligne à une position mondiale de l'espace absolu. La routine de fg_drawrel dessine une ligne de la position actuelle du curseur graphique à une position de l'espace de l'écran par rapport à lui. La routine de fg_drawrw fait la même chose dans l'espace mondial. Vous pouvez dessiner des lignes absolues en mode XOR avec fg_drawx et XOR par rapport lignes avec fg_drawrelx, ou avec leur monde homologues de l'espace fg_drawxw et fg_drawrxw. lignes XOR sont souvent utilisés lors de l'élaboration des curseurs (comme réticule) ou des boîtes rubberband pour assurer qu'ils sont visibles sur un fond de couleur. Une autre propriété utile de lignes XOR est que le dessin de la même ligne deux fois restaure ce qui était à l'origine sous la ligne.

 Chacun de ces sous-programmes comporte deux arguments qui spécifient les valeurs (x, y)

les coordonnées de la position de destination. Pour les routines de l'espace de l'écran, les arguments sont des quantités entières. Pour les routines spatiales du monde, les arguments sont flottants quantités ponctuelles. Dans les deux cas, la position de destination devient la nouvelle position du curseur graphique. Cela permet de tracer des lignes connectées sans appeler un mouvement de routine graphiques du curseur entre les appels successifs à une routine de dessin au trait.

 Exemples 6-2 et 6-3 chaque dessiner une paire de lignes croisées qui divisent le

écran en quadrants. Exemple 6-2 fait cela en utilisant fg_move et fg_draw, tandis que l'exemple 6-3 utilise fg_moverel et fg_drawrel. Les deux exemples dessinent les lignes en blanc, la valeur par défaut pour la couleur 15 dans tous les modes graphiques vidéo.

 Exemple 6-2.  Exemple 6-3.
 #include <fastgraf.h> #include <fastgraf.h>
     void main (void);  void main (void);
 void main () void main ()
     {{
        int max_x, max_y;  int max_x, max_y;
        int mid_x, mid_y;  int mid_x, mid_y;
        int new_mode, old_mode;  int new_mode, old_mode;
 fg_initpm ();  fg_initpm ();
        fg_getmode old_mode = ();  fg_getmode old_mode = ();
        fg_automode new_mode = ();  fg_automode new_mode = ();
        fg_setmode (new_mode);  fg_setmode (new_mode); 

Guide de l'utilisateur 102 Fastgraph


        fg_getmaxx max_x = ();  fg_getmaxx max_x = ();  fg_getmaxy max_y = ();  fg_getmaxy max_y = ();  mid_x = max_x / 2;  mid_x = max_x / 2;  mid_y = max_y / 2;  mid_y = max_y / 2; 
 fg_setcolor (15);  fg_setcolor (15);
        fg_move (mid_x, 0);  fg_move (mid_x, 0);
        fg_draw (mid_x, max_y);  fg_drawrel (0, max_y);
        fg_move (0, mid_y);  fg_moverel (-mid_x, -mid_y);
        fg_draw (max_x, mid_y);  fg_drawrel (max_x, 0);
        fg_waitkey ();  fg_waitkey ();
 fg_setmode (old_mode);  fg_setmode (old_mode);
        fg_reset ();  fg_reset ();
     }}


 Exemples 6-4 et 6-5 sont des variantes de l'exemple 6-2.  Exemple 6-4 utilise

l'espace du monde plutôt que de l'espace de l'écran pour dessiner les lignes croisées. Exemple 6-5 est le même que l'exemple 6-2 sauf qu'il définit une zone d'écrêtage pour restreindre le dessin dans le quadrant supérieur gauche de l'écran. La coupure supprime la moitié droite de la ligne horizontale et la moitié inférieure de la ligne verticale.

 Exemple 6-4.  Exemple 6-5.
 #include <fastgraf.h> #include <fastgraf.h>
  void main (void);  void main (void);
 void main () void main ()
  {{
     int new_mode, old_mode;  int max_x, max_y;
                                               int mid_x, mid_y;
     fg_initpm ();  int new_mode, old_mode;
     fg_getmode old_mode = ();
     fg_automode new_mode = ();  fg_initpm ();
     fg_setmode (new_mode);  fg_getmode old_mode = ();
     fg_initw ();  fg_automode new_mode = ();
     fg_setworld (-10.0,10.0, -10.0,10.0);  fg_setmode (new_mode);
 fg_setcolor (15);  fg_getmaxx max_x = ();
     fg_movew (0.0,10.0);  fg_getmaxy max_y = ();
     fg_draww (0,0, -10,0);  mid_x = max_x / 2;
     fg_movew (-10.0,0.0);  mid_y = max_y / 2;
     fg_draww (10.0,0.0);
     fg_waitkey ();  fg_setclip (0, mid_x, 0, mid_y);
 fg_setmode (old_mode);  fg_setcolor (15);
     fg_reset ();  fg_move (mid_x, 0);
  } Fg_draw (mid_x, max_y);
                                               fg_move (0, mid_y);
                                               fg_draw (max_x, mid_y);
                                               fg_waitkey ();
 fg_setmode (old_mode);
                                               fg_reset ();
                                            }
                                      Chapitre 6: Fundamentals graphiques 103


Lignes en pointillé

 Fastgraph comprend quatre routines pour tracer des lignes en pointillés.  Tous

tracer des lignes dans la valeur de la couleur actuelle et respecter les limites d'écrêtage. La routine de fg_dash dessine une ligne en pointillés de la position actuelle du curseur graphique à une position d'espace d'écran absolu, tandis que fg_dashw dessine une ligne en pointillés à une position mondiale de l'espace absolu. La routine fg_dashrel dessine une ligne en pointillés de la position actuelle du curseur graphique à une position d'espace de l'écran par rapport à lui. La routine de fg_dashrw fait la même chose dans l'espace mondial.

 Chacun de ces routines a trois arguments.  Les deux premiers spécifiez le

(X, y) les coordonnées de la position de destination. Pour les routines de l'espace de l'écran, ces arguments sont des quantités entières. Pour les routines spatiales du monde, ces arguments sont flottantes quantités ponctuelles. Le troisième argument est un modèle 16 bits qui définit l'apparence de la ligne en pointillés. Les bits qui sont définis dans le modèle produisent la partie visible de la ligne, alors que bits qui sont zéro produisent la partie invisible. Ce schéma est répété comme nécessaire d'attirer l'ensemble de la ligne. Par exemple, la valeur hexadécimale de modèle 3333 produirait une ligne en pointillés avec les deux premiers pixels au large, les deux suivants sur, les deux suivants au large, et ainsi de suite. De même, la valeur de motif FFFF hex produirait une ligne solide.

 La position de destination est passé à une des routines de la ligne en pointillés

devient la nouvelle position du curseur graphique. Cela permet de tracer des lignes en pointillés connectés sans appeler un mouvement de routine graphiques du curseur entre les appels successifs à une routine de dessin au trait.

 Exemple 6-6 dessine une paire de lignes pointillées croisées qui divisent l'écran

en quadrants. Il le fait en utilisant fg_move et fg_dash et dessine les lignes en blanc, la valeur par défaut pour la couleur 15 dans tous les modes graphiques vidéo. Le modèle de tableau de bord pour chaque ligne est 3333 hex, qui alterne deux pixels et hors tension.

 Exemple 6-6.
 #include <fastgraf.h>
                       void main (void);
 void main ()
                       {
                          int max_x, max_y;
                          int mid_x, mid_y;
                          int new_mode, old_mode;
 fg_initpm ();
                          fg_getmode old_mode = ();
                          fg_automode new_mode = ();
                          fg_setmode (new_mode);
 fg_getmaxx max_x = ();
                          fg_getmaxy max_y = ();
                          mid_x = max_x / 2;
                          mid_y = max_y / 2;
 fg_setcolor (15); 

Guide de l'utilisateur 104 Fastgraph


 fg_move (mid_x, 0);
                          fg_dash (mid_x, max_y, 0x3333);
                          fg_move (0, mid_y);
                          fg_dash (max_x, mid_y, 0x3333);
                          fg_waitkey ();
 fg_setmode (old_mode);
                          fg_reset ();
                       }


Polygones

 Fastgraph comprend des routines pour dessiner des polygones chargés et non chargés, comme

et une routine pour déterminer si un point donné est à l'intérieur d'un polygone convexe. Toutes les routines de polygone observent les limites d'écrêtage.

 La routine de fg_polygon dessine un polygone vide dans l'espace de l'écran.  Il

nécessite un tableau de nombre entier x coordonnées comme premier argument, et un tableau de nombre entier y coordonne comme second argument. Chaque (x, y) paire de coordonnées à partir des deux réseaux est traité comme un sommet du polygone. En d'autres termes, la coordonnée x du premier sommet du polygone est le premier élément du tableau de coordonnées x et la coordonnée y du premier sommet est le premier élément de la matrice coordonnée y. De même, les seconds éléments de chaque réseau définissent le deuxième sommet, et ainsi de suite. Le troisième argument pour fg_polygon est une quantité entière qui indique le nombre d'éléments dans les deux coordonnées des tableaux (qui est, le nombre de sommets du polygone).

 Une autre routine, fg_polygonw, dessine un polygone dans l'espace non rempli de monde.

La routine de fg_polygonw est la même que la routine de fg_polygon, à l'exception de son coordonnées x et y doivent contenir des tableaux valeurs à virgule flottante à la place des nombres entiers.

 dessin polygonal commence au niveau du premier sommet de coordonnées spécifié dans la

tableaux. Les routines de polygones, puis tracer une ligne solide pour le second sommet, puis au troisième sommet, et continuent de cette manière par le dernier sommet. Si nécessaire, ils ferment alors le polygone en traçant une ligne reliant le dernier sommet et le premier sommet. Exemple 6-7 illustre le dessin de polygone non rempli en utilisant fg_polygon dans le monochrome EGA ou modes (modes 15 et 16) améliorés. Le programme se termine si aucun de ces modes vidéo sont disponibles.

 Exemple 6-7.
 #include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
            void main (void);
 #define vertices 10
 int x [] = {200.300.400.400.300.240.160.160.200.210};
            int y [] = {100, 80.100.220.320.320.240.200.160.150};
 void main ()
            {
                                      Chapitre 6: Fundamentals graphiques 105


 int old_mode;
 fg_initpm ();
               fg_getmode old_mode = ();
               if (fg_testmode (16,1))
                  fg_setmode (16);
               else if (fg_testmode (15,1))
                  fg_setmode (15);
               autre {
                  printf ( "Ce programme nécessite un 640 x 350»);
                  ( "mode graphique EGA \ n".) printf;
                  sortie (1);
                  }
 fg_setcolor (1);
               fg_polygon (x, y, VERTICES);
               fg_waitkey ();
 fg_setmode (old_mode);
               fg_reset ();
            }


 Comme le montre cet exemple, fg_polygon prévoit que les composantes x et y

définissant les sommets du polygone d'être dans des tableaux distincts. Une autre routine, fg_polyline, dessine un polygone non rempli de sommets du polygone dans un tableau d'entiers. Fg_polyline avec le premier élément de tableau est la composante x du premier sommet, le second élément est la composante y du premier sommet, le troisième élément est la composante x du deuxième sommet, et ainsi de suite. Le premier argument de fg_polyline est le sommet de coordonnées tableau de composantes x et y en alternance, et le second argument spécifie le nombre de sommets. À d'autres égards, est identique à celui fg_polyline fg_polygon.

 Une caractéristique supplémentaire disponible avec fg_polyline mais pas fg_polygon est

la possibilité de spécifier des décalages vertex. deux arguments entiers de la routine de fg_polyoff respectivement définir les valeurs de décalage qui sont ajoutés à chaque sommet de fg_polyline. Ceci permet de définir des sommets du polygone en tant que valeurs relatives, qui lorsqu'ils sont combinés avec des décalages, de déterminer la position absolue du polygone.

 Peut-être le plus important programme d'affichage de polygones est fg_polyfill, qui

affiche un polygone convexe rempli dans l'espace de l'écran (le polygone est rempli de pixels de la couleur actuelle). Son premier argument est un tableau de vertex dans le même format utilisé par fg_polyline. L'argument suivant est un tableau de travail utilisé en interne. La taille en octets du tableau de travail doit être d'au moins quatre fois la hauteur de polygone. Le dernier argument spécifie le nombre de sommets du polygone.

 Exemple 6-8 illustre l'utilisation de fg_polyline, fg_polyoff et

fg_polyfill. Le programme dessine d'abord un polygone non rempli, centré dans la moitié gauche de l'écran. Il tire alors une version remplie du même polygone, centré dans la moitié droite de l'écran. Dans chaque cas, le centrage est réalisé en faisant passer les valeurs appropriées pour fg_polyoff. Après avoir attendu pendant une séquence de touches, le programme établit une zone de découpage dans le coin inférieur droit et redessine le polygone rempli à la même position, mais dans une couleur différente. Des résultats de ce parcours dans seulement une partie du polygone rempli en cours d'élaboration. Comme exemple 6-7, cet exemple requiert un mode 640x350 graphique. Guide de l'utilisateur 106 Fastgraph


 Exemple 6-8.
 #include <fastgraf.h>
          #include <stdio.h>
          #include <stdlib.h>
          void main (void);
 #define vertices 10
 int xy [] = {200,100, 300, 80, 400100, 400220, 300320,
                      240320, 160240, 160200, 200160, 210150};
          int work_array [700];
 void main ()
          {
             int old_mode;
 fg_initpm ();
             fg_getmode old_mode = ();
             if (fg_testmode (16,1))
                fg_setmode (16);
             else if (fg_testmode (15,1))
                fg_setmode (15);
             autre {
                printf ( "Ce programme nécessite un 640 x 350»);
                ( "mode graphique EGA \ n".) printf;
                sortie (1);
                }
 fg_setcolor (1);
             fg_polyoff (-120, -25);
             fg_polyline (xy, VERTICES);
             fg_polyoff (200, -25);
             fg_polyfill (xy, work_array, VERTICES);
             fg_waitkey ();
 fg_setcolor (2);
             fg_setclip (480,639,175,349);
             fg_polyfill (xy, work_array, VERTICES);
             fg_waitkey ();
 fg_setmode (old_mode);
             fg_reset ();
          }


 La routine de fg_polyfill remplit les polygones convexes.  De Fastgraph de

perspective, un polygone est convexe si une ligne horizontale tracée à travers le polygone traverse le bord gauche exactement une fois et le bord droit exactement une fois (à l'exclusion des segments de bord horizontal et de longueur nulle). A noter que cette définition inclut des formes qui ne sont pas convexe dans le sens traditionnel. En outre, tout polygone non convexe peut être décomposée en deux ou plusieurs polygones convexes. Tous les triangles (qui est, les polygones de trois sommets) sont par leur nature convexe.

 Chapitre 6: Fundamentals graphiques 107


 Le polygone convexe rempli est un outil de base de l'ordinateur en trois dimensions

graphique. Une pratique courante consiste à construire une image ou d'un objet à partir de plusieurs polygones adjacents ou de connexion. Ces polygones se chevauchent généralement à un ou plusieurs bords. Par exemple, les coordonnées définissant le bord droit d'un polygone peut également définir le bord gauche d'un autre polygone immédiatement à sa droite. Pour une image globale apparaisse correcte, ses polygones de composants doivent correspondre ensemble correctement. Par défaut, fg_polyfill applique les règles suivantes pour gérer chevaucher les bords du polygone:

 * Points situés exactement sur les bords non horizontaux
              sont dessinés uniquement si l'intérieur du polygone est
              directement à droite.
 * Points situés exactement sur les bords horizontaux sont
              dessiné que si l'intérieur du polygone est directement
              en dessous.
 * Un sommet est établi que si toutes les lignes se terminant à
              ce point satisfait les deux conditions ci-dessus.

Ces trois règles assurent qu'aucun pixel est tiré plus d'une fois lors du remplissage de polygones adjacents. Toutefois, ce comportement peut ne pas être adapté à l'affichage des polygones qui ne sont pas adjacents, parce que certains ou tous les pixels sur les bords droit et inférieur du polygone seront exclus. Si cela est un problème, vous pouvez utiliser fg_polyedge pour forcer fg_polyfill pour inclure tous les pixels de bord. La routine fg_polyedge attend un paramètre entier unique. Si elle est nulle, fg_polyfill comprendra tous les pixels de bord lors de l'élaboration des polygones convexes. Passant toute autre valeur à fg_polyedge restaure le comportement par défaut d'exclure les pixels qui répondent aux critères décrits ci-dessus.

 La routine finale Fastgraph relatives aux polygones est fg_inside, qui

vérifie si un point spécifié se situe à l'intérieur d'un polygone convexe. Son premier argument est un tableau de vertex dans le même format utilisé par fg_polyline et fg_polyfill. Le second argument est le nombre de sommets du polygone, tandis que les deux derniers arguments spécifient l'espace écran coordonnées x et y du point mis à l'essai. Les fg_inside routine renvoie 1 si le point se trouve à l'intérieur du polygone et 0 sinon. Si le tableau de vertex ne définit pas un polygone convexe, la valeur de retour est indéfinie. Les décalages de fg_polyoff sont appliqués à la fg_inside tableau de vertex, mais pas au point de test.


Cercles et Ellipses

 Fastgraph comprend des routines pour le dessin rempli et les cercles non remplis et

ellipses. Les deux versions de l'espace de l'écran et de l'espace du monde de ces routines sont disponibles, et chacun d'entre eux observent les limites d'écrêtage.

 La routine de fg_circle dessine un cercle vide dans l'espace de l'écran, centrée

à la position du curseur graphique, en utilisant la couleur actuelle. Son seul argument spécifie le rayon du cercle dans horizontales unités de l'espace de l'écran. Une autre routine, fg_circlew, dessine un cercle non rempli où le rayon est mesuré en unités horizontales spatiales mondiales. Les routines analogues pour les cercles de dessin rempli sont fg_circlef et fg_circlefw. Les quatre cercles de dessin routines quittent la position du curseur graphique inchangé. Guide de l'utilisateur 108 Fastgraph


 La routine de fg_ellipse dessine une ellipse non remplie dans l'espace de l'écran,

centré sur la position du curseur graphique, en utilisant la couleur actuelle. La routine requiert deux arguments qui indiquent respectivement la longueur de ses demi-axes horizontaux et verticaux. En d'autres termes, le premier argument est la distance absolue à partir du centre de l'ellipse à son extrémité horizontale et le second argument est la distance absolue du centre à l'extrémité verticale. Une autre routine, fg_ellipsew, dessine une ellipse non remplie dans l'espace mondial. Les routines analogues pour dessiner des ellipses remplies sont fg_ellipsef et fg_ellipsfw. Les quatre routines de dessin ellipse quittent la position du curseur graphique inchangé.

 Exemple 6-9 illustre l'utilisation de la fg_circlew et fg_ellipsew

routines. Le programme utilise d'abord fg_automode de proposer un mode vidéo de graphiques et utilise ensuite fg_setmode pour sélectionner ce mode vidéo. Il fait alors la couleur 15 la couleur actuelle, qui par défaut est blanc dans tous les modes graphiques couleur et "on" dans les modes les monochromes graphiques. Ensuite, il établit un espace de 200x200 système de coordonnées. Le programme fg_ellipsew utilise ensuite pour dessiner une ellipse et fg_circlew pour dessiner un cercle, à la fois centré au milieu de l'écran (ce qui est à l'origine de notre espace mondial du système de coordonnées). Le cercle a un rayon de 1/16 de la largeur de l'écran (12,5 horizontales unités spatiales du monde), et l'ellipse est inscrite horizontalement à l'intérieur du cercle.

 Exemple 6-10 illustre l'utilisation de la fg_circle et fg_ellipse

routines. Il est fonctionnellement identique à l'exemple 6-9, mais il utilise l'espace de l'écran plutôt que l'espace de coordonnées du monde pour dessiner le cercle et une ellipse. Notez les arguments à fg_circle et fg_ellipse dépendent du maximum de coordonnées x et y du mode vidéo sélectionné. Si l'on ne calcule ces arguments de cette manière, la taille réelle du cercle et une ellipse serait proportionnel à la résolution de pixel du mode vidéo. Aucune telle dépendance existe lorsque vous utilisez l'espace du monde, mais nous payons un prix pour cette fonction dans un peu plus lente vitesse d'exécution.

 Exemple 6-9.  Exemple 6-10.
 #include <fastgraf.h> #include <fastgraf.h>
      void main (void);  void main (void);
 void main () void main ()
      {{
         int old_mode;  int mid_x, mid_y;
                                             int old_mode;
         fg_initpm ();  int x, y;
         fg_getmode old_mode = ();
         fg_setmode (fg_automode ());  fg_initpm ();
         fg_setcolor (15);  fg_getmode old_mode = ();
                                             fg_setmode (fg_automode ());
         fg_initw ();  fg_setcolor (15);
         fg_setworld (-100.0,100.0,
                     -100.0,100.0);  mid_x = fg_getmaxx () / 2;
                                             mid_y = fg_getmaxy () / 2;
         fg_movew (0.0,0.0);  x = mid_x / 8;
         fg_ellipsew (12.5,12.5);  y = mid_y / 8;
         fg_circlew (12,5);
         fg_waitkey ();  fg_move (mid_x, mid_y);
                                             fg_ellipse (x, y);
         fg_setmode (old_mode);  fg_circle (x); 
                                      Chapitre 6: Fundamentals graphiques 109


 fg_reset ();  fg_waitkey ();
      }
                                             fg_setmode (old_mode);
                                             fg_reset ();
                                          }


Rectangles solides

 Fastgraph comprend quatre routines pour dessiner des rectangles solides, deux pour

l'espace de l'écran et deux pour l'espace du monde, avec et sans écrêtage. Aucun de ces routines affectent la position du curseur graphique.

 La routine de fg_rect dessine un rectangle solide dans l'espace de l'écran, sans

ce qui concerne les limites d'écrêtage, en utilisant la couleur actuelle. Il nécessite quatre arguments entiers qui définissent respectivement le minimum x, x maximale, y minimum, et y coordonnées maximales de l'espace de l'écran du rectangle. Les coordonnées minimales doivent être inférieures ou égales aux coordonnées maximales, ou bien les résultats sont imprévisibles. La routine de fg_clprect est identique en tous points à fg_rect, sauf qu'il respecte les limites d'écrêtage.

 Les versions de l'espace mondial des solides routines de dessin de rectangle sont

fg_rectw et fg_clprectw. Comme fg_rect et fg_clprect, ils nécessitent quatre arguments qui définissent les extrémités du rectangle, mais les arguments sont coordonnées spatiales points du monde flottant.

 Vous pouvez également utiliser fg_rect en mode texte.  Lorsqu'il est utilisé dans un mode texte, fg_rect

prévoit que ses quatre arguments pour être exprimés dans l'espace de caractères (qui est, lignes et colonnes) plutôt que l'espace de l'écran. Cela signifie que les quatre arguments spécifient respectivement la colonne minimum, colonne maximale, ligne minimale et ligne maximale du rectangle. Fastgraph construit le rectangle en stockant le solide caractère de bloc (ASCII valeur décimale 219) dans chaque cellule de caractère comprenant rectangle. Le rectangle est dessiné en utilisant l'attribut de caractère en cours, mais parce que le caractère de bloc solide occupe la cellule de caractère entier, le composant de base de l'attribut est essentiellement dépourvue de sens.

 Exemple 6-11 illustre l'utilisation de fg_rect en tirant 200 aléatoire de taille

rectangles aux couleurs aléatoires. Le programme utilise fg_automode premier à proposer un mode vidéo de graphiques, puis utilise la routine de fg_setmode pour sélectionner ce mode vidéo. Ensuite, il détermine la résolution d'écran horizontal et vertical pour le mode vidéo sélectionné, en utilisant fg_getmaxx et fg_getmaxy. La partie principale du programme est une boucle qui génère un rectangle aléatoire dans chaque itération. A l'intérieur de la boucle, la fonction de bibliothèque rand C est utilisé pour générer les extrémités du rectangle. Si nécessaire, le programme échange alors les coordonnées pour rendre minimum les coordonnées inférieures ou égales aux coordonnées maximales. Enfin, il utilise à nouveau rand pour générer un numéro de couleur aléatoire entre 0 et 15, puis dessine le rectangle dans cette couleur. Après avoir dessiné les 200 rectangles, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

 Exemple 6-11.
 #include <fastgraf.h>
            void main (void); 

Guide de l'utilisateur 110 Fastgraph


 #define RECTANGLES 200
            #define SWAP (a, b, temp) {temp = a;  a = b;  b = température;  }
 void main ()
            {
               int i;
               int minx, maxx, Miny, maxy;
               int old_mode;
               int température;
               xres int, yres;
 fg_initpm ();
               fg_getmode old_mode = ();
               fg_setmode (fg_automode ());
 xres = fg_getmaxx () + 1;
               yres = fg_getmaxy () + 1;
 for (i = 0; i <RECTANGLES; i ++) {
                  minx = rand ()% xres;
                  maxx = rand ()% xres;
                  Miny = rand ()% yres;
                  maxy = rand ()% yres;
                  if (minx> maxx)
                     SWAP (minx, maxx, temp);
                  if (Miny> maxy)
                     SWAP (Miny, Maxy, temp);
                  fg_setcolor (rand ()% 16);
                  fg_rect (minx, maxx, Miny, maxy);
                  }
 fg_setmode (old_mode);
               fg_reset ();
            }


Rectangles carnet

 Fastgraph comprend quatre routines pour dessiner des rectangles non remplis.  le

routine fg_box dessine un rectangle vide dans l'espace de l'écran, en ce qui concerne les limites d'écrêtage, en utilisant la couleur actuelle. Les arguments à fg_box sont les mêmes que ceux pour fg_rect. La profondeur des bords du rectangle est un pixel par défaut, mais vous pouvez modifier la profondeur en appelant fg_boxdepth. La routine fg_boxdepth attend deux arguments. Le premier argument est la largeur des côtés gauche et droit du rectangle, tandis que le second est la hauteur de ses faces supérieure et inférieure. Une fois que vous appelez fg_boxdepth, fg_box attire tous les rectangles non remplis en utilisant les valeurs de profondeur spécifiées dans l'appel le plus récent à fg_boxdepth. Les fonctions de fg_getxbox et fg_getybox renvoient respectivement les réglages de profondeur de la boîte horizontale et verticale, tel que défini dans l'appel le plus récent à fg_boxdepth. Contrairement à fg_rect, fg_box n'a aucun effet en mode vidéo de texte. L'analogue de routine de l'espace du monde est fg_boxw.

 Exemple 6-12 est le même que l'exemple 11.06, mais non rempli à la place tire

rectangles de solides. Le programme utilise fg_box pour dessiner le rectangle et chaque fg_boxdepth pour définir la profondeur de rectangle en trois pixels dans chaque direction.

 Chapitre 6: Fundamentals graphiques 111


Notez que vous ne devez pas appeler fg_boxdepth pour chaque rectangle si vous voulez tous avoir la même profondeur.

 Exemple 6-12.
 #include <fastgraf.h>
            void main (void);
 #define RECTANGLES 200
            #define SWAP (a, b, temp) {temp = a;  a = b;  b = température;  }
 void main ()
            {
               int i;
               int minx, maxx, Miny, maxy;
               int old_mode;
               int température;
               xres int, yres;
 fg_initpm ();
               fg_getmode old_mode = ();
               fg_setmode (fg_automode ());
               fg_boxdepth (3,3);
 xres = fg_getmaxx () + 1;
               yres = fg_getmaxy () + 1;
 for (i = 0; i <RECTANGLES; i ++) {
                  minx = rand ()% xres;
                  maxx = rand ()% xres;
                  Miny = rand ()% yres;
                  maxy = rand ()% yres;
                  if (minx> maxx)
                     SWAP (minx, maxx, temp);
                  if (Miny> maxy)
                     SWAP (Miny, Maxy, temp);
                  fg_setcolor (rand ()% 16);
                  fg_box (minx, maxx, Miny, maxy);
                  }
 fg_setmode (old_mode);
               fg_reset ();
            }


 Les fg_boxx et fg_boxxw routines sont l'espace de l'écran et de l'espace du monde

versions "exclusives ou" des routines boîte de dessin. Ils simplifient l'affichage des boîtes rubberband (rectangles creux qui se déplacent en réponse à des frappes ou des mouvements de la souris) parce que le dessin d'un objet en mode XOR fait apparaître, mais le dessin à nouveau dans la même position et la même couleur restaure ce qui était sous l'objet à l'origine. Compte tenu de cette propriété utile, voici un aperçu de ce qui est nécessaire pour dessiner une zone de rubberband:

 1. Dessinez la boîte dans sa position initiale avec
              fg_boxx ou fg_boxxw. 

Guide de l'utilisateur 112 Fastgraph


 2. Attendez une réponse utilisateur qui signifie boîte
              mouvement.
        3. Utilisez fg_boxx ou fg_boxxw pour redessiner la case dans la
              même position que dans l'étape 1. Ceci restaure ce
              il était à l'origine.
        4. Dessinez la boîte dans sa nouvelle position avec fg_boxx ou
              fg_boxxw.
        5. Répétez les étapes 2, 3 et 4 jusqu'à ce que la boîte est pas
              plus nécessaire.
 Exemple 6-13 montre une simple utilisation de fg_boxx dans le 320x200 MCGA / VGA 256-

mode couleur (mode 19). Le programme remplit les moitiés gauche et droite de l'écran avec différentes couleurs, puis affiche une boîte XOR qui chevauche chaque moitié. Même si la boîte est dessinée dans la même couleur que la moitié droite, il est encore visible, car le dessin quelque chose dans un mode XOR (sauf dans la couleur 0) garantit qu'il sera visible sur son fond. Après une séquence de touches, le programme redessine la même boîte, ce qui bien sûr restaure ce qui était là en premier lieu.

 Exemple 6-13.
 #include <fastgraf.h>
                         void main (void);
 void main ()
                         {
                            int old_mode;
 fg_initpm ();
                            fg_getmode old_mode = ();
                            fg_setmode (19);
                            fg_setcolor (9);
                            fg_rect (0,159,0,199);
                            fg_setcolor (15);
                            fg_rect (160,319,0,199);
                            fg_waitkey ();
 fg_boxx (80,239,50,149);
                            fg_waitkey ();
                            fg_boxx (80,239,50,149);
                            fg_waitkey ();
 fg_setmode (old_mode);
                            fg_reset ();
                         }


Dithered Rectangles

 Procédé selon l'une alternance de pixels de couleurs différentes dans une région de la

zone d'affichage est appelé tramage. Cette technique est particulièrement utile dans les modes avec peu de couleurs, tels que les modes CGA et Hercules graphiques, parce que vous pouvez simuler des couleurs supplémentaires grâce à des utilisations efficaces de tramage. Fastgraph comprend deux routines pour dessiner des rectangles tramées, l'un pour l'espace de l'écran

 Chapitre 6: Fundamentals graphiques 113


et un pour l'espace mondial. Ni routine observe les limites d'écrêtage, ni n'affectent la position du curseur graphique.

 La routine de fg_drect dessine un rectangle tramé dans l'espace de l'écran.  Comme le

routine fg_rect, fg_drect requiert des arguments quatre entiers qui définissent respectivement le minimum x, maximum x, y minimum, et y coordonnées maximales de l'espace de l'écran du rectangle. Les coordonnées minimales doivent être inférieures ou égales aux coordonnées maximales, ou bien les résultats sont imprévisibles. Cependant, fg_drect nécessite également un cinquième argument qui définit la matrice de tramage, qui à son tour détermine le motif de pixels utilisé pour construire le rectangle tramé. La taille et la forme de la matrice de tramage dépendent du mode vidéo.

 La version de l'espace mondial de la routine tramée de dessin rectangle est

fg_drectw. Comme fg_drect, il nécessite quatre arguments qui définissent les extrémités du rectangle, et un cinquième argument qui définit la matrice de tramage.

 Comme mentionné précédemment, la taille et le format de la matrice de tramage sont

en fonction du mode vidéo. La matrice de tramage est un tableau de quatre octets dans tous les modes vidéo, à l'exception des modes 256 graphiques couleur (modes 19 à 27), où il est un tableau de huit octets. Ce tableau contient un motif de pixels qui fg_drect ou fg_drectw reproduit dans la zone du rectangle. La structure de la matrice de tramage imite étroitement la structure de mémoire vidéo dans chaque mode graphique.

 Le reste de cette section présentera quelques-unes spécifique en mode simple

Des exemples pour illustrer la structure de la matrice de tramage dans différents modes graphiques. Supposons que nous aimerions produire un «damier» de la lumière bleue et blanche pixels. Autrement dit, dans une ligne donnée d'un rectangle, pixels consécutifs alterne entre ces deux couleurs. En outre, le motif de rangées adjacentes sera décalée de sorte qu'il y aura toujours un pixel blanc au-dessus et au-dessous d'un pixel bleu clair, et vice versa. D'où ce modèle de pixel ressemblerait à quelque chose comme

 BWBW
                                   wbwb
                                   BWBW
                                   wbwb

où chaque B représente un pixel bleu clair, et chaque W représente un pixel blanc. Les exemples suivants décrivent la matrice de tramage qui pourrait être utilisé pour produire un motif de pixels dans chaque mode graphique.

CGA quatre couleurs Modes graphiques

 Les CGA-quatre couleurs graphiques modes (modes 4 et 5) utilisent quatre octets

tramage matrice qui Fastgraph traite comme un quatre-ligne par tableau à une colonne. Etant donné que chaque pixel dans ces modes nécessite deux bits de mémoire vidéo, chaque octet de la matrice de tramage contient quatre pixels. Ainsi, la représentation des pixels de la matrice de tramage apparaîtraient comme illustré sur la gauche; sa traduction en valeurs numériques apparaît à droite.


 [3] BWBW [3] 01 11 01 11
 [2] wbwb [2] 11 01 11 01

Guide de l'utilisateur 114 Fastgraph


 [1] BWBW [1] 01 11 01 11
 [0] wbwb [0] 11 01 11 01


Parce que ces modes ne proposent pas une couleur bleu clair, nous avons utilisé cyan clair (valeur de couleur 1 dans la palette 1) pour approcher bleu clair. Les pixels B traduisent ainsi la valeur de couleur 1, ou 01 binaire. Blanc est disponible en tant que valeur de couleur 3 dans la palette 1, de sorte que les pixels W traduisent la valeur de couleur 3, ou 11 binaire. Le hexadécimal équivalent de la valeur binaire 11011101 (pour les éléments de tableau [0] et [2]) est DD, et l'équivalent hexadécimal de la valeur binaire 01110111 (pour les éléments de tableau [1] et [3]) est 77. Comme le montre la exemple 6-12, ce sont précisément les valeurs attribuées aux éléments de la matrice de tramage.

 Exemple 6-14 mode 4 utilise pour afficher 50 pixels par 50 pixels tramée

rectangle dans le coin supérieur gauche de l'écran. La matrice de tramage représente le motif en damier bleu et blanc discuté dans le paragraphe précédent.

 Exemple 6-14.
 #include <fastgraf.h>
                      void main (void);
 void main ()
                      {
                         matrice char [4];
                         int old_mode;
 fg_initpm ();
                         fg_getmode old_mode = ();
                         fg_setmode (4);
 la matrice [0] = matrice [2] = 0xDD;
                         la matrice [1] = matrice [3] = 0x77;
                         fg_drect (0,49,0,49, matrice);
                         fg_waitkey ();
 fg_setmode (old_mode);
                         fg_reset ();
                      }


CGA Two-Color Mode graphique

 Le CGA (mode 6) en deux couleurs graphiques utilise un dithering de quatre octets

matrice qui Fastgraph traite comme un tableau à quatre rangées par une colonne, comme dans les autres modes CGA-quatre couleurs. Cependant, chaque pixel dans ce mode ne nécessite qu'un seul bit de mémoire vidéo, de sorte que chaque octet de la matrice de tramage contient huit pixels. Ainsi, la représentation des pixels de la matrice de tramage apparaîtraient comme illustré sur la gauche; sa traduction en valeurs numériques apparaît à droite.


 [3] BWBWBWBW [3] 1 0 1 0 0 1 0 1
                                      Chapitre 6: Fundamentals graphiques 115


 [2] WBWBWBWB [2] 1 0 1 0 1 0 1 0
 [1] BWBWBWBW [1] 0 1 0 1 0 1 0 1
 [0] WBWBWBWB [0] 1 0 1 0 1 0 1 0


Mode 6 évidemment ne propose pas de couleur bleu clair, nous avons donc utilisé le noir (valeur de couleur 0) à sa place. Les B pixels se traduisent donc à la valeur de couleur 0. Blanc est disponible en tant que valeur de couleur 1, de sorte que les pixels W traduisent la valeur de couleur 1. L'équivalent hexadécimal de la valeur binaire 10101010 (pour les éléments de tableau [0] et [2]) est AA et l'équivalent hexadécimal de la valeur binaire 01010101 (pour les éléments de tableau [1] et [3]) est de 55. Ainsi, pour faire exemple 6-14 run en mode 6, nous avons seulement besoin de changer l'argument fg_setmode 4-6 et modifier les valeurs de la matrice de tramage comme montré ici:


 la matrice [0] = matrice [2] = 0xAA;
                        la matrice [1] = matrice [3] = 0x55;


Tandy / PCjr 16-Color Mode graphique

 Le mode 16 couleurs graphique Tandy / PCjr (mode 9) utilise également quatre octets

tramage matrice qui Fastgraph traite comme un quatre-ligne par tableau à une colonne. Chaque pixel dans ce mode nécessite quatre bits de mémoire vidéo, de sorte que chaque octet de la matrice de tramage contient deux pixels seulement. Ainsi, la représentation des pixels de la matrice de tramage apparaîtraient comme illustré sur la gauche; sa traduction en valeurs numériques apparaît à droite.


 [3] BW [3] 1001 1111
 [2] WB [2] 1111 1001
 [1] BW [1] 1001 1111
 [0] WB [0] 1111 1001


Les B pixels se traduisent par une valeur de couleur 9 (bleu clair), ou 1001 binaire, et les pixels W traduisent la valeur de couleur 15 (blanc), ou 1111 binaire. L'équivalent hexadécimal de la valeur binaire 11111001 (pour les éléments de tableau [0] et [2]) est F9, et l'équivalent hexadécimal de la valeur binaire 10011111 (pour les éléments de tableau [1] et [3]) est 9F. Ainsi, pour faire exemple 6-14 run en mode 9, nous avons seulement besoin de changer l'argument fg_setmode 4-9 et modifier les valeurs de la matrice de tramage comme montré ici:


 la matrice [0] = matrice [2] = 0xF9;
                        la matrice [1] = matrice [3] = 0x9F; 

Guide de l'utilisateur 116 Fastgraph


Mode graphique Hercules

 La taille et le format de la matrice de tramage dans le mode graphique Hercules

(Mode 11) sont les mêmes que dans le mode à deux couleurs CGA (mode 6).

Hercules Low-Resolution Mode graphique

 La taille et le format de la matrice de tramage dans le bas Hercules

résolution graphique (mode 12) sont les mêmes que dans les CGA modes de quatre couleurs (modes 4 et 5). En ce qui concerne notre exemple en damier va, nous allons utiliser le noir (valeur de couleur 0) à la place de la lumière bleue, et en gras (valeur de couleur 3) au lieu de blanc. Ainsi, les B pixels se traduisent par 00 binaire, tandis que les pixels W traduisent à 11 binaire. Le hexadécimal équivalent de la valeur binaire 11001100 (pour les éléments de tableau [0] et [2]) est CC, et l'équivalent hexadécimal de la valeur binaire 00110011 (pour les éléments de tableau [1] et [3]) est 33. Ainsi, pour faire exemple 6-14 run en mode 12, nous avons seulement besoin de changer l'argument fg_setmode 4-12 et modifier les valeurs de la matrice de tramage comme montré ici:


 la matrice [0] = matrice [2] = 0xCC;
                        la matrice [1] = matrice [3] = 0x33;


EGA / VGA / SVGA 16 couleurs Modes graphiques

 Les modes EGA / VGA / SVGA 16 couleurs graphiques (modes 13 à 18, 28 et

29) utilisent une matrice de tramage de quatre octets qui Fastgraph traite comme un quatre-ligne par tableau à une colonne. Contrairement aux autres modes graphiques qui vous permettent de stocker des pixels de plusieurs couleurs dans la matrice de tramage, ces modes traitent la matrice de tramage comme un bitmap pour une couleur spécifique. Étant donné que chaque couleur dans le motif de tramage doit être stocké dans un bitmap séparé (qui est, dans une matrice de tramage séparée), vous devez appeler fg_drect une fois pour chaque couleur. En outre, vous devez utiliser fg_setcolor avant chaque appel à fg_drect pour définir la couleur utilisée avec la matrice de tramage.

 Dans tous les modes graphiques EGA / VGA / SVGA, chaque octet de la matrice de tramage est

un bitmap qui représente huit pixels. En utilisant notre exemple en damier familier, la représentation de pixel de la matrice de tramage apparaîtrait comme indiqué ici:


 [3] BWBWBWBW
 [2] WBWBWBWB
 [1] BWBWBWBW
 [0] WBWBWBWB


Traduire ce modèle à des valeurs numériques est simple. Il suffit de construire une matrice de tramage pour chaque couleur dans le motif (il y a deux couleurs dans cet exemple), où les pixels de la couleur actuelle se traduisent à 1, et d'autres pixels traduisent à 0. Dans notre exemple, la traduction pour les B pixels apparaît ci-dessous sur la gauche, tandis que la traduction pour les pixels W apparaît sur la droite.

 Chapitre 6: Notions de base 117 Graphiques


 [3] 1 0 1 0 1 0 1 0 [3] 1 0 1 0 0 1 0 1
 [2] 0 1 0 1 0 1 0 1 [2] 1 0 1 0 1 0 1 0
 [1] 1 0 1 0 1 0 1 0 [1] 0 1 0 1 0 1 0 1
 [0] 0 1 0 1 0 1 0 1 [0] 1 0 1 0 1 0 1 0


L'équivalent hexadécimal de la valeur binaire 01010101 est de 55, et l'équivalent hexadécimal de la valeur binaire 10101010 est AA. Comme on le voit dans l'exemple 15.06, ce sont précisément les valeurs attribuées aux éléments des matrices de tramage.

 Exemple 6-15 mode 13 utilise pour afficher le bleu notre lumière et blanc

motif damier. Notez que vous devez appeler fg_drect deux fois - une fois pour les pixels bleu clair (valeur de couleur 9), et encore pour les pixels blancs (valeur de couleur 15). Notez également comment fg_setcolor est utilisé avant chaque appel à fg_drect pour définir la couleur des pixels fg_drect affichera.

 Exemple 6-15.
 #include <fastgraf.h>
                      void main (void);
 void main ()
                      {
                         matrice char [4];
                         int old_mode;
 fg_initpm ();
                         fg_getmode old_mode = ();
                         fg_setmode (13);
 la matrice [0] = matrice [2] = 0x55;
                         la matrice [1] = matrice [3] = 0xAA;
                         fg_setcolor (9);
                         fg_drect (0,49,0,49, matrice);
 la matrice [0] = matrice [2] = 0xAA;
                         la matrice [1] = matrice [3] = 0x55;
                         fg_setcolor (15);
                         fg_drect (0,49,0,49, matrice);
                         fg_waitkey ();
 fg_setmode (old_mode);
                         fg_reset ();
                      }

Guide de l'utilisateur 118 Fastgraph


256 Couleur Modes graphiques

 Les modes graphiques 256 couleurs (modes 19 à 27) utilisent huit octets

tramage matrice qui Fastgraph traite comme un quatre-ligne par tableau à deux colonnes. Chaque pixel dans ces modes nécessite huit bits de mémoire vidéo, de sorte que chaque octet de la matrice de tramage contient qu'un seul pixel. Nous devons donc la matrice de tramage à deux colonnes pour produire un motif de tramage significatif. La représentation de pixel de la matrice de tramage apparaîtrait comme indiqué sur la gauche; sa traduction en valeurs numériques apparaît à droite.


 [6] BW [7], [6] 9 15 [7]
 [4] WB [5] [4] 15 9 [5]
 [2] BW [3] [2] 9 15 [3]
 [0] WB [1] [0] 15 9 [1]


Les B pixels se traduisent par une valeur de couleur 9 (bleu clair), et les pixels W traduisent la valeur de couleur 15 (blanc). Exemple 6-16 en mode 19 utilise pour dessiner notre motif en damier bleu clair et blanc.

 Exemple 6-16.
 #include <fastgraf.h>
           void main (void);
 void main ()
           {
              matrice char [8];
              int old_mode;
 fg_initpm ();
              fg_getmode old_mode = ();
              fg_setmode (19);
 la matrice [0] = matrice [3] = matrice [4] = matrice [7] = 15;
              la matrice [1] = matrice [2] = matrice [5] = matrice [6] = 9;
              fg_drect (0,49,0,49, matrice);
              fg_waitkey ();
 fg_setmode (old_mode);
              fg_reset ();
           }


Discours de clôture

 Il y a deux autres éléments importants relatifs à fg_drect et fg_drectw.

Ces articles appliquent quel que soit le mode graphique vidéo est utilisé.

 Tout d'abord, la matrice de tramage ne peut pas contenir des valeurs de couleurs virtuelles.  Cette

est, les valeurs de couleurs de pixels stockées dans la matrice de tramage doit être entre 0 et la valeur maximale de couleur correspondant au mode vidéo en cours. Si une valeur de couleur est

 Chapitre 6: Fundamentals graphiques 119


redéfini en utilisant fg_defcolor, Fastgraph ignore toujours la redéfinition et utilise plutôt la valeur réelle de la couleur. Notez que ce ne concerne pas les registres de palette ou vidéo registres du CAD, parce que dans ces cas, nous redéfinissons la couleur associée à une valeur de couleur et non la valeur de couleur elle-même.

 Deuxièmement, Fastgraph aligne la matrice de tramage à des lignes spécifiques de pixels.

Fastgraph dessine le rectangle tramé en commençant par la rangée de pixels spécifié par la limite inférieure du rectangle (le maximum coordonnée y fg_drect, ou le minimum coordonnée y fg_drectw) et procède à la hausse jusqu'à atteindre la limite supérieure du rectangle. Dans tous les cas la matrice de tramage utilisée par fg_drect et fg_drectw contient quatre lignes. Si nous laissons r représentent la ligne de pixel correspondant à la limite inférieure du rectangle, puis la première rangée utilisée dans la matrice de tramage est r modulo 4 (en supposant que les lignes de la matrice de tramage sont numérotés de 0 à 3). Cet alignement vous permet d'utiliser la même matrice de tramage dans de multiples appels à fg_drect et fg_drectw pour la construction d'un objet de rectangles tramées adjacents (par exemple, une zone en forme de L) et ont encore le match de motif de tramage où les rectangles se croisent.


Région Fill

 Fastgraph comprend des routines pour le remplissage des régions arbitraires.  Le fg_flood

et les routines de fg_paint remplissent une région avec la valeur de couleur actuelle en spécifiant un point dans l'intérieur de la région de l'espace de l'écran. La routine de fg_floodw et fg_paintw remplir aussi une région, mais ils exigent le point intérieur à exprimer dans l'espace mondial. Toutes les régions remplir routines ont deux arguments qui spécifient le (x, y) les coordonnées du point intérieur. Pour fg_flood et fg_paint, les arguments sont des quantités entières. Pour fg_floodw et fg_paintw, ils flottent des quantités ponctuelles. Aucun d'entre eux changer la position du curseur graphique. La différence entre la «inondation» et les versions "de peinture" de ces routines est simple: fg_flood et fg_floodw ne prolongeront pas la région de remplissage au-delà des limites d'écrêtage, tandis que fg_paint et fg_paintw ignorer les limites d'écrêtage. Par conséquent, fg_paint et fg_paintw sont nettement plus rapides.

 La région étant rempli doit être un polygone fermé dont la couleur limite est

différent de celui du point intérieur spécifié. La région peut contenir des trous (zones intérieures qui ne seront pas remplis). Fastgraph remplit la région en changeant chaque pixel intérieur dont la couleur est le même que le point intérieur spécifié, à la couleur actuelle. Si le point intérieur est déjà la couleur actuelle, la région de remplissage routines ne font rien. Il est important de noter fg_paint et fg_paintw ne pas traiter les bords de l'écran que les limites des polygones. Remplissage d'un polygone ouvert provoquera ces routines à se comporter de façon imprévisible. Ce n'est pas le cas avec fg_flood et fg_floodw aussi longtemps que les limites d'écrêtage ne sont pas au-delà des bords de l'écran.

 Exemple 6-17 illustre une utilisation simple de fg_paint dans un 320x200 graphiques

mode. Le programme fg_bestmode utilise pour sélectionner un mode vidéo disponible (si aucun mode graphique de 320x200 est disponible, le programme se termine). Après avoir établi le mode vidéo sélectionné, le programme utilise fg_move et fg_drawrel pour dessiner un rectangle creux de couleur 10 et un diamant creux de couleur 9. Le diamant est tracé au milieu du rectangle, ce qui en fait un trou par rapport au rectangle . Le programme laisse ces formes sur l'écran jusqu'à ce qu'une touche est enfoncée. Il appelle ensuite fg_paint pour remplir cette partie du rectangle à l'extérieur du diamant avec la couleur 10. Après avoir attendu une autre touche, le programme utilise à nouveau fg_paint pour remplir l'intérieur du diamant avec la couleur 15. Enfin, le Guide de l'utilisateur 120 Fastgraph


programme attend une autre touche, rétablit le mode vidéo original et attributs de l'écran, et retourne à DOS.

 Exemple 6-17.
 #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main (void);
 void main ()
             {
                int old_mode, new_mode;
 fg_initpm ();
                new_mode = fg_bestmode (320,200,1);
                if (new_mode <0) {
                   printf ( "Ce programme nécessite un 320 x 200»);
                   ( "mode graphique \ n".) printf;
                   sortie (1);
                   }
 fg_getmode old_mode = ();
                fg_setmode (new_mode);
 fg_setcolor (10);
                fg_move (100,50);
                fg_drawrel (120,0);
                fg_drawrel (0100);
                fg_drawrel (-120,0);
                fg_drawrel (0, -100);
 fg_setcolor (9);
                fg_move (160,80);
                fg_drawrel (30,20);
                fg_drawrel (-30,20);
                fg_drawrel (-30, -20);
                fg_drawrel (30, -20);
                fg_waitkey ();
 fg_setcolor (10);
                fg_paint (160,70);
                fg_waitkey ();
 fg_setcolor (15);
                fg_paint (160,100);
                fg_waitkey ();
 fg_setmode (old_mode);
                fg_reset ();
             }
                                      Chapitre 6: Fundamentals graphiques 121


Résumé des fondamentaux Routines graphiques

 Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

 FG_BOX dessine un rectangle vide dans l'espace de l'écran, par rapport à la

zone de découpage. La largeur des bords du rectangle est un pixel à moins changé avec la routine de fg_boxdepth.

 FG_BOXDEPTH définit la profondeur des rectangles dessinés avec l'affichage de la boîte

routines. La routine de fg_setmode initialise la profondeur de la boîte à un pixel.

 FG_BOXW dessine un rectangle vide dans l'espace du monde, par rapport à la

zone de découpage. La largeur des bords du rectangle est un pixel à moins changé avec la routine de fg_boxdepth.

 FG_BOXX dessine un rectangle vide dans l'espace de l'écran, par rapport à la

zone de découpage, en mode "ou exclusif". La largeur des bords du rectangle est un pixel à moins changé avec la routine de fg_boxdepth.

 FG_BOXXW dessine un rectangle vide dans l'espace du monde, par rapport à la

zone de découpage, en mode "ou exclusif". La largeur des bords du rectangle est un pixel à moins changé avec la routine de fg_boxdepth.

 FG_CIRCLE dessine un cercle vide dans l'espace de l'écran.  Le cercle est

centré sur la position du curseur graphique.

 FG_CIRCLEF dessine un cercle rempli dans l'espace de l'écran.  Le cercle est centré

à la position du curseur graphique.

 FG_CIRCLEFW dessine un cercle rempli dans l'espace mondial.  Le cercle est centré

à la position du curseur graphique.

 FG_CIRCLEW dessine un cercle vide dans l'espace mondial.  Le cercle est

centré sur la position du curseur graphique.

 FG_CLPRECT dessine un (rempli) rectangle solide dans l'espace de l'écran, en ce qui concerne

à la zone de découpage.

 FG_CLPRECTW dessine un (rempli) rectangle solide dans l'espace mondial, en ce qui concerne

à la zone de découpage.

 FG_DASH dessine une ligne en pointillés des graphiques position du curseur à un

position absolue de l'espace de l'écran. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DASHREL dessine une ligne en pointillés des graphiques curseur position à une

position de l'espace de l'écran par rapport à lui. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DASHRW dessine une ligne en pointillés des graphiques curseur position à une

la position mondiale de l'espace par rapport à lui. Il permet également la position de destination de la nouvelle position du curseur graphique. Guide de l'utilisateur 122 Fastgraph


 FG_DASHW dessine une ligne en pointillés des graphiques position du curseur à un

position absolue de l'espace mondial. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAW dessine une ligne solide des graphiques position du curseur à un

position absolue de l'espace de l'écran. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAWREL dessine une ligne solide des graphiques curseur position à une

position de l'espace de l'écran par rapport à lui. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAWRELX dessine une ligne solide en mode "ou exclusif" des graphiques

la position du curseur vers une position d'espace de l'écran par rapport à lui. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAWRW dessine une ligne solide à partir de la position du curseur graphique à un monde

l'espace position par rapport à elle. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAWRXW dessine une ligne solide en mode "ou exclusif" des graphiques

la position du curseur à une position de l'espace du monde par rapport à lui. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAWW dessine une ligne solide des graphiques position du curseur à un

position absolue de l'espace mondial. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAWX dessine une ligne solide en mode "ou exclusif" des graphiques

la position du curseur à une position d'espace d'écran absolu. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRAWXW dessine une ligne solide en mode "ou exclusif" des graphiques

la position du curseur à une position mondiale de l'espace absolu. Il permet également la position de destination de la nouvelle position du curseur graphique.

 FG_DRECT dessine un rectangle tramé dans l'espace de l'écran, sans tenir compte de

la zone de découpage. Le motif de tramage du rectangle est défini par une matrice de tramage dont le format dépend du mode vidéo utilisé.

 FG_DRECTW dessine un rectangle tramé dans l'espace du monde, sans tenir compte de

la zone de découpage. Le motif de tramage du rectangle est défini par une matrice de tramage dont le format dépend du mode vidéo utilisé.

 FG_ELLIPSE dessine une ellipse non remplie dans l'espace de l'écran.  L'ellipse est

centrée sur la position du curseur graphique, et sa taille est déterminée par les longueurs spécifiées des demi-axes.

 FG_ELLIPSEF dessine une ellipse remplie dans l'espace de l'écran.  L'ellipse est

centrée sur la position du curseur graphique, et sa taille est déterminée par les longueurs spécifiées des demi-axes.

 FG_ELLIPSEW dessine une ellipse non remplie dans l'espace mondial.  L'ellipse est

centrée sur la position du curseur graphique, et sa taille est déterminée par les longueurs spécifiées des demi-axes.

 Chapitre 6: Fundamentals graphiques 123


 FG_ELLIPSFW dessine une ellipse remplie dans l'espace mondial.  L'ellipse est

centrée sur la position du curseur graphique, et sa taille est déterminée par les longueurs spécifiées des demi-axes.

 FG_ERASE efface l'écran dans le texte ou les modes graphiques.
 FG_FILLPAGE remplit l'écran avec la couleur actuelle dans le texte ou

les modes graphiques.

 FG_FLOOD remplit une région fermée arbitraire avec la valeur de couleur actuelle,

en ce qui concerne les limites d'écrêtage. La région est définie en spécifiant un point de l'espace de l'écran dans son intérieur.

 FG_FLOODW remplit une région arbitraire fermée avec la valeur de couleur actuelle,

en ce qui concerne les limites d'écrêtage. La région est définie en spécifiant un point de l'espace mondial dans son intérieur.

 FG_GETCLIP renvoie les limites d'écrêtage de courant, tel que défini dans le plus

appel récent à fg_setclip.

 FG_GETPIXEL renvoie la valeur de la couleur d'un pixel spécifié.
 FG_GETXBOX retourne la largeur en pixels pour les bords gauche et droit de

rectangles creux dessinés avec des routines d'affichage de la boîte de Fastgraph.

 FG_GETXPOS retourne l'espace x écran de coordonnées du curseur graphique

position.

 FG_GETYBOX retourne la largeur en pixels pour les bords supérieur et inférieur de

rectangles creux dessinés avec des routines d'affichage de la boîte de Fastgraph.

 FG_GETYPOS renvoie l'espace de l'écran coordonnée y du curseur graphique

position.

 FG_INSIDE détermine si le point spécifié est à l'intérieur convexe donnée

polygone.

 FG_MOVE établit la position du curseur graphique à un écran absolu

point de l'espace.

 FG_MOVEREL établit la position du curseur graphique à un espace d'écran

point par rapport à la position actuelle.

 FG_MOVERW établit la position du curseur graphique à un point de l'espace mondial

par rapport à la position actuelle.

 FG_MOVEW établit la position du curseur graphique à un monde absolu

point de l'espace.

 FG_PAINT remplit une région arbitraire fermée avec la valeur de couleur actuelle,

sans respect des limites d'écrêtage. La région est définie en spécifiant un point de l'espace de l'écran dans son intérieur. Guide de l'utilisateur 124 Fastgraph


 FG_PAINTW remplit une région arbitraire fermée avec la valeur de couleur actuelle,

sans respect des limites d'écrêtage. La région est définie en spécifiant un point de l'espace mondial dans son intérieur.

 FG_POINT dessine un point (qui est, affiche un pixel) dans l'espace de l'écran.
 FG_POINTW dessine un point dans l'espace mondial.
 FG_POINTX dessine un point en mode "ou exclusif" dans l'espace de l'écran.
 FG_POINTXW dessine un point en mode "ou exclusif" dans l'espace mondial.
 FG_POLYEDGE définit si oui ou non comprend fg_polyfill tous les pixels situés

sur les bords droit et inférieur d'un polygone lors de l'élaboration des polygones convexes remplis.

 FG_POLYFILL dessine un polygone convexe rempli dans l'espace de l'écran.  Le polygone est

fermé si nécessaire. Par défaut, les pixels se trouvant sur les bords droit et inférieur du polygone ne sont pas inclus lors de l'élaboration du polygone. Ce comportement peut être modifié avec fg_polyedge.

 FG_POLYGON dessine un polygone vide dans l'espace de l'écran, en utilisant deux

coordonner des réseaux pour définir les sommets du polygone. Le polygone est fermé si nécessaire.

 FG_POLYGONW dessine un polygone dans l'espace non rempli de monde.  Il est le même que

fg_polygon, à l'exception de la coordination des tableaux contiennent des valeurs spatiales du monde.

 FG_POLYLINE dessine un polygone vide dans l'espace de l'écran, en utilisant un seul

coordonner ensemble pour définir les sommets du polygone. Le polygone est fermé si nécessaire.

 FG_POLYOFF définit l'espace de l'écran de décalage appliqué à chaque sommet pour

polygones dessinés avec fg_polyfill ou fg_polyline.

 FG_RECT dessine un (rempli) rectangle solide dans l'espace de l'écran ou de caractère

l'espace, sans tenir compte de la zone de découpage.

 FG_RECTW dessine un (rempli) rectangle solide dans l'espace du monde, sans égard

à la zone de découpage.

 FG_SETCLIP définit la zone de découpage dans l'espace de l'écran.  La coupure

la région est une zone rectangulaire à l'extérieur de laquelle certains graphiques sont supprimés.

 FG_SETCLIPW définit la zone de découpage dans l'espace mondial.



Chapitre 7


Affichage des caractères Routines Guide de l'utilisateur 126 Fastgraph


aperçu

 Une partie importante de tout programme est la capacité d'afficher du texte ou

d'autres caractères à l'écran. Fastgraph prend en charge deux jeux de caractères: le caractère matériel ou BIOS fixés disponibles avec chaque mode vidéo et caractère propre logiciel de Fastgraph défini pour les modes graphiques vidéo. Fastgraph / Light ne supporte pas le jeu de caractères du logiciel.

 Nous commencerons ce chapitre par un examen de l'espace de caractère, puis

discuter des détails au sujet des caractères matériels et logiciels. A la fin du chapitre, nous allons expliquer brièvement comment implémenter des caractères bitmap dans un programme. Pour simplifier les choses, les exemples de programmes présentés dans ce chapitre sont des exemples spécifiques au mode, et aucun test est effectué pour vérifier si le mode vidéo est disponible sur le système de l'utilisateur.


Espace de caractères

 Le système de coordonnées utilisé pour afficher des caractères matériels est appelé

espace de caractère. Il est le seul système de coordonnées disponibles dans les modes vidéo de texte, mais il est un système complémentaire de coordonnées que vous pouvez utiliser soit avec l'espace de l'écran ou de l'espace mondial dans les modes graphiques vidéo. un espace de caractère peut être considéré comme une grille de rangées et de colonnes, chaque cellule de la grille de maintien d'un caractère. Chaque cellule est identifiée par ses propres coordonnées (ligne, colonne) entiers. Les lignes et les colonnes sont numérotées à partir de zéro; l'origine est toujours le coin supérieur gauche de l'écran. Par exemple, dans le 80-colonne en mode vidéo 25-ligne, la (ligne, colonne) les coordonnées de l'écran coins sont présentés dans le schéma suivant.


 (0,0) (0,79)


 (24,0) (24,79)


Le numéro par défaut de lignes et de colonnes dépend du mode vidéo, comme indiqué dans le tableau suivant. Pour les modes graphiques, le tableau comprend également la largeur par défaut et la hauteur en pixels d'une cellule de caractère.

 Mode de Nombre de Nombre de Char.  Carboniser.
                         Colonnes Nombre de lignes Widthheight
 0 40 25
                            1 40 25
                            2 80 25
                            3 80 25
                            4 40 25 8 8
                            5 40 25 8 8
                            6 80 25 8 8
                            7 80 25
                            9 40 25 8 8
                           11 80 25 9 14
                           12 40 25 8 8
                                 Chapitre 7: Affichage des caractères Routines 127


 13 40 25 8 8
                           14 80 25 8 8
                           15 80 25 8 14
                           16 80 25 8 14
                           17 80 30 8 16
                           18 80 30 8 16
                           19 40 25 8 8
                           20 40 25 8 8
                           21 40 50 8 8
                           22 40 30 8 8
                           23 40 60 8 8
                           24 80 25 8 16
                           25 80 30 8 16
                           26 100 37 8 16
                           27 128 48 8 16
                           28 100 37 8 16
                           29 128 48 8 16


Hardware caractères

 caractères matériels sont disponibles dans tous les modes vidéo pris en charge.  Comme

expliqué dans le chapitre 5, les caractères en mode texte ont un attribut d'affichage qui définit leur couleur de premier plan, leur couleur de fond, et si elles clignotent ou non. caractères en mode graphique apparaissent dans une seule couleur, tel que déterminé par l'indice de couleur actuelle. Chapitre 5 a également expliqué comment fg_setattr et fg_setcolor les routines de Fastgraph définissent l'attribut ou de l'indice de couleur dans lequel les caractères matériels suivants apparaissent.

 Il est évidemment important de définir la couleur ou de l'attribut pour le matériel

caractères, mais il est tout aussi important de définir leur emplacement sur l'écran. Fastgraph dessine des caractères matériels à la position définie par le curseur de texte. Comme le curseur graphique, le curseur de texte ne sont pas un curseur dans le vrai sens, mais est tout simplement une paire d'espace de caractères (ligne, colonne) coordonne avec une signification particulière. La routine fg_setmode définit la position du curseur de texte sur les coordonnées spatiales de caractères (0,0), qui est bien sûr le coin supérieur gauche de la écran.2

 La fg_locate routine Fastgraph modifie la position du curseur de texte.  Il a

deux arguments entiers qui spécifient la (ligne, colonne) espace de caractère coordonnées de la nouvelle position. Les valeurs de ligne doit être comprise entre 0 et un de moins que le nombre de lignes de caractères disponibles. Les valeurs de la colonne doit être comprise entre 0 et un de moins que le nombre de colonnes de caractères disponibles.

 La routine fg_text est basique routine d'affichage de caractères de Fastgraph.  Il

affiche une chaîne de caractères de matériel, à partir de la position du curseur de texte, en utilisant l'attribut de couleur en cours (pour les modes de texte) ou indice de couleur (pour les modes graphiques). Si la chaîne atteint la dernière colonne dans une ligne, fg_text va envelopper la chaîne à la première colonne de la ligne suivante. En outre, fg_text laisse le curseur d'une colonne à droite du dernier caractère affiché (ou la première colonne de la ligne suivante si le dernier caractère apparaît ____________________

 (2) En réalité, il y a huit curseurs de texte, une pour chaque page vidéo.  le

routine fg_setmode initialise chaque position du curseur de texte à (0,0). Le chapitre suivant décrit plus en détail. Guide de l'utilisateur 128 Fastgraph


à la fin d'une rangée). Cette fonctionnalité permet aux appels successifs à fg_text pour afficher les chaînes adjacentes. Le premier argument de la routine fg_text est une chaîne de caractères de longueur arbitraire, et le second argument est une valeur entière qui spécifie le nombre de caractères à afficher à partir de cette chaîne.

 Exemple 7-1 illustre l'utilisation de fg_locate et fg_text dans le 80x25

mode texte de couleur (mode 3). Après avoir établi le mode vidéo et en faisant le curseur du BIOS invisible, le programme affiche quatre cordes avec des attributs différents. Les attributs sont sélectionnés en utilisant fg_setattr, et les cordes sont affichées par fg_text. La première chaîne apparaît en jaune (attributs 14,0,0) dans le coin supérieur gauche de l'écran; fg_locate est pas nécessaire parce que (0,0) est la position du curseur de texte par défaut établi par fg_setmode. La deuxième chaîne apparaît en vert clair (10,0,0) un espace vers la droite de la première chaîne. Sa position repose sur le fait fg_text laisse le curseur de texte placé un espace vers la droite du dernier caractère affiché (après le "w" de "jaune" dans ce cas). L'espace de premier plan dans «vert» laisse un espace entre les première et deuxième chaînes. De même, la troisième chaîne apparaît en clignotant rouge (12,0,1) un espace vers la droite de la deuxième chaîne.

 Le programme utilise ensuite fg_locate pour déplacer le curseur de texte à la partie inférieure gauche

coin de l'écran et affiche le "Appuyez sur une touche" chaîne. Cette chaîne est affichée avec une avant-plan rouge clair sur un fond gris (12,7,0). Les espaces supplémentaires autour de la chaîne prolongent la couleur de fond d'une position de caractère à gauche et à droite et font la chaîne plus attrayant visuellement. Enfin, une fois que vous appuyez sur une touche, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

 Exemple 7-1.
 #include <fastgraf.h>
                     void main (void);
 void main ()
                     {
                        int old_mode;
 fg_initpm ();
                        fg_getmode old_mode = ();
                        fg_setmode (3);
                        fg_cursor (0);
 fg_setattr (14,0,0);
                        fg_text ( "jaune", 6);
 fg_setattr (10,0,0);
                        fg_text ( "vert", 6);
 fg_setattr (12,0,1);
                        fg_text ( "clignotant", 9);
 fg_setattr (12,7,0);
                        fg_locate (24,0);
                        fg_text ( «Appuyez sur une touche.", 16);
                        fg_waitkey (); 
                                 Chapitre 7: Affichage des caractères Routines 129


 fg_setmode (old_mode);
                        fg_reset ();
                     }


 La routine fg_where récupère la position du curseur de texte dans ses deux

arguments entiers. Cette routine n'est pas utilisé aussi souvent que fg_locate et fg_text parce que plus souvent qu'autrement, votre programme sera connaître la position du curseur de texte implicitement, ou vous saurez à l'avance les endroits où le texte sera affiché. La routine fg_where prend deux arguments entiers passés par référence, et ces deux arguments reçoivent respectivement la position de la ligne et de la colonne actuelle du curseur de texte.

 Exemple 7-2 produit les mêmes résultats que l'exemple 7-1, mais il le fait d'une

peu différemment. Il utilise sa propre routine, put_string, pour afficher une chaîne à une ligne et la colonne spécifiée.La routine de put_string appelle simplement fg_locate pour établir la position du curseur de texte et appelle fg_text pour afficher la chaîne alors. Notez l'utilisation de la fonction de la bibliothèque C strlen pour déterminer la longueur de chaîne passée à fg_text. Exemple 7-2 fg_where utilise également pour récupérer les nouvelles positions du texte du curseur, qui sont ensuite transmis à put_string.

Exemple 7-2.
#include <fastgraf.h>
                   #include <string.h>
                  void main (void);
                  put_string void (char *, int, int);
void main ()
                   {
                     int old_mode;
                     int ligne, colonne;
fg_initpm ();
                     fg_getmode old_mode = ();
                     fg_setmode (3);
                     fg_cursor (0);
fg_setattr (14,0,0);
                     put_string ( "jaune", 0,0);
fg_setattr (10,0,0);
                     fg_where (et rangée, et colonne);
                     put_string ( «vert», ligne, colonne + 1);
fg_setattr (12,0,1);
                     fg_where (et rangée, et colonne);
                     put_string ( "clignotant", ligne, colonne + 1);
fg_setattr (12,7,0);
                     put_string ( «Appuyez sur une touche.", 24,0);
                     fg_waitkey ();
fg_setmode (old_mode);
                     fg_reset (); 

Guide de l'utilisateur 130 Fastgraph


 }
put_string void (string, ligne, colonne)
                  * String char;
                  int ligne, colonne;
                   {
                     fg_locate (ligne, colonne);
                     fg_text (string, strlen (string));
                   }


Parfois, vous voudrez peut-être changer l'attribut d'affichage du texte existant,

tels que lors de la création d'une ombre sur les bords d'une fenêtre pop-up. La fg_chgattr routine Fastgraph remplit cette fonction. Il applique l'attribut d'affichage de texte actuel (tel que défini dans l'appel le plus récent à fg_setattr ou fg_setcolor) à un certain nombre de caractères, à partir de la position du curseur de texte. Il laisse le curseur de texte d'une colonne à droite du dernier caractère modifié (ou la première colonne de la ligne suivante si le dernier caractère est à la fin d'une rangée). L'argument de la routine fg_chgattr spécifie le nombre de caractères à changer. Cette routine n'a pas d'effet dans les modes graphiques vidéo.

La fg_chgtext routine Fastgraph effectue quelque peu la fonction inverse

de fg_chgattr. Il affiche un nouveau texte, mais utilise les attributs d'affichage déjà affectés aux cellules de caractère où le texte apparaîtra. La routine de fg_chgtext prend les deux mêmes arguments que fg_text, affiche les caractères à partir de la position du curseur de texte, et laisse le curseur d'une colonne à droite du dernier caractère affiché. Comme fg_chgattr, fg_chgtext n'a pas d'effet dans les modes graphiques vidéo.

Exemple 7-3 illustre les fg_chgattr et fg_chgtext routines. Il fonctionne

dans le 80 colonnes en mode texte de couleur (mode 3), mais si nous changeons l'argument fg_setmode elle aussi irait dans le mode texte monochrome (mode 7). Le programme affiche d'abord le mot «bonjour» dans le coin supérieur gauche de l'écran, en utilisant un premier plan gris et attribut de fond noir. Après avoir attendu pendant une séquence de touches, le programme appelle fg_chgattr pour rendre le mot «bonjour» apparaît en vidéo inverse (qui est, un premier plan noir et gris attribut de fond). Après une deuxième séquence de touches, le programme fg_chgtext utilise pour changer le "h" de "bonjour" en majuscules. Suite à cela, le programme revient à DOS.

Exemple 7-3.
#include <fastgraf.h>
                        void main (void);
void main ()
                         {
                           int old_mode;
fg_initpm ();
                           fg_getmode old_mode = ();
                           fg_setmode (3);
                           fg_cursor (0);
fg_setattr (7,0,0);
                           fg_text ( "bonjour", 5); 
                                Chapitre 7: Affichage des caractères Routines 131


fg_waitkey ();
fg_locate (0,0);
                           fg_setattr (0,7,0);
                           fg_chgattr (5);
                           fg_waitkey ();
fg_locate (0,0);
                           fg_chgtext ( "H", 1);
                           fg_waitkey ();
fg_setmode (old_mode);
                           fg_reset ();
                         }


Vous pouvez également récupérer le caractère ou attribut stocké dans un spécifique

cellule de caractère. La fg_getchar routine Fastgraph récupère les valeurs de caractères, tandis que fg_getattr récupère les attributs de caractère. Les deux routines ont deux arguments entiers qui spécifient la (ligne, colonne) coordonnées de la cellule de caractère d'intérêt. Exemple 7-4 utilise fg_getchar et fg_getattr à lire le caractère et l'attribut stocké à la ligne 24, la colonne 0. Juste avant la sortie du programme, il affiche ces valeurs.

Exemple 7-4.
#include <fastgraf.h>
                     #include <stdio.h>
                    void main (void);
void main ()
                     {
                       int attr, la valeur;
                       int old_mode;
fg_initpm ();
                       fg_getmode old_mode = ();
                       fg_setmode (3);
                       fg_cursor (0);
fg_setattr (9,7,0);
                       fg_locate (24,0);
                       fg_text ( "Test", 4);
                       value = fg_getchar (24,0);
                       attr = fg_getattr (24,0);
                       fg_waitkey ();
fg_setmode (old_mode);
                       fg_reset ();
                       printf ( "% c% 2.2X \ n", la valeur, attr);
                     }


Si vous avez besoin de récupérer les caractères et les attributs d'un rectangle

domaine, il est plus efficace d'utiliser la routine de fg_getimage (décrit dans le chapitre 10) que d'appeler fg_getchar et fg_getattr à plusieurs reprises. Guide de l'utilisateur 132 Fastgraph


Affichage des caractères matériels en graphiques modes vidéo est différent de

faire en mode texte. Comme mode texte, nous pouvons toujours utiliser fg_text pour afficher les chaînes dans l'espace de caractère, ce qui bien sûr limite les endroits où les chaînes peuvent apparaître. modes graphiques offrent la possibilité d'afficher les chaînes par rapport à un pixel, et non pas seulement des cellules de caractères. Le fg_print et routines fg_justify sont prévus à cet effet. Pour comparer les deux méthodes d'affichage des chaînes dans les modes graphiques, commençons par un exemple de le faire avec fg_text.

Exemple 7-5 est similaire à l'exemple 7-1, mais il fonctionne dans le EGA amélioré

mode graphique (mode 16), au lieu d'un mode texte. Dans les modes graphiques, fg_cursor n'a aucun effet, donc nous avons omis à partir du programme. En outre, les caractères ne peuvent pas être affichés avec un attribut clignotant, donc nous avons omis les caractères clignotantes (on pourrait simuler clignoter par répétitivement afficher et de les effacer, mais cela dépasse le cadre de cet exemple). Parce que les caractères en mode graphique ont seulement une couleur de premier plan, nous avons eu pour simuler le fond gris de la «Appuyez sur une touche" chaîne en dessinant d'abord un rectangle où cette chaîne apparaît. Les différences entre les exemples 7-5 et 7-1 attente pour tout mode graphique vidéo, et pas seulement le mode 16.

Exemple 7-5.
#include <fastgraf.h>
                    void main (void);
void main ()
                     {
                       int old_mode;
fg_initpm ();
                       fg_getmode old_mode = ();
                       fg_setmode (16);
fg_setcolor (14);
                       fg_text ( "jaune", 6);
fg_setcolor (10);
                       fg_text ( "vert", 6);
fg_setcolor (7);
                       fg_rect (0127336349);
                       fg_setcolor (12);
                       fg_locate (24,0);
                       fg_text ( «Appuyez sur une touche.", 16);
                       fg_waitkey ();
fg_setmode (old_mode);
                       fg_reset ();
                     }


Maintenant, nous allons montrer comment afficher les graphiques des chaînes de mode en utilisant le plus

espace écran flexible système de coordonnées. La routine est identique à celui fg_print fg_text, mais il affiche une chaîne par rapport à la position du curseur graphique (qui est, dans l'espace de l'écran), plutôt que la position de l'espace de caractère établi avec fg_locate. Par défaut, fg_print affiche des chaînes de sorte que leur

Chapitre 7: Affichage des caractères Routines 133


coin inférieur gauche est à la position du curseur graphique. La routine fg_justify vous permet de modifier cette justification par défaut. Ses deux paramètres, et xjust yjust, contrôlent le positionnement de la chaîne autour de la position actuelle de graphiques, tels que résumés dans le tableau suivant:

la valeur de la valeur de la verticale horizontale
                xjust justification justification yjust
-1 -1 Inférieur gauche
                 -1 0 centre gauche
                 -1 1 en haut à gauche
                  0 -1 centre inférieur
                  Centre 0 0 centre
                  0 1 centre supérieur
                  1 -1 en bas à droite
                  1 0 centre-droit
                  1 1 en haut à droite

Toutes les autres valeurs de justification produisent des résultats indéfinis. Dans le contexte de la justification verticale, des moyens de justification inférieure du fond de chaque caractère sera à la position graphique y actuelle. justification supérieure signifie que le haut de chaque personnage sera à la position graphique y, tandis que la justification du centre signifie caractères seront centrés sur la situation graphique y. Les paramètres de justification par défaut (établies par fg_setmode) sont xjust = -1 et yjust = -1, et vous pouvez récupérer les paramètres de justification en cours avec les fonctions de fg_getxjust et fg_getyjust de Fastgraph. Comme fg_text, fg_print laisse le curseur graphique positionné juste au-delà du coin inférieur droit du dernier caractère affiché.

Ni fg_print ni fg_text effectue écrêtage. Il peut y avoir des moments,

cependant, lors de l'affichage des chaînes écrêtés est souhaitable, par exemple lors de l'affichage du texte dans une fenêtre fixe. Lorsque l'écrêtage est nécessaire, utiliser fg_printc ou fg_textc pour afficher des chaînes. Ces deux routines sont identiques en tous points à fg_print et fg_text, mais ils ne présentent pas de caractères se trouvant en dehors de la zone de découpage établi par fg_setclip ou fg_setclipw. En outre, si une partie d'un personnage est en dehors de la zone de découpage, fg_printc et fg_textc affichage seulement qu'une partie du personnage qui se situe dans la zone de découpage. Parce que l'écrêtage est uniquement pris en charge dans les modes graphiques vidéo, fg_textc est équivalente à fg_text lorsqu'il est utilisé en mode texte vidéo.

Exemple 7-6 illustre l'utilisation de fg_print et fg_justify pour afficher

texte justifié dans le mode graphique 640x480 16 couleurs VGA (mode 18). La première série d'appels à fg_move, fg_justify et fg_print afficher la chaîne "Fastgraph" justifié à gauche, centré, et justifié à droite contre la rangée supérieure de l'écran. La deuxième série de ces appels affiche également la chaîne dans ces positions, mais chacun est centré verticalement dans le milieu de l'écran. La dernière série affiche les cordes contre la rangée du bas de l'écran. Les neuf appels à fg_justify dans l'exemple 7-6 représentent tous les paramètres possibles de justification pour les chaînes affichées avec fg_print.

Exemple 7-6.
#include <fastgraf.h>
                        void main (void);
void main ()   

Guide de l'utilisateur 134 Fastgraph


 {
                           int old_mode;
fg_initpm ();
                           fg_getmode old_mode = ();
                           fg_setmode (18);
                           fg_setcolor (9);
                           fg_fillpage ();
                           fg_setcolor (14);
fg_move (0,0);
                           fg_justify (-1,1);
                           fg_print ( «Fastgraph», 9);
                           fg_move (320,0);
                           fg_justify (0,1);
                           fg_print ( «Fastgraph», 9);
                           fg_move (639,0);
                           fg_justify (1,1);
                           fg_print ( «Fastgraph», 9);
fg_move (0240);
                           fg_justify (-1,0);
                           fg_print ( «Fastgraph», 9);
                           fg_move (320,240);
                           fg_justify (0,0);
                           fg_print ( «Fastgraph», 9);
                           fg_move (639,240);
                           fg_justify (1,0);
                           fg_print ( «Fastgraph», 9);
fg_move (0479);
                           fg_justify (-1, -1);
                           fg_print ( «Fastgraph», 9);
                           fg_move (320,479);
                           fg_justify (0, -1);
                           fg_print ( «Fastgraph», 9);
                           fg_move (639,479);
                           fg_justify (1, -1);
                           fg_print ( «Fastgraph», 9);
                           fg_waitkey ();
fg_setmode (old_mode);
                           fg_reset ();
                         }


Exemple 7-7 montre un effet secondaire qui se produit lors de l'affichage

caractères dans les modes graphiques. Cet exemple utilise le mode graphique MCGA (mode 19) et affiche les deux chaînes de caractères dans le même emplacement. Si nous devions le faire en mode texte, la première chaîne disparaîtrait une fois nous avons affiché la deuxième chaîne (en supposant que la deuxième chaîne est pas plus courte que la première). Dans les modes graphiques, cependant, les parties de la première chaîne de caractères ne sont pas couverts par des caractères de la deuxième chaîne sont encore visibles. La raison pour laquelle cela peut ne pas être clair au début, mais rappelez-vous quand nous affichons des caractères dans les modes graphiques, nous ne sommes pas vraiment affichons des caractères, mais simplement une représentation de pixels des caractères. Fastgraph n'a aucun moyen de distinguer cette

Chapitre 7: Affichage des caractères Routines 135


pixels de tous les autres pixels, peu importe ce que la routine que nous utilisons pour l'affichage de la chaîne.

Exemple 7-7.
#include <fastgraf.h>
                        void main (void);
void main ()
                         {
                           int old_mode;
fg_initpm ();
                           fg_getmode old_mode = ();
                           fg_setmode (19);
fg_setcolor (14);
                           fg_text ( "jaune", 6);
                           fg_locate (0,0);
                           fg_setcolor (10);
                           fg_text ( "vert", 6);
                           fg_waitkey ();
fg_setmode (old_mode);
                           fg_reset ();
                         }


Pour éviter ce problème, la procédure recommandée pour l'affichage

caractères dans les modes graphiques est d'abord effacer la zone où le texte apparaîtra. La meilleure façon de le faire est d'utiliser fg_rect pour dessiner un rectangle dans la couleur de fond. Dans l'exemple 7-7, nous pourrions le faire en insérant les déclarations


fg_setcolor (0);
                            fg_rect (0,47,0,7);


immédiatement avant l'appel à fg_locate. Les paramètres passés à la routine de fg_rect représentent la région 48 de 8 pixel qui correspond aux premières cellules à six caractères de la ligne 0 dans les modes les graphiques 320x200.


Hauteur des caractères

En VGA et SVGA graphiques modes (modes 17 à 29), il est possible de changer

la hauteur des caractères affichée avec fg_print, fg_printc, fg_text et fg_textc. Par défaut, les caractères sont 16 pixels de haut dans les modes les graphiques VGA et SVGA (17, 18, 24 à 29) et 8 pixels de haut dans les modes graphiques MCGA et XVGA (19 à 23). La routine de fg_fontsize vous permet d'afficher les caractères du 8x8 du BIOS, 8x14 ou 8x16 polices dans l'un de ces modes. Son seul paramètre spécifie la hauteur de caractère en pixels; il doit être 8, 14 ou 16. Si la hauteur de caractère est une autre valeur ou si fg_fontsize est utilisé dans un mode vidéo numérotée 16 ou moins (qui est, dans un mode non VGA), rien ne se passe. Guide de l'utilisateur 136 Fastgraph


Lorsque nous changeons la hauteur de caractère avec fg_fontsize, le nombre de texte

lignes sur l'écran change en conséquence. Le tableau suivant indique le nombre de lignes de texte disponibles dans chaque mode vidéo pris en charge lorsque vous utilisez les différentes tailles de caractères. Les valeurs en gras représentent la taille de caractères par défaut et le nombre de lignes pour ce mode vidéo.

Mode Nombre de lignes avec
                              Nombre 8x8 8x14 8x16
17 60 34 30
                                18 60 34 30
                                19 25 14 12
                                20 25 14 12
                                21 50 28 25
                                22 30 17 15
                                23 60 34 30
                                24 50 28 25
                                25 60 34 30
                                26 75 42 37
                                27 96 54 48
                                28 75 42 37
                                29 96 54 48
Exemple 7-8 montre comment utiliser fg_fontsize pour activer le caractère 8x8

police dans le 640x480 mode graphique VGA 16-couleur (mode 18). Dans ce mode, les caractères sont normalement 16 pixels de haut, ce qui donne 30 lignes de caractères par écran. Lorsque nous utilisons la police de 8x8, ce qui augmente à 60 lignes parce que les personnages sont maintenant la moitié aussi grand qu'avant. Le programme d'exemple fg_text utilise pour afficher la chaîne "police 8x8 ROM" 60 fois, une fois dans chaque ligne.

Exemple 7-8.
#include <fastgraf.h>
                    void main (void);
void main ()
                     {
                       int old_mode;
                       int rangée;
fg_initpm ();
                       fg_getmode old_mode = ();
                       fg_setmode (18);
fg_setcolor (9);
                       fg_fillpage ();
                       fg_setcolor (15);
                       fg_fontsize (8);
pour (rang = 0; rangée <60; rangée ++) {
                          fg_locate (ligne, 34);
                          fg_text ( «ROM de polices 8x8", 12);
                           }
                       fg_waitkey ();
fg_setmode (old_mode); 
                                Chapitre 7: Affichage des caractères Routines 137


fg_reset ();
                     }


Routines de conversion

Dans le chapitre 4, nous avons introduit les routines de Fastgraph pour convertir

coordonnées entre le caractère d'espace et de l'espace de l'écran. Dans cette section, nous passerons en revue ces routines et présentons un exemple qui utilise certains d'entre eux.

Les fg_xalpha et fg_yalpha routines convertissent les coordonnées de l'espace écran pour

espace de caractère. La routine de fg_xalpha convertit un espace de coordonnées x écran à la colonne d'espace de caractère qui contient les coordonnées. De même, fg_yalpha convertit un espace d'écran coordonnée y à l'espace rangée de caractères qui contient les coordonnées.

Les fg_xconvert et fg_yconvert routines convertissent espace de caractère

coordonnées à l'espace de l'écran. La routine de fg_xconvert convertit une colonne d'espace de caractère à l'espace de l'écran de coordonnées de son pixel gauche. De même, fg_yconvert convertit un espace rangée de caractères à l'espace de l'écran de coordonnées de son sommet (numéro le plus bas) pixel.

Exemple 05.07 a montré comment afficher des caractères dans un mode graphique.

Parce que les personnages ne sont pas une couleur de fond dans les modes graphiques, cet exemple utilisé fg_rect pour simuler une couleur de fond en dessinant un rectangle gris avant d'afficher le texte. Il était nécessaire de déterminer les coordonnées d'écran des cellules de caractères afin que nous puissions passer les paramètres corrects pour fg_rect. En utilisant fg_xconvert et fg_yconvert, nous pouvons laisser Fastgraph calculer les coordonnées nécessaires à l'écran. Cette méthode a l'avantage supplémentaire de travailler dans un mode graphique, tandis que les coordonnées transmises à fg_rect dans l'exemple 7-5 ne fonctionnerait correctement dans un mode graphique 640x350. Exemple 7-9 montre comment nous pourrions étendre exemple 7-5 en utilisant fg_xconvert et fg_yconvert.

Exemple 7-9.
#include <fastgraf.h>
                    void main (void);
void main ()
                     {
                       int old_mode;
                       int minx, maxx, Miny, maxy;
fg_initpm ();
                       fg_getmode fg_old_mode = ();
                       fg_setmode (16);
fg_setcolor (14);
                       fg_text ( "jaune", 6);
fg_setcolor (10);
                       fg_text ( "vert", 6);
fg_setcolor (7);
                       minx = fg_xconvert (0); 

Guide de l'utilisateur 138 Fastgraph


maxx = fg_xconvert (16) - 1;
                       miny = fg_yconvert (24);
                       maxy = fg_yconvert (25) - 1;
                       fg_rect (minx, maxx, Miny, maxy);
                       fg_setcolor (12);
                       fg_locate (24,0);
                       fg_text ( «Appuyez sur une touche.", 16);
                       fg_waitkey ();
fg_setmode (old_mode);
                       fg_reset ();
                     }


logiciels caractères

caractères de logiciels, également appelés caractères d'AVC ou de caractères vectoriels

dans d'autres documents, ne sont sont disponibles dans les modes graphiques vidéo. Contrairement aux caractères matériels de taille fixe, vous pouvez afficher les caractères de logiciels dans toutes les dimensions, à un angle quelconque, et à une position quelconque. En outre, les caractères de logiciels sont espacés proportionnellement. Cependant, les caractères de logiciels prennent plus de temps pour dessiner que des caractères matériels font.

Fastgraph comprend deux polices de caractères du logiciel, appelé la police primaire

et la police de remplacement. La police primaire contient des lettres majuscules et minuscules, des nombres, la ponctuation et la plupart des autres caractères ASCII imprimables. La police alternative contient majuscules et minuscules lettres grecques et d'autres symboles mathématiques et scientifiques.

La routine Fastgraph fg_swchar affiche une chaîne de caractères de logiciels

dans l'index de couleur courante (tel que défini par l'appel le plus récent à fg_setcolor). La chaîne peut contenir tous les caractères de la police primaire, la police de remplacement, ou les deux. Vous pouvez afficher les caractères justifiés à gauche, centré ou justifié à droite par rapport à la position du curseur graphique. Tout comme fg_text met à jour la position du curseur de texte, fg_swchar définit la position graphique du curseur juste à droite du dernier caractère dessiné. Les caractères sont coupées en fonction de la zone de découpage de courant. En plus des caractères, la chaîne passée à fg_swchar peuvent également contenir des opérateurs pour la commutation des polices, soulignant, subscripting, ou en exposant caractères. Parce que fg_swchar utilise en interne les coordonnées spatiales du monde, vous devez appeler la routine de fg_initw à un certain point dans votre programme avant le premier appel à fg_swchar. Vous devez également créer un espace de système de coordonnées avec la routine de fg_setworld.

La routine de fg_swchar a trois arguments. Le premier argument est le

chaîne de caractères à afficher. Le second argument est une valeur entière qui spécifie le nombre de caractères dans la chaîne, y compris les caractères utilisés comme opérateurs spéciaux. Le troisième argument est une valeur entière qui détermine la position de la chaîne par rapport à la position du curseur graphique. Si cette valeur est négative, le coin en bas à gauche du premier caractère sera à la position du curseur graphique. Si elle est positive, le coin inférieur droit du dernier caractère sera à la position du curseur graphique. Si elle est nulle, la chaîne sera centrée horizontalement à la position du curseur graphique.

Chapitre 7: Affichage des caractères Routines 139


La taille des caractères du logiciel est déterminée par les valeurs passées à

fg_setsize, fg_setsizew et fg_setratio. La routine fg_setsize a un seul argument entier qui définit la hauteur des caractères de logiciels dans les unités spatiales de l'écran, tandis que fg_setsizew a un seul argument flottant point qui définit la hauteur dans les unités spatiales du monde. Si aucune de ces routines est appelé, Fastgraph utilisera sa hauteur de caractères par défaut d'une unité mondiale de l'espace. La routine de fg_setratio a un seul argument à virgule flottante qui définit le rapport d'aspect pour les personnages de logiciels. Le rapport d'aspect est le rapport de la largeur à la hauteur de caractère du caractère. Par exemple, un rapport d'aspect de 2,0 signifie que les caractères sont deux fois plus larges que hautes. Si fg_setratio est pas appelée, Fastgraph utilise son rapport d'aspect par défaut de 1.

Exemple 7-10 affiche tous les caractères dans les deux polices de caractères de logiciels.

Le programme utilise le mode EGA graphique amélioré (mode 16), mais il pourrait fonctionner dans un mode graphique en changeant l'argument fg_setmode. Après avoir établi le mode vidéo, le programme appelle fg_initw pour initialiser les paramètres de l'espace mondial de Fastgraph; cela est nécessaire puisque les logiciels routines de dessin de caractères utilisent en interne les coordonnées spatiales du monde. La déclaration suivante est un appel à fg_setworld qui établit un espace de système de coordonnées avec 0,01 monde unités d'espace par pixel. Suite à cela est un appel à fg_setsizew qui définit la hauteur de caractère 0,21 unités spatiales du monde, ou 21 pixels. Notez que nous aurions pu plutôt utilisé fg_setsize ici avec un argument entier de 21.

La prochaine partie du programme dessine les caractères de la police primaire sur

la moitié supérieure de l'écran. Après avoir fait cela, le programme dessine les polices de caractères de substitution sur la moitié inférieure. Dans chaque cas, il le fait avec fg_swchar. Par défaut, la chaîne passée à fg_swchar va produire des caractères de la police primaire. Cependant, vous pouvez insérer un caractère de retour de barre oblique (\) dans la chaîne pour basculer entre les deux polices. Ne pas oublier C et C ++ appliquer une signification particulière pour le caractère de retour de barre dans les chaînes, vous devez donc utiliser deux barres obliques inverses consécutives pour insérer une seule barre oblique inverse dans la chaîne.

Exemple 7-10.
#include <fastgraf.h>
           void main (void);
void main ()
            {
              int old_mode;
fg_initpm ();
              fg_getmode old_mode = ();
              fg_setmode (16);
              fg_initw ();
              fg_setworld (0.0,6.39,0.0,3.49);
              fg_setsizew (0,21);
fg_setcolor (15);
              fg_locate (0,26);
              fg_text ( "caractères de logiciels - police 1", 28);
fg_setcolor (10);
              fg_movew (0.0,3.1);
              fg_swchar ( "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 26, -1);
              fg_movew (0.0,2.8); 

Guide de l'utilisateur 140 Fastgraph


fg_swchar ( "abcdefghijklmnopqrstuvwxyz", 26, -1);
              fg_movew (0.0,2.5);
              fg_swchar ( "0123456789", 10, -1);
              fg_movew (0.0,2.2);
              fg_swchar ( "! \" # $% & '() * +, - / :; <=> [] ^ `{|} ~", 29, -1.?);
fg_setcolor (15);
              fg_locate (12,26);
              fg_text ( "caractères de logiciels - police 2", 28);
fg_setcolor (10);
              fg_movew (0.0,1.4);
              fg_swchar ( "\\ ABCDEFGHIJKLMNOPRSTUWXYZ", 25, -1);
              fg_movew (0.0,1.1);
              fg_swchar ( "\\ abcdefghijklmnoprstuwxyz", 25, -1);
              fg_movew (0.0,0.4);
              fg_swchar ( "\\ 012345678 # $% & () * + / <=> [] {}?", 27, -1);
              fg_waitkey ();
fg_setmode (old_mode);
              fg_reset ();
            }


Si vous comparez les chaînes de police primaires avec les chaînes de police de remplacement, vous verrez la police alternative contient moins de caractères. Par exemple, les lettres Q et V (soit majuscules ou minuscules) ont aucun caractère correspondant dans la police alternative. Vous pourriez avoir également remarqué la police primaire ne supporte pas l'ensemble de caractères ASCII imprimable. Tout caractère dans une chaîne passée à fg_swchar qui n'a pas un caractère correspondant dans la police courante affiche un caractère blanc.

En plus de l'opérateur de changement de police (le caractère de retour de barre oblique),

fg_swchar reconnaît trois autres opérateurs. L'opérateur superscript est une barre oblique inverse suivie d'un caret (\ ^). Il provoque le caractère suivant à apparaître comme un exposant. De même, l'opérateur d'indexation est une barre oblique inverse suivie d'un cas v inférieur (\ v); il provoque le caractère suivant à apparaître comme un indice. La taille des caractères en exposant et en indice est une moitié de la hauteur des autres caractères. L'opérateur de soulignement est le caractère de soulignement (_). Il provoque tous les caractères suivants dans la chaîne à être soulignés jusqu'à ce qu'un autre caractère de soulignement est trouvé, ou jusqu'à la fin de la chaîne. Lors de l'utilisation de ces opérateurs, assurez-vous de les inclure dans le cadre du compte de longueur de chaîne passée à fg_swchar.

Exemple 7-11 illustre l'utilisation de la sélection de la police, exposant,

indice, et de souligner les opérateurs avec fg_swchar. Encore une fois, parce que le caractère de retour de barre a une signification particulière en C et C ++, il faut utiliser deux barres obliques arrière consécutives pour représenter une seule barre oblique inverse dans la chaîne. Le programme affiche quatre cordes:

cos2 + sin2 = 1
                                     H2O
                                   U232
                          Un mot est souligné. 
                                Chapitre 7: Affichage des caractères Routines 141


Le symbole de thêta dans la première chaîne est produite par l'affichage du caractère "h" dans la police de remplacement. Notez un autre opérateur de sélection de police (\) apparaît immédiatement après le "h" pour revenir à la police primaire. La première chaîne comprend également les opérateurs en exposant (\ ^) pour afficher les exposants dans l'équation. La deuxième chaîne comprend un caractère indicé unique, tandis que la troisième chaîne montre comment afficher trois caractères indicés consécutifs. Enfin, la quatrième chaîne montre comment souligner les caractères.

Notez par exemple 7-11 utilise également fg_setratio. Les trois premières cordes sont

dessiné avec un rapport d'aspect de 2, ce qui en fait deux fois plus larges que hautes. La quatrième corde est tirée avec un rapport d'aspect de 1 (le rapport d'aspect par défaut pour les caractères Fastgraph logiciels), de sorte que la hauteur des caractères est la même que la largeur de caractère. En outre, les chaînes sont centrées au lieu de justifiés à gauche comme dans l'exemple précédent.

Exemple 7-11.
#include <fastgraf.h>
           void main (void);
void main ()
            {
              int old_mode;
fg_initpm ();
              fg_getmode old_mode = ();
              fg_setmode (16);
              fg_setcolor (10);
              fg_initw ();
              fg_setworld (0.0,6.39,0.0,3.49);
              fg_setratio (2.0);
              fg_setsizew (0,21);
fg_movew (3.2,3.0);
              fg_swchar ( "cos \\ ^ 2 \\ h \\ + sin \\ ^ 2 \\ h \\ = 1", 25,0);
fg_movew (3.2,2.0);
              fg_swchar ( "H \\ V2O U \\ v2 \\ v3 \\ v2", 18,0);
fg_movew (3.2,1.0);
              fg_setratio (1,0);
              fg_swchar ( "One _word_ est souligné.", 25,0);
              fg_waitkey ();
fg_setmode (old_mode);
              fg_reset ();
            }


La routine fg_setangle définit l'angle de rotation à laquelle le logiciel

caractères sont affichés. Son seul argument est une valeur en virgule flottante spécifiant l'angle, mesuré en degrés dans le sens antihoraire à partir de l'axe x positif. Si un programme dessine les personnages de logiciels avant d'appeler fg_setangle, Fastgraph utilisera son angle par défaut de zéro degré (qui est, les caractères seront orientés horizontalement). Guide de l'utilisateur 142 Fastgraph


Dans la plupart des programmes, la police de remplacement est pas nécessaire. Toutefois, si vous utilisez

la routine fg_swchar, Fastgraph comprendra les définitions de ces caractères dans le segment de données de votre programme. Pour éviter de gaspiller cet espace, Fastgraph comprend la routine de fg_swtext. La routine de fg_swtext est identique fg_swchar, sauf qu'il ne comprend pas la police de remplacement. Comme l'opérateur de sélection de police ne s'applique pas lorsque vous utilisez fg_swtext, la routine ignore tout simplement. Vous ne devez utiliser fg_swtext si ne pas utiliser fg_swchar. Si vous utilisez les deux routines, votre programme ne fonctionne toujours correctement, mais son segment de données contiendra une copie supplémentaire des définitions de polices primaires.

Exemple 7-12 illustre l'utilisation de fg_setangle et fg_swtext.  le

programme dessine une série de chaînes de la forme "degrés" nnn, où nnn est un multiple de 15, rayonnant à partir du centre de l'écran. Chaque chaîne apparaît à l'angle spécifié. Par exemple, la chaîne "15 degrés" est tiré à un angle de 15 degrés.

Exemple 7-12.
#include <fastgraf.h>
               #include <stdio.h>
              void main (void);
void main ()
               {
                 chaîne char [24];
                 angle int;
                 int old_mode;
fg_initpm ();
                 fg_getmode old_mode = ();
                 fg_setmode (16);
                 fg_setcolor (10);
                 fg_initw ();
                 fg_setworld (0.0,6.39,0.0,3.49);
                 fg_setsizew (0,21);
pour (angle = 0; angle <360; angle + = 15) {
                    fg_movew (3.2,1.75);
                    fg_setangle ((double) angle);
                    sprintf (string, "% 3d" degrés, angle);
                    fg_swtext (string, 16, -1);
                     }
                 fg_waitkey ();
fg_setmode (old_mode);
                 fg_reset ();
               }


La routine finale concernant les personnages de logiciels est fg_swlength, qui

retourne la longueur d'une chaîne de caractères spécifiée de logiciels dans les unités spatiales du monde. La longueur est retourné comme variable la valeur de fonction de point de la routine. La routine de fg_swlength a deux arguments - une chaîne de caractères de logiciels, et une valeur d'entier spécifiant le nombre de caractères dans la chaîne. Comme fg_swchar et fg_swtext, le nombre inclut les caractères spéciaux de l'opérateur.

Chapitre 7: Affichage des caractères Routines 143


Exemple 7-13 montre une utilisation typique de la routine de fg_swlength.  le

programme affiche la chaîne "bonjour là." en vert clair sur un fond gris au milieu de l'écran. Comme dans nos exemples de caractères de logiciels précédents, le programme utilise le mode 16 et effectue les initialisations nécessaires pour utiliser des caractères de logiciels en premier. À la suite de cela, le programme fg_swlength utilise pour calculer la longueur de monde unités spatiales de la chaîne. Notez que nous avons ajouté des caractères blancs à chaque extrémité de la chaîne passée à fg_swlength; ce qui augmente la longueur de la chaîne réelle et donnera effectivement le rectangle gris une frontière étendue sur ses côtés gauche et droit. La longueur de la chaîne renvoyée par fg_swlength est multiplié par 0,5, ce qui donne la distance par rapport au centre de l'écran de chaque côté du rectangle. Le programme utilise ensuite cette valeur pour calculer le minimum et le maximum x coordonnées transmises à fg_rectw. Après avoir dessiné le rectangle gris, le programme fg_swtext utilise pour dessiner la chaîne de caractères de logiciels dans le milieu de l'écran. Il attend ensuite une touche avant de restaurer les attributs d'origine en mode vidéo et d'écran et de revenir à DOS.

Exemple 7-13.
#include <fastgraf.h>
             void main (void);
void main ()
              {
                int old_mode;
                deux demi;
fg_initpm ();
                fg_getmode old_mode = ();
                fg_setmode (16);
                fg_initw ();
                fg_setworld (0.0,6.39,0.0,3.49);
                fg_setsizew (0,21);
fg_setcolor (7);
                moitié = fg_swlength ( «Bonjour»., 14) * 0,5;
                fg_rectw (3,2-moitié, 3,2 + moitié, 1.6,1.9);
fg_setcolor (10);
                fg_movew (3.2,1.65);
                fg_swtext ( «Bonjour»., 12,0);
                fg_waitkey ();
fg_setmode (old_mode);
                fg_reset ();
              }


Personnages bitmap

caractères bitmap combinent les propriétés du matériel et des logiciels

personnages.Comme les caractères matériels, ils sont d'une taille fixe, mais ils sont presque toujours plus attrayant. Parce qu'ils ne sont pas évolutifs, ils font 144 Guide de l'utilisateur Fastgraph


pas besoin d'arithmétique en virgule flottante, et donc ils sont beaucoup plus rapides que les caractères de logiciels.

Fastgraph ne fait aucune disposition spéciale pour les caractères bitmap parce qu'il

les traite comme si elles étaient une autre image bitmap. Par exemple, pour utiliser un cinq-pixel par pixel cinq police bitmap, vous pouvez construire des caractères comme montré ici, puis stocker ces représentations dans un tableau d'image.

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

La routine d'affichage d'image fg_drawmap et fg_drwimage, discuté dans le chapitre 10, pourraient alors être utilisés pour afficher des caractères spécifiques de la matrice d'image. En outre, les Fastgraph / Fonts add-on produit simplifie grandement l'ajout du support de police bitmap aux applications Fastgraph.


Résumé de l'affichage de caractères Routines

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

FG_CHGATTR applique l'attribut d'affichage de texte en cours à un nombre donné

de caractères démarrant à la position du curseur de texte. Cette routine laisse le curseur de texte d'une colonne à droite du dernier caractère modifié (ou la première colonne de la ligne suivante si le dernier caractère est à la fin d'une rangée). Elle n'a aucun effet dans les modes graphiques vidéo.

FG_CHGTEXT affiche une chaîne de caractères de matériel, à partir du texte

la position du curseur, en utilisant les attributs d'affichage de texte existants. Cette routine laisse le curseur de texte d'une colonne à droite du dernier caractère affiché (ou la première colonne de la ligne suivante si le dernier caractère est à la fin d'une rangée). Elle n'a aucun effet dans les modes graphiques vidéo.

FG_FONTSIZE permet au 8x8, 8x14, ou la police de caractères BIOS 8x16 ROM pour

chaînes affichées avec fg_print et fg_text. Cette routine n'a de sens que dans les modes VGA et SVGA graphiques vidéo.

    FG_GETATTR renvoie l'attribut de caractère stockée à la valeur spécifiée 

position sur la page vidéo active. Elle n'a aucun effet dans les modes graphiques vidéo.

 FG_GETCHAR renvoie la valeur de caractères stockée à la position spécifiée

sur la page de la vidéo active. Elle n'a aucun effet dans les modes graphiques vidéo.

 FG_GETXJUST renvoie la justification horizontale actuelle pour la mise en

chaînes affichées avec fg_print ou fg_printc.

 FG_GETYJUST renvoie la justification verticale réglage actuel pour

chaînes affichées avec fg_print ou fg_printc.

 Chapitre 7: Affichage des caractères Routines 145


 FG_JUSTIFY définit les paramètres de justification horizontale et verticale pour

chaînes affichées avec fg_print ou fg_printc.

 FG_LOCATE établit la position du curseur de texte pour la page de la vidéo active.
 FG_PRINT affiche une chaîne de caractères de matériel, par rapport à la

graphiques position du curseur, en utilisant l'indice de couleur actuelle. Par défaut, les chaînes sont affichées de telle sorte que la rangée du bas du premier caractère est à la position graphique actuelle. Au retour, le curseur graphique est positionné juste à droite du dernier caractère affiché.

 FG_PRINTC est une version de fg_print qui effectue écrêtage.
 FG_SETANGLE définit l'angle ou l'orientation à laquelle les caractères de logiciels

sont affichés. L'angle est mesuré en degrés dans le sens antihoraire à partir de l'axe x positif.

 FG_SETATTR établit le courant attribut d'affichage de texte en texte vidéo

modes. Cette routine n'a pas d'effet dans les modes graphiques vidéo.

 FG_SETCOLOR établit l'indice de couleur actuelle (qui peut être un virtuel

indice de couleur dans les modes graphiques). Dans les modes de texte, la routine fg_setcolor propose une autre méthode pour établir l'attribut d'affichage de texte en cours.

 FG_SETRATIO définit le rapport d'aspect pour les caractères de logiciel.  l'aspect

le rapport est le rapport de la largeur à la hauteur de caractère du caractère.

 FG_SETSIZE définit la hauteur des caractères de logiciels dans l'espace de l'écran

unités.

 FG_SETSIZEW définit la hauteur des caractères de logiciels dans l'espace mondial

unités.

 FG_SWCHAR affiche une chaîne de caractères de logiciels utilisant le courant

indice de couleur. La chaîne peut être justifié à gauche, centré ou justifié à droite par rapport à la position du curseur graphique. La chaîne passée à fg_swchar peut contenir des opérateurs spéciaux qui permettent la commutation entre les polices, le soulignement, en exposant, ou subscripting. Cette routine n'a aucun effet en mode texte vidéo.

 FG_SWLENGTH retourne la longueur en monde unités spatiales d'une chaîne de

caractères de logiciels.

 FG_SWTEXT est une version réduite de la routine de fg_swchar.  Ce ne est pas

inclure les définitions de caractères de police de remplacement et nécessite donc moins de mémoire que fg_swchar.

 FG_TEXT affiche une chaîne de caractères de matériel, à partir du texte

la position du curseur, en utilisant l'attribut de couleur en cours (pour les modes de texte) ou indice de couleur (pour les modes graphiques). Cette routine laisse le curseur de texte d'une colonne à droite du dernier caractère affiché (ou la première colonne de la ligne suivante si le dernier caractère est à la fin d'une rangée).

 FG_TEXTC est une version de fg_text qui effectue écrêtage lorsqu'il est exécuté dans

graphiques modes vidéo. En mode texte, fg_textc équivaut à fg_text. Guide de l'utilisateur 146 Fastgraph


 FG_WHERE récupère les numéros de ligne et de colonne du curseur de texte

position.

 Coordonnées FG_XALPHA et FG_YALPHA convertir l'espace de l'écran à caractère

espace.

 FG_XCONVERT et FG_YCONVERT convertir les coordonnées d'espace de caractères à l'écran

espace.



chapitre 8


Pages vidéo et le Guide virtuel Tampons 148 Fastgraph utilisateur


aperçu

 La quantité de mémoire nécessaire pour stocker un plein écran d'information est

appelé une page vidéo (ou parfois tout simplement une page). Fastgraph offre une variété de types de pages, y compris les pages physiques, pages virtuelles, des pages étendues et pages logiques. En outre, les tampons virtuels vous permettent de définir des blocs arbitraires de la mémoire conventionnelle et les traiter comme si elles étaient de mémoire vidéo. Ce chapitre discutera pages vidéo et les tampons virtuels en détail, ainsi que les routines Fastgraph pour les gérer.


Pages physiques et virtuelles Pages

 Pages qui utilisent la mémoire qui se trouve sur la carte vidéo sont appelés

pages physiques ou vraies pages. Le nombre de pages physiques disponibles dépend du mode vidéo et la quantité de mémoire résidente sur la carte vidéo de l'utilisateur. Tous les modes vidéo ont au moins une page physique. Dans certains modes vidéo, Fastgraph peut allouer disponible mémoire vive (RAM) et de traiter cette mémoire comme une page vidéo. Pages qui utilisent RAM standard dans ce sens sont appelés pages virtuelles. Du point de vue d'un programmeur, pages virtuelles sont essentiellement identiques aux pages physiques.

 Le tableau suivant indique le nombre de pages physiques dans chaque vidéo

mode. Il indique également si oui ou non les modes vidéo spécifiques prennent en charge les pages virtuelles.

 Page Mode Taille physique virtuelle
    Description Numéro dans Bytes Pages Pages
 0 40 colonne texte de couleur 2000 8 no
      1 40 colonne texte de couleur 2000 8 no
      2 80 colonne texte de couleur 4000 4 pas
      3 80 colonne texte de couleur 4000 4 pas
      4 320x200x4 CGA graphiques 16.000 1 oui
      5 320x200x4 CGA graphiques 16.000 1 oui
      6 640x200x2 CGA graphiques 16.000 1 oui
      7 80 colonnes texte monochrome 4000 1 oui
      9 320x200x16 Tandy graphiques 32.000 1 oui
      11 720x348 Hercules graphiques 31,320 2 oui
      12 320x200 Hercules graphiques 31,320 2 oui
      13 320x200x16 graphiques EGA 32000 8 pas
      14 640x200x16 graphiques EGA 64.000 4 pas
      15 640x350 EGA mono graphiques 56.000 2 pas
      16 640x350x16 graphiques EGA 112.000 2 pas
      17 640x480x2 MCGA / VGA graphiques 38.400 1+ pas
      18 640x480x16 graphiques VGA 153,600 1+ pas
      19 320x200x256 MCGA graphiques 64.000 1 oui
      20 320x200x256 XVGA graphiques 64.000 4 pas
      21 320x400x256 XVGA graphiques 128.000 2 pas
      22 320x240x256 XVGA graphiques 76.800 3+ pas
      23 320x480x256 XVGA graphiques 153,600 1+ pas
      24 640x400x256 graphique SVGA 256.000 4 pas
      25 640x480x256 graphique SVGA 307.200 2 pas
      26 800x600x256 SVGA graphiques 480.000 2 pas
      27 1024x768x256 graphique SVGA 786.432 1+ pas
                            Chapitre 8: Pages vidéo et Virtual Tampons 149


 28 800x600x16 graphique SVGA 240.000 4 pas
      29 1024x768x16 graphique SVGA 393,216 2 pas

Ce tableau suppose l'adaptateur vidéo a 256K de mémoire vidéo installée pour les modes EGA et VGA, et 1 Mo de mémoire vidéo pour les modes SVGA. Pour les cartes de mémoire vidéo moins, le nombre de pages physiques est réduit proportionnellement. En d'autres termes, un 64K EGA a deux pages vidéo disponibles au lieu de huit en mode 13. De même, un 512K SVGA a une page au lieu de deux dans les modes 25 et 26, et ne serait pas en charge le mode 27. Le tableau suivant résume le nombre des pages vidéo disponibles en modes graphiques SVGA pour les cartes vidéo avec 256K, 512K, 768K et 1 Mo de mémoire vidéo installés.

 Mode Nombre de pages avec ...
                     Résolution numéro 256K 512K 768K 1MB
 24 640x400x256 1 + 2 3 4
                       25 640x480x256 0 1+ 1+ 2
                       26 800x600x256 0 1+ 1+ 2
                       27 1024x768x256 0 0 1 1+
                       28 800x600x16 1+ 2 3 4
                       29 1024x768x16 0 1+ 1+ 2
 Dans les deux tableaux précédents, notez que le nombre de pages physiques

certains modes vidéo est suivie par un symbole plus. Dans ces modes, il y a une page vidéo partielle supplémentaire disponible. Pour les modes 17, 18, et 23, il y a une page entière (page 0) plus une page partielle de 320 rangées de pixels (page 1). Pour le mode 22, il y a trois pages pleines physiques (numérotés de 0 à 2), plus une page partielle de 80 rangées de pixels (page 3). Pour le mode 27, il y a une page entière (page 0) plus une page partielle de 256 rangées de pixels (page 1) sur une carte 1MB SVGA. Vous pouvez utiliser en toute sécurité les pages partielles aussi longtemps que vous ne référencez pas de lignes de pixels au-delà de leur dernière ligne disponible. Cependant, vous ne pouvez pas faire une page vidéo partielle de la page visuelle.

 Dans SVGA graphiques modes (modes 24 à 29), les pages vidéo doivent commencer à 256K

limites pour maintenir la compatibilité entre les différents chipsets SVGA. Il en résulte dans la mémoire vidéo non utilisé à la fin d'une page. Par exemple, les pages en mode 26 nécessitent 480.000 octets de mémoire vidéo. Sur une carte 1MB SVGA, les deux pages commenceront à 0 et 524.288 (512K). Ainsi, il y a 44,288 (524,288 moins 480,000) de mémoire vidéo utilisé octets à la fin de chaque page. Avec 800 pixels (et donc 800 octets) par ligne de l'écran, cela signifie que chaque page a un supplément de 55 rangées de pixels par page. La taille réelle de la page est donc 800x655, avec les 600 premières lignes affichées. De même, la taille de la page en mode 25 est 640x819, les 480 premières lignes affichées.

 pages physiques sont numérotées à partir de zéro.  Par exemple, il y a quatre

pages vidéo physiques disponibles en mode 3, et ils sont numérotés de 0 à 3. Les pages virtuelles sont numérotées à 63 n, où n est le nombre de pages physiques dans ce mode. Par exemple, il y a deux pages physiques (numérotées de 0 et 1) et 62 pages virtuelles (numérotées 2 à 63) en mode 11. Remarque seuls modes 4 à 12 et le mode 19 offre des pages virtuelles, et la quantité de mémoire conventionnelle dans le mode de système limite généralement le nombre de pages virtuelles disponibles (ceci est particulièrement vrai en mode 19 en raison de la grande taille de la page). Guide de l'utilisateur 150 Fastgraph


Pages ayant une signification particulière

 Il y a trois pages de vidéo qui ont une signification particulière à Fastgraph.  le

la page visuelle, comme on peut le deviner, est la page vidéo visible sur l'écran de l'utilisateur. La page active est la page de vidéo à laquelle Fastgraph écrit du texte ou des informations graphiques. La page cachée n'a de sens que pour quelques routines de Fastgraph et sera discuté spécifiquement dans le contexte de ces routines. Les fg_setmode ensembles de routine tous les trois de ces pages à la page 0, et il n'a pas d'importance si ces pages sont physiques ou virtuels.

 L'une des caractéristiques les plus utiles de multiples pages de vidéo (soit physique

ou virtuel) est la capacité à construire une image de texte ou des graphiques hors de l'écran (qui est, sur une page vidéo en plus la page visuelle). Puis, une fois l'image est prête, nous pouvons soit le transférer à la page visuelle, ou faire la page sur laquelle l'image réside la page visuelle. Cette fonctionnalité est particulièrement utile dans l'animation, car il affiche une image instantanément au lieu de mettre à jour visiblement l'écran tout en produisant l'image.


Quelques exemples simples

 Dans cette section, nous allons présenter six variantes d'un programme simple qui

utilise quatre pages vidéo. Le programme remplit chaque page de la vidéo avec un rectangle, puis affiche le texte contenant le numéro de page de la vidéo dans le centre de chaque page. Les deux premiers exemples exécuter en mode texte ou des graphiques vidéo spécifique et utilisent uniquement des pages physiques. Les deux exemples suivants fonctionnent également en mode texte ou des graphiques vidéo spécifique, mais ils utilisent aussi des pages virtuelles. Les deux derniers exemples sont plus généraux et courir dans plusieurs modes vidéo. Vous pouvez bien sûr écrire un programme qui fait essentiellement la même chose que les exemples de cette section sans utiliser plusieurs pages vidéo. Toutefois, pour utiliser l'affichage d'image et d'animation des routines de Fastgraph efficacement, vous devez d'abord comprendre le concept de pages vidéo.

 Avant de poursuivre, nous devons introduire la Fastgraph routines fg_setpage

et fg_setvpage. La routine fg_setpage définit la page vidéo active, ce qui provoque Fastgraph pour mettre du texte suivant et sortie graphique sur cette page. La routine fg_setvpage définit la page vidéo visuel affiché sur l'écran. Les deux routines prennent un seul argument entier entre 0 et 63 qui spécifie le numéro de la page vidéo. Il n'a pas d'importance si la page vidéo de référence est une page physique ou une page virtuelle. Comme mentionné précédemment, fg_setmode rend la page 0 la page de la vidéo active et visuelle.

 Exemple 8-1 utilise quatre pages vidéo (numérotés de 0 à 3) dans les 40 colonnes

mode texte couleur (mode 1). Le programme des premiers appels fg_testmode pour vérifier la disponibilité du mode vidéo demandé lorsqu'il est utilisé avec quatre pages vidéo. Si elle est disponible, le programme appelle fg_setmode pour établir que le mode vidéo. La première boucle remplit chacune des quatre pages avec différents rectangles de couleurs et affiche le texte noir contenant le numéro de page de la vidéo dans le centre de chaque page. Elle le fait en appelant fg_setpage pour définir la page de vidéo active, fg_setcolor et fg_rect pour dessiner les rectangles colorés, et enfin fg_setattr, fg_locate et fg_text pour afficher le texte. Le programme doit appeler fg_locate intérieur de la boucle parce que chaque page vidéo a sa propre position du curseur de texte. La deuxième boucle fait successivement chaque page vidéo la page visuelle; la page reste affichée jusqu'à ce que vous appuyez sur une touche. après

 Chapitre 8: Pages vidéo et Virtual Tampons 151


afficher toutes les quatre pages vidéo, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

 Exemple 8-1.
 #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main (void);
 PAGES #define 4
 void main ()
               {
                  Couleur int;
                  int old_mode;
                  Page int;
                  chaîne char [8];
 fg_initpm ();
                  if (fg_testmode (1, PAGES) == 0) {
                     printf ( "Ce programme nécessite la couleur. \ n");
                     sortie (1);
                     }
 fg_getmode old_mode = ();
                  fg_setmode (1);
 pour (page = 0; Page <PAGES; Page ++) {
                     fg_setpage (page);
                     color = Page + 1;
                     fg_setcolor (couleur);
                     fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                     fg_setattr (0, couleur, 0);
                     fg_locate (12,17);
                     sprintf (string, "la page% d", la page);
                     fg_text (string, 6);
                     }
 pour (page = 0; Page <PAGES; Page ++) {
                     fg_setvpage (page);
                     fg_waitkey ();
                     }
 fg_setmode (old_mode);
                  fg_reset ();
               }


 Exemple 8-2 est similaire à l'exemple 8-1, mais il utilise le EGA 320x200

mode graphique (mode 13), au lieu d'un mode texte. Notez que la seule différence réelle entre ce programme et la version en mode texte est l'utilisation de fg_setcolor au lieu de fg_setattr pour faire apparaître le texte en noir.

 Exemple 8-2. 

Guide de l'utilisateur 152 Fastgraph


 #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main (void);
 PAGES #define 4
 void main ()
               {
                  Couleur int;
                  int old_mode;
                  Page int;
                  chaîne char [8];
 fg_initpm ();
                  if (fg_testmode (13, PAGES) == 0) {
                     printf ( "Ce programme nécessite une");
                     ( "en mode 320 x 200 graphiques EGA \ n".) printf;
                     sortie (1);
                     }
 fg_getmode old_mode = ();
                  fg_setmode (13);
 pour (page = 0; Page <PAGES; Page ++) {
                     fg_setpage (page);
                     color = Page + 1;
                     fg_setcolor (couleur);
                     fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                     fg_setcolor (0);
                     fg_locate (12,17);
                     sprintf (string, "la page% d", la page);
                     fg_text (string, 6);
                     }
 pour (page = 0; Page <PAGES; Page ++) {
                     fg_setvpage (page);
                     fg_waitkey ();
                     }
 fg_setmode (old_mode);
                  fg_reset ();
               }


 pages vidéo virtuels sont créés avec la routine de fg_allocate de Fastgraph.  le

réserves de routine fg_allocate mémoire conventionnelle à accès aléatoire (RAM) qui Fastgraph traite alors comme une page vidéo. La quantité de mémoire requise dépend du mode vidéo actuel. La routine fg_allocate prend un seul argument entier qui spécifie le numéro de la page par laquelle la page virtuelle sera référencé. Cette valeur doit être comprise entre 1 et 63.

 Si vous essayez de créer une page virtuelle avec un numéro de page déjà attribué

à une page physique, fg_allocate ne fait rien. Par exemple, dans les graphiques modes Hercules (modes 11 et 12), il y a deux pages physiques numérotées 0 et 1. pages virtuelles dans les modes les graphiques Hercules doit donc avoir des numéros de page

 Chapitre 8: Pages vidéo et Virtual Tampons 153


entre 2 et 63. Si vous dites fg_allocate pour créer une page virtuelle Hercules numérotés de 0 ou 1, il ne fait rien parce que ces pages vidéo existent sous forme de pages physiques. De même, si vous utilisez fg_allocate dans un mode vidéo qui ne supporte pas les pages vidéo virtuelles, il retourne simplement sans rien faire.

 Un problème possible avec fg_allocate peut se produire quand il n'y a pas assez

mémoire disponible pour la création d'une page virtuelle en mode vidéo en cours. La routine renvoie fg_allocate que sa valeur de fonction d'un code d'état indiquant si oui ou non il a réussi. Les valeurs possibles du code d'état sont les suivants:

 sens de la valeur
 0 page virtuelle créée
         1 numéro de page spécifié est une page physique
         7 page virtuelle créé, mais les blocs de contrôle de mémoire ont été détruits
         8 mémoire insuffisante pour créer la page virtuelle

Si vous utilisez fg_testmode ou fg_bestmode pour vérifier si le nombre requis de pages vidéo sont disponibles lorsque vous utilisez le mode vidéo sur demande, vous ne devriez pas avoir besoin de surveiller le code de statut retourné par fg_allocate.

 La routine de fg_freepage libère la mémoire pour une page virtuelle créée

avec fg_allocate. Elle exige un seul argument entier qui identifie le numéro de page virtuelle pour libérer. Cette valeur doit être comprise entre 0 et 63. Si vous essayez de libérer une page vidéo physique, ou libérer une page virtuelle qui n'a jamais été créé, fg_freepage ne fait rien. Il est une bonne idée d'utiliser fg_freepage pour libérer toutes les pages vidéo virtuelles avant qu'un programme retourne le contrôle DOS, ou juste avant un programme sélectionne un nouveau mode vidéo.

 Exemple 8-3 est également similaire à l'exemple 8-1, mais il utilise le monochrome

en mode texte (mode 7). Parce que le mode texte monochrome ne dispose que d'une seule page vidéo physique, nous devons utiliser des pages vidéo virtuelles pour les numéros de page 1, 2 et 3. Notez comment fg_allocate et fg_freepage sont utilisés pour créer et libérer les pages vidéo virtuelles dans cet exemple.

 Exemple 8-3.
 #include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
            void main (void);
 PAGES #define 4
 void main ()
            {
               int old_mode;
               Page int;
               chaîne char [8];
 fg_initpm ();
               if (fg_testmode (7, PAGES) == 0) {
                  printf ( "Ce programme nécessite monochrome. \ n");
                  sortie (1);
                  }

Guide de l'utilisateur 154 Fastgraph


 fg_getmode old_mode = ();
               fg_setmode (7);
               fg_cursor (0);
 pour (page = 0; Page <PAGES; Page ++) {
                  fg_allocate (page);
                  fg_setpage (page);
                  fg_setcolor (7);
                  fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                  fg_setattr (0,7,0);
                  fg_locate (12,37);
                  sprintf (string, "la page% d", la page);
                  fg_text (string, 6);
                  }
 pour (page = 0; Page <PAGES; Page ++) {
                  fg_setvpage (page);
                  fg_waitkey ();
                  fg_freepage (page);
                  }
 fg_setmode (old_mode);
               fg_reset ();
            }


 Exemple 8-4 est similaire à l'exemple 8-3, mais il utilise le Hercules norme

mode graphique (mode 11) au lieu du mode texte monochrome. Parce que les modes les graphiques Hercules ont deux pages vidéo physiques, nous devons utiliser des pages vidéo virtuelles pour les numéros de page 2 et 3. Notez la seule vraie différence entre ce programme et la version en mode texte est l'utilisation de fg_setcolor au lieu de fg_setattr pour faire apparaître le texte en noir.

 Exemple 8-4.
 #include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
              void main (void);
 PAGES #define 4
 void main ()
              {
                 int old_mode;
                 Page int;
                 chaîne char [8];
 fg_initpm ();
                 if (fg_testmode (11, PAGES) == 0) {
                    printf ( "Ce programme nécessite Hercules");
                    printf ( "graphiques monochromes \ n.");
                    sortie (1);
                    }
 fg_getmode old_mode = (); 
                            Chapitre 8: Pages vidéo et Virtual Tampons 155


 fg_setmode (11);
 pour (page = 0; Page <PAGES; Page ++) {
                    fg_allocate (page);
                    fg_setpage (page);
                    fg_setcolor (7);
                    fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                    fg_setcolor (0);
                    fg_locate (12,37);
                    sprintf (string, "la page% d", la page);
                    fg_text (string, 6);
                    }
 pour (page = 0; Page <PAGES; Page ++) {
                    fg_setvpage (page);
                    fg_waitkey ();
                    fg_freepage (page);
                    }
 fg_setmode (old_mode);
                 fg_reset ();
              }


 Exemple 8-5 est une version généralisée d'exemples 8-1 et 8-3 qui fonctionne dans

tout mode texte vidéo 80 colonnes. Afin de simplifier le programme, chaque page vidéo est remplie avec des rectangles de la même couleur. Notez que fg_allocate et fg_freepage sont utilisés pour gérer les pages vidéo virtuelles en cas fg_bestmode sélectionne le mode texte monochrome (mode 7). Si fg_bestmode sélectionne une des couleurs mode texte de 80 colonnes (qui ont quatre pages vidéo physiques), fg_allocate et fg_freepage vont tout simplement revenir sans rien faire.

 Exemple 8-5.
 #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main (void);
 PAGES #define 4
 void main ()
                {
                   int old_mode, new_mode;
                   Page int;
                   chaîne char [8];
 fg_initpm ();
                   new_mode = fg_bestmode (80,25, PAGES);
                   if (new_mode <0) {
                      printf ( "Ce programme nécessite");
                      printf ( "un affichage de 80 colonnes. \ n");
                      sortie (1);
                      }
 fg_getmode old_mode = (); 

Guide de l'utilisateur 156 Fastgraph


 fg_setmode (new_mode);
                   fg_cursor (0);
 pour (page = 0; Page <PAGES; Page ++) {
                      fg_allocate (page);
                      fg_setpage (page);
                      fg_setcolor (7);
                      fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                      fg_setattr (0,7,0);
                      fg_locate (12,37);
                      sprintf (string, "la page% d", la page);
                      fg_text (string, 6);
                      }
 pour (page = 0; Page <PAGES; Page ++) {
                      fg_setvpage (page);
                      fg_waitkey ();
                      fg_freepage (page);
                      }
 fg_setmode (old_mode);
                   fg_reset ();
                }


 Exemple 8-6 est une version généralisée d'exemples 8-2 et 8-4 qui fonctionne dans

tout mode vidéo 320x200 graphique. Afin de simplifier le programme, chaque page vidéo est remplie avec des rectangles de la même couleur. Comme dans l'exemple 8-5, fg_allocate et fg_freepage sont utilisés pour gérer les pages vidéo virtuelles en cas fg_bestmode sélectionne un mode vidéo avec moins de quatre pages vidéo physiques. Notez que la seule différence réelle entre ce programme et la version en mode texte est l'utilisation de fg_setcolor au lieu de fg_setattr pour faire apparaître le texte en noir.

 Exemple 8-6.
 #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main (void);
 PAGES #define 4
 void main ()
                {
                   int old_mode, new_mode;
                   Page int;
                   chaîne char [8];
 fg_initpm ();
                   new_mode = fg_bestmode (320.200, PAGES);
                   if (new_mode <0) {
                      printf ( "Ce programme nécessite une");
                      ( "en mode 320 x 200 graphiques \ n".) printf;
                      sortie (1);
                      }
                            Chapitre 8: Pages vidéo et Virtual Tampons 157


 fg_getmode old_mode = ();
                   fg_setmode (new_mode);
 pour (page = 0; Page <PAGES; Page ++) {
                      fg_allocate (page);
                      fg_setpage (page);
                      fg_setcolor (15);
                      fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                      fg_setcolor (0);
                      fg_locate (12,17);
                      sprintf (string, "la page% d", la page);
                      fg_text (string, 6);
                      }
 pour (page = 0; Page <PAGES; Page ++) {
                      fg_setvpage (page);
                      fg_waitkey ();
                      fg_freepage (page);
                      }
 fg_setmode (old_mode);
                   fg_reset ();
                }


Curseurs de texte

 Comme mentionné dans le chapitre précédent, Fastgraph dessine des caractères matériels

à la position définie par le curseur de texte. Comme le curseur graphique, le curseur de texte ne sont pas un curseur dans le vrai sens, mais est tout simplement une paire d'espace de caractères (ligne, colonne) coordonne avec une signification particulière. Les 8 premières pages vidéo (qui est, pages 0 à 7) ont chacune leur propre curseur de texte. Chaque groupe ultérieur de 8 pages vidéo (pages 8 à 15, pages 16 à 23, et ainsi de suite) partagent respectivement les mêmes positions texte du curseur que les 8 premières pages. Cela signifie fg_locate mettra à jour l'un des 8 curseurs de texte différents en fonction de la page vidéo active. De même, fg_where retourne la position du curseur de texte pour la page active. Les fg_setmode de routine tous les ensembles de positions de curseur 8 texte aux coordonnées spatiales de caractères (0,0).

 Exemple 8-7 illustre l'utilisation de différents curseurs de texte dans un 80-

en mode texte, couleur de colonne (mode 3). Le programme affiche d'abord le texte "Page" à la page vidéo 0 (la page visible) et attend une touche. Il fait alors la page 1 de la page vidéo active, modifie l'emplacement du curseur de texte pour cette page, et affiche le texte «Page 1» à la page vidéo 1. Ensuite, il ajoute le caractère "0" au texte initialement affiché à la page 0. Notez que nous ne devons rétablir la position du curseur de texte pour la page 0, car il est affecté en changeant le curseur de texte pour la page 1. Après avoir attendu une autre touche, le programme fait Page vidéo 1 la page visuelle et attend encore un autre touches activées avant de retourner à DOS.

 Exemple 8-7.
 #include <fastgraf.h>
                         void main (void); 

Guide de l'utilisateur 158 Fastgraph


 void main ()
                         {
                            int old_mode;
 fg_initpm ();
                            fg_getmode old_mode = ();
                            fg_setmode (3);
                            fg_cursor (0);
                            fg_setattr (10,0,0);
 fg_locate (1,0);
                            fg_text ( "Page", 5);
                            fg_waitkey ();
 fg_setpage (1);
                            fg_locate (23,0);
                            fg_text ( "Page 1", 6);
 fg_setpage (0);
                            fg_text ( "0", 1);
                            fg_waitkey ();
 fg_setvpage (1);
                            fg_waitkey ();
 fg_setmode (old_mode);
                            fg_reset ();
                         }


Obtention vidéo Informations sur la page

 Fastgraph comporte deux routines, et fg_getpage fg_getvpage que,

retour respectivement le nombre actif ou visuelle Page vidéo. Chaque routine retourne la vidéo numéro de page en tant que valeur de la fonction, et ni routine nécessite aucun argument.

 Lors de la création de pages virtuelles ou logiques, vous devez choisir un numéro de page

qui ne fait pas référence une page physique ou une page virtuelle ou logique précédemment créé. Alors qu'il est bien sûr possible de garder la trace des numéros de page seront disponibles dans un mode vidéo donné, la fonction de fg_findpage de Fastgraph peut rendre le travail plus facile. Elle retourne un numéro de page utilisé, que vous pouvez ensuite passer à l'une des routines d'allocation de pages virtuelles ou logiques de Fastgraph. S'il n'y a plus disponibles (soit les 64 entrées dans les tables de pages internes sont en cours d'utilisation), fg_findpage renvoie zéro.

 La routine de fg_getaddr est parfois utile lors de l'utilisation des pages virtuelles.  Il

retours que sa valeur de la fonction d'adresse de segment (en mode réel) ou le sélecteur de segment (en mode protégé) pour le début de la page vidéo active. Il ne nécessite pas d'arguments. Bien que fg_getaddr est plus utile lors de l'utilisation des pages vidéo virtuelles, il fonctionne aussi bien avec des pages vidéo physiques.

 Exemple 8-9 illustre l'utilisation de fg_getpage, fg_getvpage, fg_findpage,

et fg_getaddr dans le VGA standard / MCGA mode 256 couleurs graphiques (mode 19). Ce mode vidéo offre une seule page physique, de sorte que le programme utilise fg_findpage

 Chapitre 8: Pages vidéo et Virtual Tampons 159


de trouver un numéro de page utilisé (qui sera page 1 en mode 19), puis appelle fg_allocate pour créer une page vidéo virtuelle. Après la création de la page virtuelle, le programme rend la page vidéo active; Page 0 reste la page vidéo visuelle. La routine de fg_getpage retourne ensuite le numéro de page active, suivie d'un appel à fg_getvpage pour retourner le numéro de page visuelle (0). Ensuite, le programme fg_getaddr utilise pour retourner l'adresse de segment / sélecteur pour les deux pages vidéo. Enfin, il restaure les attributs d'origine en mode vidéo et écran, affiche les valeurs retournées, et retourne au DOS.

 Exemple 8-9.
 #include <fastgraf.h>
              #include <stdio.h>
              void main (void);
 void main ()
              {
                 int old_mode;
                 int active visuelle;
                 int page page0, page1;
 fg_initpm ();
                 fg_getmode old_mode = ();
                 fg_setmode (19);
                 page = fg_findpage ();
                 fg_allocate (page);
                 fg_setpage (page);
 active = fg_getpage ();
                 fg_getvpage visuel = ();
 fg_setpage (0);
                 page0 = fg_getaddr ();
                 fg_setpage (page);
                 page1 = fg_getaddr ();
 fg_freepage (page);
                 fg_setmode (old_mode);
                 fg_reset ();
 printf ( "la page active est% d \ n"., actif);
                 printf ( "la page visuelle est% d \ n"., visuel);
                 printf ( "Page 0 adresse% 4X \ n", page0);
                 printf ( "page adresse% d est 4X% \ n", page, page1);
              }


Considérations pour les pages virtuelles

 Si vous utilisez Puissance C, tout compilateur BASIC pris en charge, Borland Pascal, ou

Turbo Pascal et le besoin de créer des pages virtuelles, vous devez réduire la taille du tas loin. Normalement, ces compilateurs allouer toute la mémoire restante pour le tas, ce qui signifie fg_allocate ne sera pas en mesure d'allouer de la mémoire pour la page virtuelle. Guide de l'utilisateur 160 Fastgraph


 Dans les programmes de base, la fonction SETMEM réduit la taille du tas loin.

Les versions de base des exemples de programmes Fastgraph comprennent la déclaration

 SetMemStatus & = SETMEM (-n)

avant d'appeler FGallocate. Ceci réduit la taille du segment loin de n octets. Pour un mode vidéo donné, la diminution réelle nécessaire est le nombre de pages virtuelles, multiplié par la taille de page dans ce mode. Page tailles sont répertoriés au début de ce chapitre, ou vous pouvez utiliser fg_pagesize pour déterminer la taille de la page pour le mode vidéo actuel.

 En Borland Pascal et Turbo Pascal, la directive du compilateur $ M définit la

taille de tas maximale en octets. Les versions Pascal des exemples de programmes Fastgraph comprennent la déclaration

 {$ M 16384,0,16384}

au début des exemples qui font appel fg_allocate. La troisième valeur dans cette liste définit la taille maximale du tas à 16K octets. Ceci est approprié pour la plupart des applications, mais si votre programme utilise les nouvelles procédures ou GetMem pour créer des variables dynamiques qui nécessitent plus d'espace de tas, vous aurez besoin d'augmenter la taille au-delà de 16K.

 La taille bien tas pour les programmes d'alimentation C est défini au moment de la liaison.  Vous devez

remplacer la taille de segment par défaut en incluant l'option [,, 16K] sur la commande PCL lorsque vous liez un programme d'alimentation C qui utilise fg_allocate. La valeur 16K est adapté pour la plupart des applications, mais si votre programme appelle les fonctions farcalloc ou farmalloc (ou calloc ou des fonctions malloc lorsque vous utilisez le modèle de mémoire), vous devrez peut-être augmenter la taille bien au-delà de tas 16K.

 Lorsque vous utilisez des pages virtuelles, vous devriez éviter d'utiliser le fg_setvpage

routine dans les sections du programme qui nécessitent des mises à jour d'écran rapides ou des séquences d'animation. En effet, le PC et PS / 2 BIOS vidéo ne sont capables d'afficher des pages physiques. Pour compenser cette restriction, Fastgraph échange le contenu d'une page physique à la page virtuelle demandée. En d'autres termes, si la page 1 est une page virtuelle et vous rendre la page visuelle, Fastgraph va échanger le contenu de la page 1 avec ce que la page était auparavant la page visuelle. Cela ne signifie pas les numéros de page du changement de Fastgraph parce Fastgraph maintient également une table interne contenant des adresses de pages vidéo et échange les deux entrées de table correspondantes. Comme précédemment, vous feriez page 1 de la page vidéo active si vous voulez écrire quelque chose à la page visuelle.

 A propos de la seule autre problème potentiel lors de l'utilisation des pages virtuelles est ce que

qui se produit lorsque vous essayez d'écrire à une page vidéo inexistante (par exemple, si vous écrivez à la page vidéo virtuelle 1 avant de créer avec fg_allocate). Dans ce cas, Fastgraph redirige simplement la sortie vidéo à la page visuelle.


Considérations pour Pages SuperVGA

 Si un programme en cours d'exécution en mode graphique SVGA retourne en mode texte lorsque

la page visuelle est pas la page 0, certains chipsets SVGA ont des problèmes la prochaine fois que vous essayez d'exécuter une application SVGA. Nous recommandons donc d'appeler fg_setvpage (0) juste avant de restaurer le mode vidéo d'origine si une application effectue un changement de page dans les modes graphiques SVGA. Par exemple:

 Chapitre 8: Pages vidéo et Virtual Tampons 161


 fg_getmode old_mode = ();
         fg_svgainit (0);
         fg_setmode (25);
                 .
                 .
                 .
         fg_setvpage (1);
                 .
                 .
                 .
         fg_setvpage (0);  / * Ajouter cette ligne pour être sûr * /
         fg_setmode (old_mode);
 Quelques chipsets SVGA ne peuvent pas définir l'adresse de début d'affichage au-delà du 16-

capacité de bits fourni par le contrôleur CRT, rendant fg_setvpage sens. S'il vous plaît se référer au fichier READ.ME pour plus de détails.


Pages logiques

 En plus des pages vidéo physiques et virtuels, Fastgraph offre une autre

classe de pages vidéo, appelé pages logiques. Vous pouvez créer des pages logiques dans un mode vidéo. Ils peuvent exister dans la mémoire conventionnelle, mémoire paginée (EMS), ou mémoire étendue (XMS). Cependant, ils ne sont pas aussi polyvalent que les pages physiques ou virtuels parce que les seules opérations que vous pouvez effectuer avec des pages logiques sont:

 * Copiez toute une page virtuelle ou physique à une page logique
    * Copiez toute une page logique à une page physique ou virtuel
    * Copiez toute une page logique à une autre page logique

Trois routines Fastgraph - fg_alloccms, fg_allocems et fg_allocxms - créer des pages logiques dans la mémoire conventionnelle, mémoire étendue, et la mémoire étendue, respectivement. Les trois routines ont un seul argument entier qui spécifie le numéro de page par lequel la page logique sera référencé. Le numéro de page doit être comprise entre 1 et 63 et ne doit pas faire référence à une page physique ou virtuelle. Leur valeur de retour est 0 si la page logique est créé, et négatif autrement (voir les descriptions de ces routines dans le Manuel de référence Fastgraph pour une liste complète des valeurs de retour). Comme pages virtuelles, utilisez fg_freepage pour libérer une page logique.

 Avant de pouvoir créer des pages logiques en mémoire étendue ou prolongée, vous

doit initialiser ces ressources pour une utilisation avec Fastgraph. Les fg_initems initialise routine mémoire paginée. Pour utiliser la mémoire paginée, vous devez avoir un gestionnaire de mémoire paginée (EMM) qui est conforme à l'étendue Lotus / Intel / Microsoft Spécification de la mémoire (LIM-EMS) version 3.2 ou ultérieure. Sur 80386 et 80486 systèmes, le pilote de périphérique EMM386.EXE fourni avec DOS 5.0 peut être utilisé pour traiter une partie ou l'ensemble de la mémoire étendue que la mémoire paginée. La routine de fg_initxms initialise la mémoire étendue pour une utilisation avec Fastgraph. Pour utiliser la mémoire étendue, vous devez avoir un pilote XMS conforme à la Lotus / Intel / Microsoft / AST eXtended Memory Specification version 2.0 ou ultérieure, tels que HIMEM.SYS. pilotes XMS nécessitent un système 80286, 80386 ou 80486. Les fg_initems et fg_initxms routines ont pas d'arguments et doivent être appelées après fg_setmode. Leur valeur de retour est 0 en cas de succès, et -1 si le conducteur et les ressources nécessaires ne sont pas présents. Guide de l'utilisateur 162 Fastgraph


 En mode protégé, la distinction entre classique, élargi, et

mémoire étendue disparaît parce que DOS extenders essentiellement traiter toute la mémoire système comme mémoire conventionnelle. Pour cette raison, fg_initems et fg_initxms ne sont pas significatifs et donc toujours revenir -1 en mode protégé bibliothèques Fastgraph. Cela désactive efficacement les fg_allocems et fg_allocxms routines, vous devez donc créer des pages logiques avec fg_alloccms en mode protégé.

 Exemple 8-10 illustre l'utilisation de pages logiques dans une couleur 320x200

le mode graphique. Le programme tente d'abord de créer une page logique dans la mémoire étendue en appelant fg_initxms et fg_allocxms. Si la création d'initialisation ou de la page échoue, il tente alors de créer la page en mémoire étendue avec fg_initems et fg_allocems. En cas d'échec, le programme appelle fg_alloccms pour essayer de créer la page en mémoire conventionnelle. Si elle ne peut pas créer la page logique du tout, le programme affiche un message d'erreur et sort.

 Une fois la page logique est créé, par exemple 8-10 affiche le mot "test"

au milieu de la page visuelle (page 0) puis fg_copypage utilise pour transférer le contenu des pages visuelles à la page logique. Parce que ce programme fonctionne dans l'un de plusieurs modes graphiques différents, nous utilisons fg_findpage pour choisir le numéro de page logique. Après avoir attendu pendant une séquence de touches, le programme efface la page visuelle, attend une autre touche, et copie les pages de contenu logiques retour à la page visuelle. Il libère alors la page et les sorties logiques.

 Exemple 8-10.
 #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main (void);
 void main ()
             {
                int new_mode, old_mode;
                int page statut;
 fg_initpm ();
                new_mode = fg_bestmode (320,200,1);
                if (new_mode <0 || new_mode == 12) {
                   printf ( "Ce programme nécessite une 320");
                   ( "le mode x 200 graphiques couleur \ n".) printf;
                   sortie (1);
                   }
                fg_getmode old_mode = ();
                fg_setmode (new_mode);
 page = fg_findpage ();
                status = fg_initxms ();
                if (état == 0) status = fg_allocxms (page);
                si (état <0) {
                   status = fg_initems ();
                   if (état == 0) status = fg_allocems (page);
                   }
                si (état <0) état = fg_alloccms (page);
 si (état <0) {
                            Chapitre 8: Pages vidéo et Virtual Tampons 163


 fg_setmode (old_mode);
                   fg_reset ();
                   printf ( "Impossible de créer la page logique. \ n");
                   sortie (1);
                   }
 fg_setcolor (7);
                fg_rect (0,319,0,199);
                fg_setcolor (9);
                fg_locate (12,18);
                fg_text ( "test", 4);
                fg_waitkey ();
 fg_copypage (0, p);
                fg_erase ();
                fg_waitkey ();
 fg_copypage (page, 0);
                fg_waitkey ();
 fg_freepage (page);
                fg_setmode (old_mode);
                fg_reset ();
             }
 Comme mentionné précédemment, les seules fonctions que vous pouvez effectuer avec logique

pages sont la copie des pages physiques / virtuelles vers des pages logiques, pages logiques aux pages physiques / virtuels, ou la copie d'une page logique à un autre. La routine fg_copypage fournit la seule façon de le faire pour des pages logiques. Voir le chapitre 11 pour plus d'informations sur fg_copypage.


Extended Pages Vidéo

 L'une des questions de support technique plus fréquentes que nous recevons est "I

?. Avoir un mégaoctet de mémoire sur ma carte vidéo, pourquoi ne puis-je utiliser seulement la première 256K "La réponse est simple: les modes du EGA standard et VGA graphiques ont aucun moyen de répondre à la mémoire vidéo au-delà de 256K Accès plus de mémoire nécessite le changement de banque SVGA. techniques. Ceci est analogue au fait que vous pourriez avoir quatre mégaoctets de RAM sur votre système, mais sans un gestionnaire EMS / XMS mémoire, une extension DOS, ou similaire, tout ce que la mémoire ne sera pas faire beaucoup de bien.

 Malheureusement, tous les chipsets SVGA permettent la commutation de banque non-SVGA

modes vidéo. Pour ceux qui le font, cependant, Fastgraph comprend une fonctionnalité appelée pages vidéo étendues. pages étendues permettent d'accéder à toute la mémoire vidéo dans les modes 13 à 18 et les modes 20 à 23 au lieu de restreindre l'accès à la première 256K. Cela signifie, par exemple, qu'une carte 1MB permettra SVGA 32 pages physiques dans le mode 13 plutôt que sur les 8 pages habituelles. pages étendues sont disponibles avec les chipsets SVGA suivants:

 * Ahead B
    * Avance Logic série 2000
    * ATI 28800 / mach32 / mach64
    * Avance Logic série 2000
    * NCR 77C22 / 77C32
    * Oak OTI-067

Guide de l'utilisateur 164 Fastgraph


 * Oak OTI-077
    * Oak OTI-087
    * Paradise WD90C11 / WD90C30 / WD90C31 / WD90C33
    * Tseng ET4000
 Bien que les pages étendues sont utilisées dans les modes graphiques non-SVGA, la méthode

d'accès à la mémoire vidéo au-dessus de 256K est spécifique à chaque puce SVGA. Ainsi, vous devez initialiser le noyau SVGA de Fastgraph (avec fg_svgainit) avant de pouvoir utiliser les pages étendues. On n'a pas encore trouvé une application VESA qui prend en charge les pages étendues, vous aurez donc besoin d'initialiser le noyau SVGA pour un soutien spécifique le chipset.

 Lors de l'écriture des applications qui utilisent des pages vidéo étendues, vous devez vous

que SVGA chipset de l'utilisateur prend en charge les pages étendues et qu'il ya suffisamment de mémoire vidéo pour le nombre de pages nécessaires. Tout d'abord, assurez-vous que fg_svgainit initialise avec succès le noyau SVGA. Si oui, vérifier le bit 2 de la valeur de retour de fg_svgastat pour voir si le chipset prend en charge les pages étendues. Enfin, utilisez fg_memory pour assurer que la mémoire vidéo suffisante est disponible pour le nombre de pages vidéo nécessaires.

 Le tableau suivant indique le nombre de pages vidéo disponibles dans le

modes graphiques qui prennent en charge les pages étendues.

 Nombre de pages Avec
                             Mode de 256K 512K 1MB
 13 8 16 32
                              14 4 8 16
                              15 2 4 8
                              16 2 4 8
                              17 2 4 8
                              18 2 4 8
                              20 4 8 16
                              21 2 4 8
                              22 4 8 16
                              23 2 4 8

Notez que lorsque les pages étendues ne sont pas activés, le mode vidéo a le nombre de pages vidéo physiques figurant dans la colonne 256K.

 Certains modes vidéo ne fournissent pas le nombre indiqué de pages vidéo complètes.

Par exemple, les modes 17 et 18 ont normalement deux pages vidéo - une complète 640x480 page (0) et une partielle 640x320 page (1). Pour les pages étendues, Fastgraph utilise une page système de numérotation qui maintient la cohérence avec sa numérotation de page standard. Autrement dit, lorsque les pages étendues sont disponibles et le mode 17 ou 18 est utilisé sur une carte vidéo de 1MB, les numéros de page vont de 0 à 7, avec les pages paires étant pleines pages et les pages impaires étant partielles 640x320 pages . De même, dans le mode de 22 pages 3, 7, 11 et 15 sont partielles (320x80); en mode 23 pages impaires sont partielles (320x320).

 Lorsque vous utilisez de Fastgraph routines de transfert de bloc (le fg_copypage,

fg_restore, fg_save, fg_tcxfer et fg_transfer) avec des pages étendues, vous devez passer les numéros de source et de la page de destination pour fg_defpages. Cela est nécessaire parce que les deux pages peuvent résider dans différentes banques SVGA, et le changement de banque est pas effectuée dans le code non-SVGA de Fastgraph. La charge supplémentaire d'avoir les routines de transfert de bloc déterminer les numéros de banque auraient un impact sur la

 Chapitre 8: Pages vidéo et virtuels Tampons 165


bloquer les routines de transfert lorsque les pages étendues ne sont pas utilisés. La routine de fg_defpages détermine les numéros de banque SVGA dans laquelle les pages de source et de destination résident et permet aux banques correspondantes pour la lecture et l'écriture. Ces banques restent en vigueur jusqu'à ce que vous définissez de nouveaux avec fg_defpages ou fg_setpage, donc vous ne pouvez pas besoin d'appeler fg_defpages avant chaque appel à une routine de transfert de bloc. La routine de fg_defpages n'a aucun effet sauf si les pages étendues sont activées. Le tableau suivant indique les numéros de banque pour chaque page vidéo dans chaque mode graphique qui prend en charge les pages étendues.

 Banque 0 Banque 1 Banque 2 Banque 3
                          Mode de pages Pages Pages Pages
 13 0-7 8-15 16-23 24-31
                           14 0-3 4-7 8-11 12-15
                           15 0-1 2-3 4-5 6-7
                           16 0-1 2-3 4-5 6-7
                           17 0-1 2-3 4-5 6-7
                           18 0-1 2-3 4-5 6-7
                           20 0-3 4-7 8-11 12-15
                           21 0-1 2-3 4-5 6-7
                           22 0-3 4-7 8-11 12-15
                           23 0-1 2-3 4-5 6-7
 Ensuite, nous allons présenter une séquence de code court qui appelle fg_defpages uniquement lorsque

nécessaire en mode 13, où chaque groupe de 8 pages réside dans sa propre banque de SVGA. fg_setmode appel permet la banque 0 pour la lecture et l'écriture, donc on n'a pas besoin d'appeler fg_defpages jusqu'à ce que nous référençons une page dans l'une des autres banques (qui est, une page numérotée 8 ou au-dessus).

 fg_svgainit (0);
    fg_setmode (13);  / * Permet la banque 0 pour la lecture et l'écriture * /
    fg_copypage (0,1);
    fg_copypage (0,2);
    fg_defpages (0,1);  / * Page 10 est dans la banque 1 * /
    fg_copypage (2,10);
    fg_defpages (1,1);  / * Page 15 est dans la banque 1 * /
    fg_copypage (10,15);
    fg_setpage (0);  / * Permet la banque 0 pour la lecture et l'écriture * /
    fg_erase ();
    fg_copypage (0,3);
    fg_defpages (1,0);  / * Page 15 est dans la banque 1 * /
    fg_copypage (15,4);
 La plupart des pilotes de souris ne savent rien de changer de banque SVGA et non

modes vidéo standard (qui est pourquoi Fastgraph doit accrocher ses propres gestionnaires de contrôle du curseur de la souris dans le pilote de la souris dans les modes XVGA et SVGA). Comme Fastgraph repose sur le pilote de la souris pour le contrôle du curseur dans les modes 13 à 18, il est seulement possible d'afficher le curseur de la souris sur les pages vidéo dans la première banque de SVGA (banque 0) dans ces modes. Notez que cela ne vaut pas aux modes 20 à 23, où Fastgraph contrôle le curseur de la souris par le biais de son propre gestionnaire.

 Certains chipsets SVGA ne réinitialisent pas la lecture et d'écriture des numéros de banque retour à

zéro lors de l'établissement d'un mode vidéo non-SVGA. Lorsqu'une opération de réglage du mode efface la mémoire vidéo, ces chipsets effacer la première page de la vidéo dans la dernière banque d'écriture sélectionnée. Alors que fg_setmode ne fixe les banques lire et écrire à zéro lorsque les pages étendues sont disponibles, il ne peut pas le faire avant le réglage du mode vidéo, Guide de l'utilisateur 166 Fastgraph


qui est ce qui serait normalement effacer l'écran. Cela peut entraîner des artefacts à la page 0 après avoir appelé fg_setmode. La meilleure façon de contourner ce problème est d'appeler fg_defpages (0,0) avant de restaurer le mode vidéo d'origine dans les programmes qui utilisent les pages étendues. Même cela, cependant, ne fait pas de mémoire vidéo clair après un jeu de mode lorsque vous utilisez les pages étendues avec certains chipsets SVGA. Nous recommandons donc d'appeler immédiatement fg_erase après la restauration du mode vidéo d'origine lors de l'utilisation des pages étendues.


Vidéo page Redimensionnement

 Redimensionnement est le processus de modification des dimensions de la page vidéo.  C'est

disponible uniquement dans les modes natifs EGA graphiques (modes 13 à 16), les modes natifs graphiques VGA (17 et 18), les modes VGA étendus (20 à 23), et les modes SVGA (24 à 29). Redimensionnement ne change pas la résolution de l'écran, mais augmente plutôt la page vidéo taille de sorte qu'une partie de la page est visible. Pour l'instant, nous allons simplement présenter le redimensionnement avec un exemple simple, mais dans le chapitre 13, nous verrons sa puissance réelle lorsque nous effectuons un panoramique lisse.

 La fg_resize routine Fastgraph modifie les dimensions de la page vidéo.

Ses deux arguments entiers définissent la largeur de la page et hauteur de page, à la fois en pixels. Exemple 11.08 fonctionne dans le mode graphique EGA 320x200 (mode 13). Après avoir établi le mode vidéo, il affiche le mot "resize" à partir de la colonne 38 de la ligne 0. Parce que les personnages vont au-delà de la dernière colonne de la ligne, ils enveloppent à la ligne suivante. Le programme continue l'affichage jusqu'à ce que vous appuyez sur une touche. Ensuite, il efface l'écran et fg_resize appelle à faire de la taille de la page 640x200 pixels. Encore une fois, le programme affiche le mot "resize" à partir de la colonne 38 de la ligne 0, mais cette fois il ne revient pas à la ligne suivante. En effet, le redimensionnement a doublé la largeur de la page, ce qui a augmenté le nombre de cellules de caractères par ligne de 40 à 80. Les caractères qui autrefois enveloppées à la ligne suivante continuent maintenant sur une partie hors de l'écran de la même ligne.

 Exemple 8-11.
 #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main (void);
 void main ()
                {
                   int old_mode;
 fg_initpm ();
                   if (fg_testmode (13,1) == 0) {
                      printf ( "Ce programme nécessite une 320");
                      ( "le mode x 200 graphiques EGA \ n".) printf;
                      sortie (1);
                      }
 fg_getmode old_mode = ();
                   fg_setmode (13);
 fg_setcolor (9);
                   fg_locate (0,38);
                   fg_text ( "resize", 6); 
                            Chapitre 8: Pages vidéo et Virtual Tampons 167


 fg_waitkey ();
 fg_erase ();
                   fg_resize (640,200);
                   fg_setcolor (10);
                   fg_locate (0,38);
                   fg_text ( "resize", 6);
                   fg_waitkey ();
 fg_setmode (old_mode);
                   fg_reset ();
                }


 La taille d'une page vidéo est limitée seulement par la quantité de données vidéo

mémoire disponible et la capacité d'adressage du mode vidéo. L'augmentation de la taille de la page vidéo réduit le nombre de pages physiques disponibles proportionnellement. En mode 13, par exemple, en augmentant la taille de la page de 320x200 à 640x400 réduit le nombre de pages vidéo de 8 à 2. Lorsque vous appelez fg_resize, la page visuelle doit être la page 0. Si vous avez créé des pages vidéo logiques, vous devez les libérer avec fg_freepage avant d'appeler fg_resize, puis créer à nouveau par la suite. Si vous avez initialisé la souris (avec fg_mouseini), joysticks (avec fg_initjoy), la mémoire (avec fg_initems) élargie, ou de la mémoire (avec fg_initxms) prolongée, vous devez réinitialiser ces ressources après avoir appelé fg_resize. Dans les modes 13 à 18, la plupart des pilotes de souris attendent un fixe largeur de la page vidéo, de sorte que le curseur de la souris peut être déformé après le redimensionnement des pages vidéo dans ces modes. Lorsque vous appelez fg_resize, Fastgraph définit la zone de découpage à la nouvelle page limites. La fg_setmode routine rétablit les dimensions d'une page vidéo à la résolution d'écran par défaut pour le mode vidéo sélectionné. La routine de fg_resize n'a pas d'effet quand un tampon virtuel est actif.

 Selon les dimensions passées à fg_resize, vous pouvez vous retrouver avec un

Page vidéo partielle. Encore une fois, supposons que nous utilisons le mode 13 et avons changé la taille de la page à 960x400 (ce qui est six fois la taille de page par défaut). Les pages originales de 0 à 5 représentent maintenant la page 0, et les pages originales 6 et 7 font maintenant la page 1. Cependant, il n'y a pas assez de mémoire vidéo à gauche sur la page 1 pour une pleine 960x400 page. Dans ce cas, le nombre de lignes de pixels disponibles à la page 1 serait tiers de la taille de la page complète à un, ou 133 lignes. En effet, le stockage total requis par les pages de l'original 6 et 7 est un tiers du total requis pour les pages de l'original 0 à 5.

 pages vidéo étendues peuvent être redimensionnées dans les modes 13-18 et 20-23, mais le

pages résultantes ne doivent pas franchir les limites de la banque SVGA. En mode 20, par exemple, vous avez normalement quatre 320x200 pages dans chaque banque. Vous pouvez changer la taille de la page vidéo de 640x400, ayant ainsi quatre pages plus grandes, un dans chaque banque. On ne pouvait pas, cependant, redimensionner la mémoire vidéo à deux 640x800 pages, que chaque page serait étendre sur deux banques.


Préserver la vidéo Contenu de la page À travers les commutateurs de mode

 Parfois, un programme graphique peut temporairement besoin de passer à une autre

mode vidéo. Un exemple de cela pourrait être une interface utilisateur (GUI) système de menuing graphique qui comprend "shell DOS" comme l'une de ses options. Lorsque l'utilisateur sélectionne cette option, le programme doit revenir à un mode texte vidéo pour le Guide de l'utilisateur 168 Fastgraph


utilisateur verra l'invite DOS familier lorsque le shell exécute. A la sortie du shell DOS, le programme revient à un mode graphique et devrait idéalement revenir à l'écran ce qu'il était à l'origine.

 Lorsque vous établissez un mode vidéo avec fg_setmode, Fastgraph efface toutes les

pages vidéo physiques et initialise ses tables de pages internes comme si aucune des pages virtuelles ou logiques ont été créées. Bien qu'il soit impossible de préserver le contenu de la page physique à travers les commutateurs de mode vidéo, vous pouvez utiliser fg_getentry et fg_setentry les routines de Fastgraph pour enregistrer le contenu des pages virtuelles ou logiques. L'astuce, pour ainsi dire, est d'utiliser fg_getentry pour enregistrer l'adresse de page virtuelle ou logique et le type avant de passer les modes vidéo. Ensuite, lorsque vous retournez sur le même mode vidéo, vous pouvez utiliser fg_setentry pour restaurer les tables de pages internes à leur état précédent. Cela rend effectivement la page virtuelle ou logique nouveau accessible.

 Exemple 8-12 illustre ce processus.  Ce programme fonctionne en mode vidéo

18, le mode graphique 640x480 VGA 16-couleur. Après avoir établi ce mode vidéo, le programme appelle fg_alloccms pour créer une page logique dans la mémoire conventionnelle. Ensuite, il appelle fg_getentry pour enregistrer l'adresse et le type de la page logique vient d'être créé. Le premier argument de fg_getentry spécifie le numéro de page (déterminé par fg_findpage); les deux arguments suivants reçoivent l'adresse de la page et le type. codes de type de page utilisés par fg_getentry et fg_setentry sont:

 0 page = non alloué
    1 page = physique
    2 = page virtuelle
    3 page = logique dans la mémoire paginée (EMS)
    4 = page logique dans la mémoire étendue (XMS)
    5 = page logique dans la mémoire conventionnelle
 Après ce travail d'installation, par exemple 8-12 remplit l'écran avec bleu clair

pixels, dessine une boîte blanche autour du bord, puis attend une touche. Avant de revenir au mode vidéo original (supposé être le mode 3), le programme utilise fg_copypage pour copier le contenu des pages visuelles à la page logique. Cela est nécessaire parce que nous ne pouvons enregistrer le contenu de la page virtuels ou logiques à travers les changements de mode vidéo, pas de pages physiques. En mode 3, le programme invite à entrer une combinaison de touches avant de revenir en mode 18.

 Maintenant, nous sommes prêts à restaurer le contenu précédent de la page visuelle.

Parce que l'exemple de programme n'a pas communiqué la page logique, la mémoire est toujours allouée; Fastgraph juste ne peut pas y accéder. Pour résoudre ce problème, le programme appelle fg_setentry pour restaurer les entrées de tables de pages internes de Fastgraph pour le numéro logique de la page originale à ce qu'ils étaient auparavant. Notez comment nous utilisons la même adresse de la page et le type de valeurs dans l'appel à fg_setentry qui ont été retournés plus tôt par fg_getentry. Maintenant que la page logique est de nouveau accessible, le programme peut fg_copypage utiliser pour copier son contenu revenir à la page visuelle. Avec cette explication derrière nous, voici par exemple 8-12.

 Exemple 8-12.
 #include <fastgraf.h>
                 void main (void);
 void main ()
                 {
                    int old_mode; 
                            Chapitre 8: Pages vidéo et Virtual Tampons 169


 int page page_addr, page_type;
 fg_initpm ();
                    fg_getmode old_mode = ();
                    fg_setmode (18);
                    page = fg_findpage ();
                    fg_alloccms (page);
                    fg_getentry (page, & page_addr, & page_type);
 fg_setcolor (9);
                    fg_fillpage ();
                    fg_setcolor (15);
                    fg_box (0,639,0,479);
                    fg_waitkey ();
 fg_copypage (0, p);
                    fg_setmode (old_mode);
                    fg_cursor (0);
                    fg_setcolor (15);
                    fg_text ( «Appuyez sur une touche.", 14);
                    fg_waitkey ();
 fg_setmode (18);
                    fg_setentry (page, page_addr, page_type);
                    fg_copypage (page, 0);
                    fg_waitkey ();
 fg_freepage (page);
                    fg_setmode (old_mode);
                    fg_reset ();
                 }


 Pour garder l'exemple le plus simple possible, il ne teste pas

disponibilité des modes vidéo, ni vérifier si la création de la page logique a réussi. Dans une application réelle, bien sûr, en omettant ces contrôles est pas recommandé. Voir l'exemple 8-17 pour une version de ce programme qui utilise des tampons virtuels au lieu de pages logiques.


Contrôle de la page Allocation

 Lorsque Fastgraph crée des pages virtuelles ou logiques en mémoire conventionnelle

avec fg_allocate ou fg_alloccms, il utilise le DOS allouer service de mémoire (fonction 48 hex d'interruption 21 hex). Certains compilateurs allouer tout ou partie de la mémoire conventionnelle disponible pour une structure de données appelée le tas ou tas loin. fonctions d'allocation de mémoire tels que malloc gérer leurs demandes par l'intermédiaire d'un gestionnaire de tas associé plutôt que par les services DOS. Si le gestionnaire de tas contrôle la mémoire tous disponibles, le DOS allouer service de mémoire est essentiellement désactivé parce qu'il n'y aura pas de mémoire disponible pour satisfaire les demandes d'allocation. Si le gestionnaire de tas contrôle certains, mais toute la mémoire non disponible, un conflit peut survenir entre le gestionnaire de tas et le DOS allouer service de mémoire.

 Pour résoudre ce problème, vous pouvez utiliser allouer de la mémoire loin du compilateur

fonction pour réserver la mémoire de la page virtuelle ou logique et ensuite faire le Guide de l'utilisateur 170 Fastgraph


Page connue Fastgraph avec fg_setentry. La meilleure façon de déterminer la quantité de mémoire à allouer est par la fonction fg_pagesize, qui renvoie la taille de page en octets (comme un entier long) pour le mode vidéo actuel. Pour libérer la page, utilisez fg_setentry avec un type de zéro page pour marquer la page comme non alloué avant de réellement libérer la mémoire. Les pages créées de cette façon ne sont pas initialement effacées parce que le contenu de blocs de mémoire alloués ne sont pas définis. Nous vous recommandons d'utiliser fg_erase pour définir le contenu des pages à la couleur de fond.

 Exemple 8-13 montre comment créer une page virtuelle dans les programmes en mode réel

l'utilisation de ces techniques au lieu de fg_allocate. Il utilise les fonctions farmalloc et farfree de la bibliothèque d'exécution C pour les compilateurs Borland (les fonctions Microsoft analogues sont _fmalloc et _ffree). Exemple 8-13 utilise fg_pagesize et Borland run-time fonction de bibliothèque farmalloc pour créer une page virtuelle dans le / MCGA mode 256 graphiques couleur 320x200 VGA. Après attribution de la mémoire, le programme appelle fg_setentry, en lui transmettant le numéro de page (1), la partie de segment de l'adresse du bloc de mémoire (en utilisant la macro FP_SEG de la bibliothèque run-time), et le code d'une page virtuelle (2) . Une fois la page virtuelle est mis en place, le programme écrit un texte sur la page virtuelle puis fg_copypage utilise pour afficher le contenu des pages virtuelles sur la page visuelle. Enfin, il libère la page en appelant fg_setentry (donc Fastgraph sait la page virtuelle est parti) et la fonction de bibliothèque run-time farfree (pour réellement libérer la mémoire). L'appel à fg_setentry est pas vraiment nécessaire dans ce cas, car aucune autre fait référence à la page 1.

 Exemple 8-13.
 #include <fastgraf.h>
           #include <dos.h>
           #ifdef __TURBOC__
           #include <alloc.h>
           #autre
           #include <malloc.h>
           #define farfree (p) _ffree (p)
           #define farmalloc (n) _fmalloc (n)
           #fin si
 void main (void);
 void main ()
           {
              int old_mode;
              page_addr unsigned;
              carboniser loin * buffer;
 fg_getmode old_mode = ();
              fg_setmode (19);
              buffer = farmalloc (fg_pagesize () + 16);
              page_addr = FP_SEG (tampon) + (FP_OFF ​​(tampon) +15) / 16;
              fg_setentry (1, page_addr, 2);
 fg_setpage (1);
              fg_erase ();
              fg_setcolor (9);
              fg_text ( "Ceci est la page 1.", 15);
              fg_waitkey (); 
                            Chapitre 8: Pages vidéo et Virtual Tampons 171


 fg_copypage (1,0);
              fg_setentry (1,0,0);
              fg_waitkey ();
 farfree (tampon);
              fg_setmode (old_mode);
              fg_reset ();
           }


tampons virtuels

 tampons virtuels sont des blocs de mémoire conventionnelle que vous pouvez traiter comme

la mémoire vidéo. Ils sont beaucoup plus grand que les pages virtuelles, car ils sont pris en charge dans tous les modes vidéographique et peut être plus petite ou plus grande que la taille réelle de la page. Une demande peut avoir jusqu'à 32 tampons virtuels ouvrent simultanément. Chaque tampon virtuel a ses propres limites d'écrêtage indépendants, qui par défaut à l'ensemble du tampon virtuel. Tout programme qui utilise des tampons virtuels doit initialiser l'environnement de tampon virtuel en appelant fg_vbinit une fois, avant d'appeler l'un des autres routines tampons virtuels Fastgraph. La routine de fg_vbinit n'a pas d'arguments et aucune valeur de retour.

 En mode protégé, et lors de l'utilisation des compilateurs en mode réel qui prennent en charge énorme

tableaux (tableaux lointains dont la taille peut dépasser 64 Ko), utiliser fg_vbdefine pour créer des tampons virtuels. La routine fg_vbdefine définit un bloc de mémoire allouée précédemment en tant que mémoire virtuelle. Habituellement, cette mémoire est allouée dynamiquement avec les fonctions malloc ou farmalloc en C ou C ++, la fonction GlobalAllocPtr en mode protégé Pascal, ou l'instruction ALLOCATE en FORTRAN protégées de mode. La routine fg_vbdefine renvoie une poignée par laquelle le tampon virtuel est référencé dans d'autres routines Fastgraph. Deux routines virtuelles connexes tampons sont fg_vbundef, qui libère une poignée de tampon virtuel, et fg_vbhandle, qui retourne la poignée de la mémoire tampon virtuelle active (ou -1 si aucun tampon virtuel est actif).

 Le nombre d'octets nécessaires pour un buffer virtuel est simplement sa largeur

pixels multiplié par sa hauteur en pixels, quel que soit le mode vidéo actuel. La mise en page de mémoire virtuelle est tout aussi simple. Par exemple, un tampon virtuel 320x200 nécessite 64,000 octets. Les 320 premiers octets représentent la première ligne de la mémoire virtuelle, les 320 octets suivants représentent la deuxième rangée, et ainsi de suite. Dans chacune des 200 ces lignes, chacune des 320 octets représente un pixel. Cela signifie, par exemple, le (0,0) pixel dans la mémoire tampon virtuelle serait à l'offset 0, le (2,0) pixel serait à l'offset 2, et (2,1) pixel serait à l'offset 322. d'une manière générale, le décalage de la position (x, y) pixel est donnée par la formule y * virtual_buffer_width + x.

 La méthode de l'allocation de mémoire dynamique appropriée pour les tampons virtuels

est compilateur et dépendant de l'environnement. Lorsque vous utilisez le mode protégé 32 bits, la mémoire tampon virtuelle réside dans le segment de données par défaut du programme et est référencé par un pointeur près standard. Dans les environnements 16 bits, la mémoire tampon virtuelle est un choix énorme et est référencé par un pointeur loin. Les exemples suivants illustrent la façon d'allouer de la mémoire pour un tampon virtuel 640x400 pour chaque compilateur qui prend en charge l'allocation dynamique des énormes blocs de mémoire. Guide de l'utilisateur 172 Fastgraph


Pour Borland C ++ (16-bit), Turbo C ++, Turbo C:

 carboniser énorme tampon *;
    buffer = (char énorme *) farmalloc (640L * 400L);

Pour Microsoft C / C ++, QuickC, Visual C ++, 16-bit WATCOM C / C ++:

 carboniser énorme tampon *;
    buffer = (char énorme *) halloc (640L * 400L, 1);

Pour les compilateurs C 32-bit / C ++:

 char * tampon;
    buffer = (char *) malloc (640 * 400);

Pour Borland Pascal 7 (mode protégé):

 tampon var: pointeur;
    tampon: = GlobalAllocPtr (GMEM_FIXED, Longint (640) * Longint (400));

Pour Microsoft FORTRAN PowerStation:

 ENTIER * 1 TAMPON [ALLOCATABLE] (:)
    ENTIER STATUS
    ALLOCATE (TAMPON (640 * 400), STAT = STATUS)
 Mode réel BASIC, Pascal, et les compilateurs Fortran ont limité, le cas échéant,

soutien aux énormes tableaux. Dans ces environnements, utilisez fg_vballoc pour créer des tampons virtuels. La routine de fg_vballoc utilise le DOS allouer service de mémoire à réserver la mémoire tampon virtuelle. Les compilateurs BASIC pris en charge et le mode réel Turbo Pascal assignent normalement toute la mémoire classique utilisé à une zone appelée le tas loin. Au mieux, cela va provoquer DOS demandes d'allocation de mémoire à l'échec, mais le plus souvent, il crée des conflits de mémoire qui se manifestent plus tard dans votre application. Pour résoudre ce problème, vous devez dire au compilateur de réduire la taille du tas loin.

 Mode réel programmeurs Pascal doivent utiliser la directive $ M pour réduire l'extrême

taille tas par l'espace total nécessaire pour tous les tampons virtuels. Si vous voulez utiliser un tampon virtuel 640x400, par exemple, la directive $ M suivante réduirait la taille loin tas par 256.000 octets:

 {$ M 16384,0,256000}
 les programmeurs de base doivent utiliser la fonction SETMEM pour réduire le tas loin

la taille de l'espace total nécessaire pour tous les tampons virtuels, plus 16 octets par tampon virtuel. Si vous voulez utiliser un tampon virtuel 640x400 dans un programme BASIC, l'appel SETMEM suivante réduirait la taille loin tas par 256,016 octets:

 SetMemStatus & = SETMEM (-256.016)
 Une fois que vous avez terminé avec un tampon virtuel, sa mémoire peut être libérée

en utilisant fg_vbfree. Vous devez utiliser fg_vbfree uniquement avec des tampons virtuels créés avec fg_vballoc et non ceux créés avec fg_vbdefine, et vous ne pouvez pas l'utiliser sur le tampon virtuel actif. Comme fg_vballoc et fg_vbfree sont nécessaires pour le mode réel uniquement, ils ne sont pas présents dans les bibliothèques de mode Fastgraph protégées. pour

 Chapitre 8: Pages vidéo et Virtual Tampons 173


tampons virtuels créés avec fg_vbdefine, il suffit d'utiliser la méthode standard de votre compilateur pour libérer des blocs de mémoire dynamique.

 Une fois un tampon virtuel est défini, vous pouvez l'activer avec fg_vbopen.

Quand un buffer virtuel est actif, la plupart des routines Fastgraph qui fonctionnent sur un tampon virtuel au lieu de la mémoire vidéo. Cela va continuer jusqu'à ce que vous appelez fg_vbclose, qui redirige les opérations graphiques revenir à la page de la vidéo active. Si vous voulez plus tard pour activer à nouveau le tampon virtuel, ou si vous voulez passer à un autre tampon virtuel précédemment créé avec fg_vbdefine, vous pouvez utiliser fg_vbopen à cet effet.

 Deux des plus importantes routines de tampons virtuels sont Fastgraph fg_vbpaste

et fg_vbcut. Ces routines se déplacent des zones rectangulaires entre la mémoire tampon virtuelle active et la page de la vidéo active. Les fg_vbcut copies de routine un de la zone de la page vidéo active à la mémoire tampon virtuelle active. De même, des copies fg_vbpaste un de la zone de la mémoire tampon virtuelle active à la page de la vidéo active. Une propriété particulièrement utile de fg_vbcut et fg_vbpaste est que chacun se souviennent de la page la plus récente de la mémoire tampon et la vidéo virtuelle active. Cette fonction permet de déplacer les zones avant et en arrière entre un tampon virtuel et la mémoire vidéo sans en continu l'ouverture et la fermeture de la mémoire virtuelle.

 La routine fg_vbpaste effectue une simple traduction des valeurs de pixels

plus grand que le nombre de couleurs disponibles en mode vidéo en cours. Cela pourrait se produire, par exemple, si vous avez utilisé fg_vbcut dans un mode graphique 256 couleurs et plus tard utilisé fg_vbpaste pour afficher le contenu du tampon virtuel dans un mode graphique de 16 couleurs. Si cela se produit, fg_vbpaste affiche des pixels de couleur c dans la couleur c modulo n, où n est le nombre de couleurs disponibles dans le mode vidéo actuel.

 À ce stade, certains exemples de programmes devraient permettre de clarifier l'utilisation de

tampons virtuels.Notre premier exemple, 8-14, fonctionne dans le VGA standard / MCGA 320x200 mode graphique 256 couleurs (mode 19) et crée un tampon virtuel deux fois plus élevée et deux fois plus large que la taille de l'écran. Cela signifie que nous allons créer un tampon virtuel 640x400 nécessitant 256.000 octets de mémoire conventionnelle (séquences de compilation conditionnelle montrent comment allouer la mémoire tampon virtuelle pour différents compilateurs). Si le tampon virtuel a été créé avec succès, le programme appelle fg_vbopen pour activer la mémoire virtuelle, puis dessine quatre 320x200 rectangles de couleurs différentes, un dans chaque quadrant de la mémoire virtuelle. Il fg_vbpaste utilise ensuite pour copier chaque rectangle sur la page vidéo active, suivie d'un autre appel pour montrer la partie centrale 320x200 du buffer virtuel (cela affichera des parties égales des quatre rectangles).

Exemple 8-14.
#include <fastgraf.h>
      #include <stdio.h>
      #include <stdlib.h>
     #ifdef __TURBOC__
     #include <alloc.h>
      #autre
     #include <malloc.h>
      #fin si
#define WIDTH 640
     #define HAUTEUR 400   

Guide de l'utilisateur 174 Fastgraph


void main (void);
void main ()
      {
        poignée int;
        int old_mode;
     #ifdef FG32
         char * tampon;
      #autre
        carboniser énorme tampon *;
      #fin si
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
        fg_getmode old_mode = ();
        fg_setmode (19);
        fg_vbinit ();
/ * Mettre en place un 640x400 tampon virtuel * /
#ifdef FG32
        buffer = (char *) malloc (WIDTH * HEIGHT);
     #elif défini (__ TURBOC__)
        buffer = (char énorme *) farmalloc ((long) WIDTH * (long) HAUTEUR);
      #autre
        buffer = (char énorme *) halloc ((long) WIDTH * (long) HAUTEUR, 1);
      #fin si
        if (tampon == NULL) {
           fg_setmode (old_mode);
           fg_reset ();
           printf ( "Impossible de créer la mémoire virtuelle. \ n");
           sortie (1);
            }
        handle = fg_vbdefine (buffer, largeur, hauteur);
        fg_vbopen (poignée);
/ * Dessiner un rectangle 320x200 dans chaque quadrant de tampon virtuel * /
fg_setcolor (9);
        fg_rect (0,319,0,199);
        fg_setcolor (10);
        fg_rect (320,639,0,199);
        fg_setcolor (11);
        fg_rect (0319200399);
        fg_setcolor (12);
        fg_rect (320,639,200,399);
/ * Coller chaque rectangle sur la page vidéo active 320x200 * /
fg_vbpaste (0,319,0,199,0,199);
        fg_waitkey ();
        fg_vbpaste (320,639,0,199,0,199);
        fg_waitkey ();
        fg_vbpaste (0,319,200,399,0,199);
        fg_waitkey (); 
                           Chapitre 8: Pages vidéo et Virtual Tampons 175


fg_vbpaste (320,639,200,399,0,199);
        fg_waitkey ();
/ * Coller le centre 320x200 sous-ensemble de la mémoire virtuelle * /
fg_vbpaste (160,479,100,299,0,199);
        fg_waitkey ();
/ * Fermer le tampon virtuel * /
fg_vbclose ();
/ * Rétablir le mode de la vidéo originale et la sortie * /
fg_setmode (old_mode);
        fg_reset ();
      }


Appel fg_vbclose avant l'appel de fg_setmode final est nécessaire parce que

fg_setmode n'a pas d'effet quand un tampon virtuel est actif. Si nous n'appelons fg_vbclose, le programme de retour au DOS en mode 19 au lieu du mode vidéo original.

Si vous vouliez au lieu d'allouer la mémoire tampon virtuelle avec

fg_vballoc dans l'exemple 8-14, les étapes pour créer la mémoire virtuelle allait changer la façon suivante:

/ * Mettre en place un 640x400 tampon virtuel * /
handle = fg_vballoc (largeur, hauteur);
si (poignée <0) {
   fg_setmode (old_mode);
   fg_reset ();
   printf ( "Impossible de créer la mémoire virtuelle. \ n");
   sortie (1);
    }
fg_vbopen (poignée);

Si vous créez le tampon virtuel avec fg_vballoc, vous devez également utiliser fg_vbfree pour libérer la mémoire tampon virtuelle quand il est plus nécessaire:

/ * Fermer le tampon virtuel * /
fg_vbclose ();
fg_vbfree (poignée);

Encore une fois, nous vous recommandons d'utiliser fg_vballoc et fg_vbfree seulement avec les compilateurs 16 bits qui ne fournissent pas des méthodes faciles pour créer d'énormes tableaux.

Exemple 8-15 illustre l'utilisation de la routine de fg_vbcut, qui

réalise essentiellement l'opération inverse de fg_vbpaste. Autrement dit, fg_vbcut copie une zone rectangulaire de la page vidéo active à la mémoire tampon virtuelle active. Le programme commence par dessiner un rectangle bleu 20x20 avec une bordure blanche dans le coin supérieur gauche de la page de la vidéo active. Après une séquence de touches, il met en place un tampon virtuel 20x20 et appelle fg_vbcut pour copier le rectangle pour le Guide de l'utilisateur 176 Fastgraph


la mémoire virtuelle. Le programme appelle ensuite fg_vbpaste dans une boucle pour afficher 16 copies du contenu de tampons virtuels à travers le fond de l'écran. Notez que par exemple 8-15 utilise un tampon virtuel qui est juste 20 pixels carrés, ou 400 octets au total. Parce qu'il est si petit, nous avons choisi de déclarer un tableau de 400 octets pour le tampon virtuel au lieu d'allouer dynamiquement la mémoire comme dans l'exemple précédent. Notez également que parce que la taille virtuelle de réseau de tampon est inférieure à 64K octets, nous pouvons déclarer ce loin au lieu d'énorme dans les environnements 16 bits (énormes tableaux moins de 64K sont fonctionnellement équivalents à des tableaux loin).

Exemple 8-15.
#include <fastgraf.h>
#define WIDTH 20
               #define HAUTEUR 20
void main (void);
#ifdef FG32
               char buffer [WIDTH * HEIGHT];
                #autre
               carboniser loin tampon [WIDTH * HEIGHT];
                #fin si
void main ()
                {
                  poignée int;
                  int old_mode;
                  int x;
fg_initpm ();
                  fg_getmode old_mode = ();
                  fg_setmode (19);
                  fg_vbinit ();
fg_setcolor (15);
                  fg_rect (0, WIDTH-1,0, HAUTEUR-1);
                  fg_setcolor (9);
                  fg_rect (1, WIDTH-2,1, HAUTEUR-2);
                  fg_waitkey ();
handle = fg_vbdefine (buffer, largeur, hauteur);
                  fg_vbopen (poignée);
                  fg_vbcut (0, WIDTH-1,0, HAUTEUR 1,0, HAUTEUR-1);
for (x = 0; x <= 320 Width = x + WIDTH)
                     fg_vbpaste (0, WIDTH-1,0, HAUTEUR-1, x, 199);
                  fg_waitkey ();
fg_vbclose ();
                  fg_setmode (old_mode);
                  fg_reset ();
               }   
                           Chapitre 8: Pages vidéo et Virtual Tampons 177


Si vous créez un tampon virtuel qui est plus grand ou plus large que la taille de la page

(Ou peut-être à la fois plus grand et plus large), il est possible d'effectuer un défilement de tampon virtuel. Pour obtenir un effet de défilement, vous généralement juste appeler fg_vbpaste itérative de telle sorte que la région de source dans les incréments de tampons virtuels progressivement, tandis que la région de destination sur la page vidéo actif reste le même. Selon le mode vidéo et la taille de la zone de défilement, vous pouvez avoir besoin d'inclure un facteur de retard entre fg_vbpaste appelle donc la zone à défilement ne semble pas sauter immédiatement à sa destination finale.

Exemple 8-16 effectue le défilement de la mémoire tampon virtuelle. Cet exemple fonctionne dans le

XVGA 320x200 mode graphique 256 couleurs (mode 20) et crée un buffer virtuel 1000x50 en utilisant la méthode de l'exemple 8-14. Le programme remplit la mémoire tampon virtuelle avec une série d'un seul pixel de largeur des rectangles, chacun 50 pixels en hauteur et en couleurs alternées. Le défilement réel a lieu dans la boucle contenant les deux appels fg_vbpaste. Nous allons définir une zone 100x50 dans le milieu de la page visuelle, avec des extrêmes horizontaux entre 110 et 209, et les extrêmes verticales entre 75 et 124, que notre région de défilement. Nous allons faire défiler la moitié supérieure (25 pixels) du buffer virtuel de droite à gauche tout en faisant défiler la moitié inférieure de gauche à droite. En d'autres termes, nous allons déplaçons deux 100x25 sous-ensembles de la mémoire tampon virtuelle à travers la zone de défilement.

Le premier appel de fg_vbpaste fait défiler la moitié supérieure de la mémoire virtuelle.  le

à partir de coordonnées x définissant la zone de transfert à partir des plages tampons virtuels 0-900 par incréments d'un pixel, et la largeur de la zone de transfert est toujours 100 pixels. La hauteur de la zone de transfert reste constante à 25 pixels (lignes de mémoire tampon virtuel 0 à 24). La position de la destination est la moitié supérieure de la zone de défilement de la page visuelle; son coin inférieur gauche est à x = 110 et y = 99.

Le deuxième appel de fg_vbpaste, qui fait défiler la moitié inférieure du virtuel

tampon, mais dans le sens opposé, se comporte de manière similaire. Dans ce cas, le x de départ de coordonnées dans le tampon virtuel diminue 900-0 dans les étapes d'une durée d'pixel, et sa largeur est toujours 100 pixels. La hauteur de la zone de transfert est à nouveau 25 pixels, mais cette fois-ci utilise des lignes 25-49 dans la mémoire tampon virtuelle. La position de la destination est la moitié inférieure de la zone de défilement de la page visuelle; son coin inférieur gauche est à x = 110 et y = 124.

Exemple 8-16.
#include <fastgraf.h>
     #include <stdio.h>
     #include <stdlib.h>
    #ifdef __TURBOC__
    #include <alloc.h>
     #autre
    #include <malloc.h>
     #fin si
WIDTH #define 1000
    #define HAUTEUR 50
void main (void);
void main ()
     {
       poignée int; 

Guide de l'utilisateur 178 Fastgraph


int old_mode;
       int x;
    #ifdef FG32
        char * tampon;
     #autre
       carboniser énorme tampon *;
     #fin si
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
       fg_getmode old_mode = ();
       fg_setmode (20);
       fg_vbinit ();
/ * Remplir l'écran avec la lumière pixels bleus * /
fg_setcolor (9);
       fg_fillpage ();
/ * Mettre en place le tampon virtuel * /
#ifdef FG32
       buffer = (char *) malloc (WIDTH * HEIGHT);
    #elif défini (__ TURBOC__)
       buffer = (char énorme *) farmalloc ((long) WIDTH * (long) HAUTEUR);
     #autre
       buffer = (char énorme *) halloc ((long) WIDTH * (long) HAUTEUR, 1);
     #fin si
       if (tampon == NULL) {
          fg_setmode (old_mode);
          fg_reset ();
          printf ( "Impossible de créer la mémoire virtuelle. \ n");
          sortie (1);
           }
       handle = fg_vbdefine (buffer, largeur, hauteur);
       fg_vbopen (poignée);
/ * Remplir le tampon virtuel avec une série de rectangles étroits * /
for (x = 0; x <WIDTH; x ++) {
          fg_setcolor (x);
          fg_rect (x, x, 0, HAUTEUR-1);
           }
/ * Faire défiler le tampon virtuel à travers une fenêtre 100x50 sur le * /
       / * La page visuelle, de telle sorte que les rouleaux de la moitié en haut à gauche et le * /
       / * Défile demi bas à droite * /
for (x = 0, x largeur <99; x ++) {
          fg_vbpaste (x, x + 99,0,24,110,99);
          fg_vbpaste (WIDTH-100-x, WIDTH-1-x, 25,49,110,124);
           }
       fg_waitkey ();
/ * Fermer le tampon virtuel * /   
                           Chapitre 8: Pages vidéo et Virtual Tampons 179


fg_vbclose ();
/ * Rétablir le mode de la vidéo originale et la sortie * /
fg_setmode (old_mode);
       fg_reset ();
     }


Le dernier exemple virtuel tampon programme que nous allons présenter dans ce chapitre est

une version de l'exemple 8-12 modifié pour fonctionner avec des tampons virtuels. Exemple 8-12 utilisé une page logique dans la mémoire conventionnelle pour préserver le contenu de la page visuelle à travers les commutateurs de mode vidéo, avec l'aide de fg_getentry et fg_setentry les routines de Fastgraph. Exemple 8-17 illustre comment vous pouvez accomplir la même chose avec un tampon virtuel. Il fonctionne dans le mode 320x240 256- graphique couleur (mode 22) et utilise un tampon virtuel dont la taille est identique à la résolution de l'écran. Après la création de la mémoire virtuelle, le programme remplit la page visuelle avec des pixels bleus et dessine une bordure blanche autour de lui. Il utilise ensuite fg_vbcut pour copier le contenu de l'écran dans la mémoire tampon virtuelle. Comme exemple 8-12, le programme passe temporairement revenir au mode vidéo original et attend une touche. Il passe ensuite en mode 22 et fg_vbpaste utilise pour restaurer le contenu de l'écran.

Exemple 8-17.
#include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
          #ifdef __TURBOC__
          #include <alloc.h>
           #autre
          #include <malloc.h>
           #fin si
void main (void);
void main ()
           {
             poignée int;
             int old_mode;
          #ifdef FG32
              char * tampon;
           #autre
             carboniser énorme tampon *;
           #fin si
fg_initpm ();
             fg_getmode old_mode = ();
             fg_setmode (22);
             fg_vbinit ();
#ifdef FG32
             buffer = (char *) malloc (320 * 240);
          #elif défini (__ TURBOC__)
             buffer = (char énorme *) farmalloc (320L * 240L); 

Guide de l'utilisateur 180 Fastgraph


 #autre
             buffer = (char énorme *) halloc (320L * 240L, 1);
           #fin si
             if (tampon == NULL) {
                fg_setmode (old_mode);
                fg_reset ();
                printf ( "Impossible de créer la mémoire virtuelle. \ n");
                sortie (1);
                 }
             handle = fg_vbdefine (tampon, 320240);
fg_setcolor (9);
             fg_fillpage ();
             fg_setcolor (15);
             fg_box (0,319,0,239);
             fg_vbopen (poignée);
             fg_vbcut (0,319,0,239,0,239);
             fg_vbclose ();
             fg_waitkey ();
fg_setmode (old_mode);
             fg_cursor (0);
             fg_setcolor (15);
             fg_text ( «Appuyez sur une touche.", 14);
             fg_waitkey ();
fg_setmode (22);
             fg_vbopen (poignée);
             fg_vbpaste (0,319,0,239,0,239);
             fg_waitkey ();
fg_vbclose ();
             fg_setmode (old_mode);
             fg_reset ();
           }


Fastgraph comprend d'autres fonctions pour travailler avec des tampons virtuels, mais

nous reportons notre discussion sur eux jusqu'à ce que les chapitres suivants.


Résumé de la vidéo et de la page Routines tampons virtuels

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

FG_ALLOCATE crée une page vidéo virtuelle. La quantité de mémoire requise

dépend du mode vidéo en cours. Cette routine n'a pas d'effet si elle fait référence à une page vidéo physique ou logique.

FG_ALLOCEMS crée une page logique dans la mémoire paginée (EMS). Le montant

de mémoire requise dépend des dimensions du mode vidéo et tampon vidéo actuels. Cette routine n'a pas d'effet si elle fait référence à un physique ou virtuel

Chapitre 8: Pages vidéo et Virtual Tampons 181


Page vidéo. En mode protégé, fg_initems toujours échoue, alors fg_allocems est effectivement désactivé.

FG_ALLOCXMS crée une page logique dans la mémoire étendue (XMS). Le montant

de mémoire requise dépend des dimensions du mode vidéo et tampon vidéo actuels. Cette routine n'a pas d'effet si elle fait référence à une page vidéo physique ou virtuel. En mode protégé, fg_initxms toujours échoue, alors fg_allocxms est effectivement désactivé.

FG_COPYPAGE transfère le contenu d'une page vidéo à un autre.  le

pages peuvent être des pages vidéo physiques, virtuels ou logiques. Si les deux pages sont des pages logiques, ils doivent exister dans le même type de mémoire. Cette routine applique toujours les pages vidéo, même quand un tampon virtuel est actif.

FG_DEFPAGES définit les banques SVGA pour la page source et de destination

numéros lorsque vous utilisez les routines de transfert de bloc de Fastgraph avec des pages vidéo étendues.

FG_FINDPAGE trouve un numéro de page de vidéo disponible pour un virtuel ou logique

page.

FG_FREEPAGE publie une page vidéo virtuelle ou logique créé avec

fg_allocate, fg_alloccms, ou fg_allocems fg_allocxms. Cette routine n'a pas d'effet si elle fait référence à une page vidéo physique, ou une page virtuelle qui n'a jamais été créé.

FG_GETADDR retourne l'adresse de segment en mode réel ou en mode protégé

sélecteur de segment pour la page de la vidéo active.

FG_GETENTRY récupère le type et l'adresse d'un physique, virtuel ou

Page vidéo logique. Cette routine est utile pour sauvegarder le contenu de la page virtuelles ou logiques à travers les changements de mode vidéo.

FG_GETPAGE renvoie le nombre actif de Page vidéo.
FG_GETVPAGE renvoie le numéro visuel de la page vidéo.
FG_INITEMS initialise la mémoire paginée pour une utilisation avec Fastgraph de logique

pages. En mode protégé, l'initialisation de la mémoire paginée échouera toujours.

FG_INITXMS initialise la mémoire étendue pour une utilisation avec Fastgraph de logique

pages. En mode protégé, l'initialisation de la mémoire étendue échouera toujours.

FG_PAGESIZE renvoie la page vidéo taille en octets pour la vidéo en cours

mode. La taille de la page est toujours la taille de la page vidéo, même quand un tampon virtuel est actif.

FG_RESIZE modifie les dimensions d'une page vidéo EGA et VGA graphiques

modes. Cette fonction n'a pas d'effet quand un tampon virtuel est actif.

FG_SETENTRY spécifie le type et l'adresse d'un physique, virtuel ou

Page vidéo logique. Pour les pages logiques, il précise en outre si la page réside dans la mémoire conventionnelle, étendue ou prolongée. Cette routine est utile pour sauvegarder le contenu de la page virtuelles ou logiques à travers les changements de mode vidéo, ou pour la création manuelle des pages virtuelles et logiques. Guide de l'utilisateur 182 Fastgraph


FG_SETPAGE établit la page vidéo active. Il peut être une personne physique ou

page virtuelle.

FG_SETVPAGE établit la page vidéo visuelle. Il peut être une personne physique ou

page virtuelle.

FG_VBALLOC crée un tampon virtuel de la taille spécifiée. La mémoire pour

la mémoire virtuelle est attribuée automatiquement. Cette routine doit être utilisé au lieu de fg_vbdefine pour les compilateurs en mode réel qui ne supportent pas d'énormes blocs de mémoire (qui est, blocs loin supérieur à 64K octets). La routine de fg_vballoc est pas présent dans les bibliothèques en mode protégé de Fastgraph.

FG_VBCLOSE ferme le tampon virtuel actif et dirige la production graphique

Retour à la page de la vidéo active.

FG_VBCUT copies d'une région rectangulaire de la page vidéo active à la

tampon virtuel actif.

FG_VBDEFINE crée un tampon virtuel de la taille spécifiée.
FG_VBFREE libère la poignée d'un tampon virtuel et libère la mémoire

attribué à un tampon virtuel créé avec fg_vballoc. La routine de fg_vbfree est pas présent dans les bibliothèques en mode protégé de Fastgraph.

FG_VBHANDLE retourne la poignée pour le tampon virtuel actif, ou -1 si aucune

tampon virtuel est actif.

FG_VBINIT initialise environnement tampon virtuel Fastgraph.  Ce

routine doit être appelée une fois, avant que d'autres routines qui font référence à des tampons virtuels.

FG_VBOPEN fait un tampon virtuel existant du tampon virtuelle active.
copies FG_VBPASTE une région rectangulaire de la mémoire tampon virtuelle active à

la page de la vidéo active.

FG_VBUNDEF relâche la poignée associée à un tampon virtuel.



chapitre 9


Guide de l'image Fichiers 184 Fastgraph utilisateur


aperçu

Dans le contexte de Fastgraph, une image est une zone rectangulaire

contenant un certain type d'image. Une image peut-être quelque chose d'aussi simple que d'une icône de la main de pointage, ou aussi détaillée que le tableau de bord d'une voiture de sport. Fastgraph comprend plusieurs routines pour afficher, récupérer et manipuler des images. Dans ce chapitre, nous allons commencer notre discussion sur les images en regardant le PCX, GIF, FLI / FLC, et les formats de fichiers d'image pixel d'exécution Fastgraph supports, ainsi que les routines disponibles pour l'affichage et la création de fichiers d'images dans ces formats.


fichiers PCX

Le format de fichier PCX a été initialement développé par ZSoft Corporation pour

leur programme de peinture commerciale, PC Paintbrush. Il a évolué pour devenir l'un des formats de fichier d'image les plus populaires parce que de nombreux produits peuvent lire et écrire des fichiers PCX au moins dans une certaine mesure. Fastgraph comprend des routines pour l'affichage et la création de fichiers PCX, ainsi que d'autres fonctions de soutien PCX.

La routine fg_showpcx affiche une image stockée dans un fichier PCX.  Ça peut

positionner l'image en utilisant les informations contenues dans l'en-tête de PCX de coordonnées, ou de telle sorte que son coin supérieur gauche est à la position graphique du curseur sur la page vidéo active. Le premier argument de fg_showpcx est le nom du fichier PCX (il peut inclure un nom de chemin), et son second argument est un masque de bits qui contrôle la façon dont l'image est affichée. Le nom du fichier doit se terminer par un caractère nul, donc les programmeurs BASIC, FORTRAN et Pascal auront besoin de stocker un octet nul comme le dernier caractère de la chaîne de nom de fichier. La routine de fg_showpcx ne peut pas afficher les images PCX dans les tampons virtuels. Une routine séparée, fg_loadpcx, est prévu à cet effet et sera décrit plus loin dans cette section.

Dans la version actuelle de Fastgraph, seule la faible commande trois bits (bits

0 à 2) de l'argument de masque de bits sont significatifs. Le tableau suivant résume la signification de ces bits.

Bit Valeur Signification
0 0 Utiliser les valeurs de palette stockées dans le fichier PCX
             0 1 Utilisez les paramètres de la palette en cours
             1 0 image d'affichage à la position indiquée en tête PCX
             1 1 Afficher l'image à la position graphique actuelle
             2 0 données d'image d'affichage à partir du fichier PCX
             2 1 données d'image d'affichage de la mémoire tampon de fg_imagebuf

Tous les autres bits sont réservés et doivent être zéro pour garantir la compatibilité avec les futures versions. La routine fg_showpcx renvoie une valeur de 0 en cas de succès, 1 si le fichier spécifié n'a pas été trouvé, et 2 si le fichier est pas un fichier PCX.

La routine de fg_makepcx crée un fichier PCX à partir du rectangle spécifié

région de la page vidéo active ou tampon virtuel. Ses quatre premiers arguments définissent le minimum x, maximum x, y au minimum, et y coordonnées d'espace d'écran maximale de la région (les x minimales coordonnées est réduite à une limite d'octet si nécessaire). Son cinquième argument est le nom du fichier PCX pour créer (il peut inclure un nom de chemin). Comme fg_showpcx, le nom du fichier doit se terminer par un caractère nul. Si un fichier portant le même nom existe, il est

Chapitre 9: Image Fichiers 185


écrasé. La routine fg_makepcx renvoie une valeur de 0 en cas de succès, et 1 si le fichier PCX n'a ​​pas été créé.

Exemple 9-1 utilise fg_showpcx et fg_makepcx pour créer un nouveau fichier PCX à partir

lignes sélectionnées d'un fichier existant 320x200 PCX 256 couleurs. Comme il est écrit, le programme utilise le fichier CORAL.PCX pour créer NEW.PCX, mais il pourrait facilement être étendu à travailler avec tous les fichiers PCX. L'appel à fg_showpcx affiche l'image en CORAL.PCX en utilisant la position de l'écran et les paramètres de la palette définie dans le fichier PCX. Après avoir attendu pendant une séquence de touches, le programme appelle fg_makepcx pour créer un fichier PCX nommé NEW.PCX de rangées de pixels 80 à 99 de l'image originale. Dans le cas où le programme rencontre des problèmes, il affiche un message d'erreur avant de quitter.

Exemple 9-1.
#include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
          void main (void);
void main ()
           {
             int old_mode;
             int READ_STATUS, write_status;
fg_initpm ();
             if (fg_testmode (19,1) == 0) {
                printf ( "Ce programme nécessite une 320");
                ( "le mode x 200 graphiques MCGA \ n".) printf;
                sortie (1);
                 }
             fg_getmode old_mode = ();
             fg_setmode (19);
READ_STATUS = fg_showpcx ( "CORAL.PCX", 0);
             fg_waitkey ();
             si (== READ_STATUS 0)
                write_status = fg_makepcx (0,319,80,99, "NEW.PCX");
              autre
                write_status = 1;
fg_setmode (old_mode);
             fg_reset ();
si (== READ_STATUS 1)
                printf ( "CORAL.PCX introuvable. \ n");
             else if (READ_STATUS == 2)
                printf ( "CORAL.PCX est pas un fichier PCX. \ n");
             if (write_status == 1)
                printf ( "NEW.PCX pas créé. \ n");
           }


Dans le mode 16-graphique couleur Tandy / PCjr (mode 9) et l'EGA native

modes graphiques (modes 13 à 16), les registres de la palette ne sont pas lisibles. Par conséquent, fg_makepcx utilisera les paramètres de la palette par défaut lorsqu'il est utilisé dans le guide de ces 186 Fastgraph utilisateur


modes vidéo sur Tandy et systèmes EGA. Affichage d'un fichier PCX à une résolution inférieure (par exemple, un fichier 640x480 PCX à 320x200) tronque l'affichage sur la droite et sur le fond. Cette affiche effectivement le coin supérieur gauche de l'image. Les fg_showpcx et fg_makepcx routines ont aucun effet en mode vidéo de texte ou en mode graphique basse résolution Hercules.

Si vous voulez afficher un fichier PCX dans un tampon virtuel, vous devez utiliser

fg_loadpcx la routine de Fastgraph au lieu de fg_showpcx. Les paramètres de fg_loadpcx et les valeurs de retour sont identiques à ceux de fg_showpcx, mais la destination de l'image virtuelle est une mémoire tampon et non de mémoire vidéo. Nous avons trouvé qu'il est préférable de créer une fonction distincte pour le chargement des images PCX dans des tampons virtuels car PCX fichiers de ressembler étroitement à la structure de la mémoire vidéo. La routine fg_showpcx est optimisée pour tirer profit de ce fait, alors que fg_loadpcx doit exécuter la tâche supplémentaire consistant à convertir les données de pixel au format de mémoire virtuelle.

Exemple 9-2 montre comment afficher une image PCX dans un tampon virtuel avec

fg_loadpcx. Le fichier CORAL.PCX utilisé dans cet exemple est une image 320x200, donc la taille de la mémoire tampon virtuelle requise est de 64.000 octets. Après la création et l'ouverture de la mémoire virtuelle, le programme appelle fg_loadpcx pour afficher l'image dans la mémoire tampon virtuelle. En cas de succès, il est l'image visible en copiant le contenu du tampon virtuel à la page visuelle utilisant fg_vbpaste.

Exemple 9-2.
#include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
          #ifdef __TURBOC__
          #include <alloc.h>
           #autre
          #include <malloc.h>
           #fin si
          void main (void);
void main ()
           {
             poignée int;
             int old_mode;
             statut int;
          #ifdef FG32
              char * tampon;
           #autre
             carboniser énorme tampon *;
           #fin si
fg_initpm ();
             if (fg_testmode (19,1) == 0) {
                printf ( "Ce programme nécessite une 320");
                ( "le mode x 200 graphiques MCGA \ n".) printf;
                sortie (1);
                 }
             fg_getmode old_mode = ();
             fg_setmode (19);
             fg_vbinit (); 
                                               Chapitre 9: Image Fichiers 187


#ifdef FG32
             buffer = (char *) malloc (64000);
          #elif défini (__ TURBOC__)
             buffer = (char énorme *) farmalloc (64000L);
           #autre
             buffer = (char énorme *) halloc (64000L, 1);
           #fin si
             if (tampon == NULL) {
                fg_setmode (old_mode);
                fg_reset ();
                printf ( "Impossible de créer la mémoire virtuelle. \ n");
                sortie (1);
                 }
             handle = fg_vbdefine (tampon, 320200);
             fg_vbopen (poignée);
status = fg_loadpcx ( "CORAL.PCX", 0);
             if (état == 0) {
                fg_vbpaste (0,319,0,199,0,199);
                fg_waitkey ();
                 }
fg_vbclose ();
             fg_setmode (old_mode);
             fg_reset ();
if (état == 1)
                printf ( "CORAL.PCX introuvable. \ n");
             else if (status == 2)
                printf ( "CORAL.PCX est pas un fichier PCX. \ n");
           }


Parce que leur structure parallèle à celle de la mémoire vidéo, fichiers PCX sont

spécifiques à certains modes vidéo. Si vous essayez d'afficher un fichier PCX dans un mode vidéo incompatible, fg_showpcx sera toujours afficher quelque chose, mais il sera tronqué. Le tableau suivant résume les modes vidéo compatibles pour les fichiers PCX.

Si le fichier PCX était Vous pouvez afficher
                  créé en mode dans ces modes
4, 5 4, 5
                  6, 11 6, 11, 13-18, 28, 29
                  9 9
                  13-18 13-18, 28, 29
                  19-27 19-27
                  28-29 13-18, 28, 29
Contrairement à fg_showpcx, fg_loadpcx ne montre pas une image PCX directement à

la mémoire vidéo. La routine fg_loadpcx convertit au lieu de la structure spécifique de mode du fichier PCX au format du buffer virtuel en mode indépendant comme il décompresse les données d'image. Cette surcharge signifie fg_showpcx est plus rapide que fg_loadpcx, mais fg_loadpcx permet d'afficher tous les fichiers PCX dans tous les modes graphiques vidéo. Le seul problème se produit lors de l'affichage d'une image PCX avec plus de couleurs que les supports actuels en mode vidéo (par exemple, afficher le Guide de l'utilisateur 188 Fastgraph


PCX 256 couleurs dans un mode 16 couleurs). Dans ce cas, fg_vbpaste affichera des pixels de couleur c dans la couleur c modulo n, où n est le nombre de couleurs disponibles dans le mode vidéo actuel.

La routine fg_pcxpal extrait la palette d'une image stockée dans un PCX

fichier.Son premier argument est un nom de fichier PCX, terminé par un octet nul comme fg_showpcx. Son second argument est l'adresse du tableau qui va recevoir les valeurs de la palette PCX. Les valeurs de la palette sont renvoyées en tant que composants de couleur RVB, chacune entre 0 et 63. Les trois premiers octets de ce tableau contiendra les valeurs RVB pour la couleur 0, les trois suivants pour la couleur 1, et ainsi de suite. La taille du tableau en octets doit être au moins trois fois le nombre de couleurs dans l'image PCX. En cas de succès, la valeur de retour de la fonction fg_pcxpal est le nombre de couleurs dans la palette PCX, 16 ou 256. Les valeurs possibles de retour d'erreur sont -1 (fichier non trouvé) et -2 (le fichier est pas un fichier PCX).

Pour les modes vidéo 18 et au-dessus, les valeurs de la palette fg_pcxpal conviennent

pour une utilisation avec fg_setdacs. Pour les modes graphiques EGA natifs (13 à 16), les valeurs de la palette doivent être converties en valeurs spécifiques au mode (avec fg_maprgb) avant d'être utilisé avec fg_palette ou fg_palettes. Si le fichier PCX comprend un (256 couleurs) palette étendue, fg_pcxpal retourne les valeurs dans la palette étendue. Sinon, elle retourne les valeurs de la palette de 16 couleurs dans l'en-tête de PCX.

La fonction de fg_pcxmode de Fastgraph détermine le mode vidéo optimal pour

l'affichage d'un fichier PCX. Par optimal, on entend le mode vidéo compatible ayant la plus basse résolution est supérieure ou égale aux dimensions de l'image. La routine de fg_pcxmode a un seul argument - l'adresse d'un tampon qui contient un en-tête de fichier PCX 128 octets. Des valeurs spécifiques définies dans certains domaines de l'en-tête de PCX déterminer quel mode vidéo est optimal. Une valeur de rendement positif de fg_pcxmode représente le nombre optimal de mode vidéo. Les retours d'erreurs sont -1 si le tampon ne contient pas un en-tête de PCX valide et -2 si fg_pcxmode ne peut pas trouver un mode vidéo compatible.

Une autre fonction utile de support PCX est fg_pcxrange, qui renvoie la

une information de position d'image à partir de l'en-tête PCX. Le premier argument de fg_pcxrange est l'adresse d'un tampon contenant un en-tête de fichier PCX 128 octets. Les quatre arguments restants reçoivent le minimum x, maximum x, y au minimum, et les valeurs y maximales de l'image PCX correspondante. Vous pouvez utiliser les extensions d'image pour déterminer les dimensions de l'image - par exemple, la largeur d'une image PCX serait maximum_x - minimum_x + 1.

Comment pouvons-nous l'en-tête d'un fichier PCX dans le tampon passé à

fg_pcxmode ou fg_pcxrange? Le plus simple est avec la fonction fg_pcxhead. Son premier argument est le nom du fichier PCX à partir duquel récupérer l'en-tête (comme avant, le nom du fichier doit être terminée par NULL). Le second argument est l'adresse de la mémoire tampon qui recevra l'en-tête de PCX. La taille de ce tampon doit être d'au moins 128 octets. En cas de succès, retourne fg_pcxhead zéro. Sinon, la valeur de retour est -1 si le fichier spécifié n'a pas pu être ouvert, ou -2 si le fichier est pas un fichier PCX. Après avoir lu avec succès l'en-tête PCX, vous pouvez passer à fg_pcxmode pour déterminer le mode vidéo optimal pour le fichier PCX. Des informations complètes sur l'en-tête de fichier PCX 128 octets figure à l'Annexe H.

Exemple 03.09 utilise fg_pcxhead, fg_pcxmode, fg_pcxpal de Fastgraph et

routines fg_pcxrange pour obtenir des informations sur le fichier CORAL.PCX. Il

Chapitre 9: Image Fichiers 189


affiche le numéro de mode vidéo optimal pour afficher l'image, les dimensions de l'image, et 16 premières valeurs de palette de couleurs de l'image.

Exemple 9-3.
#include <fastgraf.h>
   #include <stdio.h>
   #include <stdlib.h>
  void main (void);
void main ()
   {
     int i, j;
     int mode, le statut;
     int minx, maxx, Miny, maxy;
     unsigned char PCXpal [768];
     tête unsigned char [128];
fg_initpm ();
     status = fg_pcxhead ( "CORAL.PCX", en-tête);
     if (état == -1) {
        printf ( "Impossible de CORAL.PCX open \ n.");
        sortie (1);
         }
     else if (status == -2) {
        printf ( "CORAL.PCX est pas un fichier PCX. \ n");
        sortie (1);
         }
mode = fg_pcxmode (tête);
     printf ( "mode d'affichage optimal est% d \ n"., mode);
fg_pcxrange (en-tête, et mijaurée, & maxx, & Miny, & maxy);
     printf ( "Taille de l'image est de% d par% d pixels. \ n", maxx-minx + 1, Maxy-Miny + 1);
fg_pcxpal ( «CORAL.PCX», PCXpal);
     printf ( "16 premières valeurs de la palette sont: \ n");
      j = 0;
      for (i = 0; i <16; i ++) {
        printf ( "couleur% 2d: R =% 2d G =% 2d B =% 2d \ n",
           i, PCXpal [j], PCXpal [j + 1], PCXpal [j + 2]);
        j + = 3;
         }
   }


fichiers GIF

Le format de fichier GIF a été créé par CompuServe, Inc., en tant que transmission

format pour les images et les données graphiques sur le réseau CompuServe. Il a évolué dans ce qui est probablement le format de fichier d'image le plus populaire en usage aujourd'hui. les fichiers GIF sont particulièrement répandus sur les babillards et les réseaux de données électroniques parce que leurs résultats de compression d'image efficace dans moins d'espace de stockage et les temps de transmission plus rapides que d'autres formats de fichiers image. GIF, prononcé "JIF", est un acronyme de Graphics Interchange Format. Le format est le Guide de l'utilisateur 190 Fastgraph


la propriété de CompuServe, Inc., dont le GIF spécification "accorde une licence libre de redevance limitée, non exclusive pour l'utilisation du Graphics Interchange Format dans le logiciel informatique droit d'auteur; les logiciels informatiques utilisant GIF doit reconnaître la propriété du Graphics Interchange Format et sa marque de service par CompuServe, Inc., l'utilisateur et la documentation technique ".

Deux spécifications GIF, publié en 1987 et 1989, sont définis. En 1989,

spécification (connue sous le nom "89a") est un surensemble de la spécification originale 1987 (connu sous le nom "87a"). fichier GIF la routine d'affichage de Fastgraph peut gérer soit 87a ou 89a fichiers. Pour une portabilité maximale, la routine de création de fichier GIF produit toujours des fichiers conformes à la spécification 87a.

La routine fg_showgif affiche une image stockée dans un fichier GIF.  Ça peut

positionner l'image en utilisant les informations contenues dans l'en-tête de GIF de coordonnées, ou de telle sorte que son coin supérieur gauche est à la position graphique du curseur sur la page vidéo active ou tampon virtuel. Les arguments de fg_showgif sont les mêmes que pour les fg_showpcx, à l'exception du nom du fichier doit bien sûr référence à un fichier GIF plutôt que d'un fichier PCX. De même, les valeurs de retour fg_showgif sont analogues à celles de fg_showpcx.

La routine de fg_makegif crée un fichier GIF à partir du rectangle spécifié

région de la page vidéo active ou tampon virtuel. Ses arguments et la valeur de retour sont analogues à celles des fg_makepcx.

Exemple 9-4 utilise fg_showgif et fg_makegif pour créer un nouveau fichier GIF à partir

lignes sélectionnées d'un fichier existant 320x200 GIF 256 couleurs. Similaire à l'exemple 9-1, le programme utilise le fichier CORAL.GIF pour créer new.gif, mais il pourrait facilement être étendu à travailler avec tous les fichiers GIF. L'appel à fg_showgif affiche l'image en CORAL.GIF en utilisant la position de l'écran et les paramètres de la palette définie dans le fichier GIF. Après avoir attendu pendant une séquence de touches, le programme appelle fg_makegif pour créer un fichier GIF nommé new.gif de rangées de pixels 80 à 99 de l'image originale. Dans le cas où le programme rencontre des problèmes, il affiche un message d'erreur avant de quitter.

Exemple 9-4.
#include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
          void main (void);
void main ()
           {
             int old_mode;
             int READ_STATUS, write_status;
fg_initpm ();
             if (fg_testmode (19,1) == 0) {
                printf ( "Ce programme nécessite une 320");
                ( "le mode x 200 graphiques MCGA \ n".) printf;
                sortie (1);
                 }
             fg_getmode old_mode = ();
             fg_setmode (19);
READ_STATUS = fg_showgif ( "CORAL.GIF", 0); 
                                               Chapitre 9: Image Fichiers 191


fg_waitkey ();
             si (== READ_STATUS 0)
                write_status = fg_makegif (0,319,80,99, "new.gif");
              autre
                write_status = 1;
fg_setmode (old_mode);
             fg_reset ();
si (== READ_STATUS 1)
                printf ( "CORAL.GIF introuvable. \ n");
             else if (READ_STATUS == 2)
                printf ( "CORAL.GIF est pas un fichier GIF. \ n");
             if (write_status == 1)
                printf ( "new.gif pas créé. \ n");
           }


Comme fg_makepcx, la routine fg_makegif utilisera la palette par défaut

les paramètres lors de l'exécution sur Tandy et systèmes EGA. Affichage d'un fichier GIF à une résolution inférieure (par exemple, un fichier 640x480 GIF à 320x200) tronque l'affichage sur la droite et sur le fond. Cette affiche effectivement le coin supérieur gauche de l'image. Contrairement aux fichiers PCX, les fichiers GIF ne présentent pas de problèmes de compatibilité entre les modes graphiques 16 couleurs et 256 couleurs. Lorsque fg_showgif affiche un GIF 256 couleurs dans un mode 16 couleurs, il affiche des pixels de couleur c dans la couleur c modulo 16. Les fg_showgif et fg_makegif routines ont aucun effet en mode texte vidéo, ou dans les modes graphiques CGA et Hercules.

Fastgraph inclut des routines de support GIF supplémentaires analogues à celles pour

fichiers PCX. La routine fg_gifpal récupère la palette d'une image stockée dans un fichier GIF. Si le fichier GIF comprend une palette locale pour la première image, fg_gifpal retourne les valeurs de la palette locale. Sinon, fg_gifpal retourne les valeurs de la palette globale du fichier GIF. La fonction fg_gifmode détermine le mode vidéo optimal pour l'affichage d'un fichier GIF. La routine fg_gifrange renvoie l'information de position d'image à partir de l'en-tête du format GIF. La routine de fg_gifhead lit tête global d'un fichier GIF et premier en-tête locale dans un tableau de 23 octets (informations complètes sur les en-têtes apparaît à l'annexe H). Les paramètres et les valeurs de retour de ces routines sont les mêmes que pour leurs homologues PCX.

Exemple 9-5 utilise fg_gifhead, fg_gifmode, fg_gifpal de Fastgraph et

routines fg_gifrange pour obtenir des informations sur le fichier CORAL.GIF. Il affiche le numéro de mode vidéo optimal pour afficher l'image, les dimensions de l'image, et 16 premières valeurs de la palette de l'image.

Exemple 9-5.
#include <fastgraf.h>
   #include <stdio.h>
   #include <stdlib.h>
  void main (void);
void main ()
   {
     int i, j;
     int mode, le statut; 

Guide de l'utilisateur 192 Fastgraph


int minx, maxx, Miny, maxy;
     unsigned char GIFpal [768];
     tête unsigned char [23];
fg_initpm ();
     status = fg_gifhead ( "CORAL.GIF", en-tête);
     if (état == -1) {
        printf ( "Impossible de CORAL.GIF open \ n.");
        sortie (1);
         }
     else if (status == -2) {
        printf ( "CORAL.GIF est pas un fichier GIF. \ n");
        sortie (1);
         }
mode = fg_gifmode (tête);
     printf ( "mode d'affichage optimal est% d \ n"., mode);
fg_gifrange (en-tête, et mijaurée, & maxx, & Miny, & maxy);
     printf ( "Taille de l'image est de% d par% d pixels. \ n", maxx-minx + 1, Maxy-Miny + 1);
fg_gifpal ( «CORAL.GIF», GIFpal);
     printf ( "16 premières valeurs de la palette sont: \ n");
      j = 0;
      for (i = 0; i <16; i ++) {
        printf ( "couleur% 2d: R =% 2d G =% 2d B =% 2d \ n",
           i, GIFpal [j], GIFpal [j + 1], GIFpal [j + 2]);
        j + = 3;
         }
   }


fichiers FLI et FLC

Les fichiers FLI et FLC (fichiers appelés collectivement CIDF) contiennent des séquences de

trames d'image qui peuvent être affichées en succession rapide pour atteindre l'illusion du mouvement (ce qu'on appelle la lecture d'un fichier flac). Les fichiers FLI sont produites par Autodesk Animator et toujours avoir une résolution 320x200, tandis que les fichiers FLC sont produites par Autodesk Animator Pro et peuvent avoir une résolution. routines de fichiers de flic Fastgraph fonctionnent à la fois avec FLI et FLC fichiers, mais ils sont limités aux modes graphiques 256 couleurs parce que les fichiers contiennent toujours des images flic 256 couleurs. La première image d'un fichier flac est généralement une version compressée de l'image entière, tandis que les cadres ultérieurs sont des versions compressées des différences entre ce cadre et l'image précédente. Ce schéma de compression est souvent appelé compression delta dans la littérature de fichier flac.

Fastgraph inclut à la fois de haut niveau et bas niveau routines pour le travail

avec des fichiers flic. Le plus important de routine de haut niveau, fg_showflic, joue tout le contenu d'un fichier flac un certain nombre de fois. Il peut positionner l'image de telle sorte que son coin supérieur gauche est à l'origine de l'écran ou à la position graphique du curseur sur la page vidéo active ou tampon vitual. La routine fg_showflic attend trois arguments. Le premier est le nom du fichier flac, ce qui peut inclure un nom de chemin, mais il doit être mis fin null-. La seconde spécifie le nombre de fois pour lire le fichier flac. Si le nombre de jeu est nul, fg_showflic va jouer en continu. La routine fg_showflic va arrêter la lecture du FLIC

Chapitre 9: Image Fichiers 193


fichier si la touche Echap est enfoncée. Notez que ceci est le seul moyen d'arrêter la lecture du fichier flac si le nombre de jeu est égale à zéro (lecture continue).

Le troisième argument fg_showflic est un masque de bits qui contrôle comment l'image

est affiché.Dans la version actuelle de Fastgraph, seule la faible commande trois bits (0 à 2) de l'argument de masque de bits sont significatifs. Le tableau suivant résume la signification de ces bits.

Bit Valeur Signification
             0 0 Délai entre les trames comme indiqué dans l'entête FLIC
             0 1 Pas de retard entre les images
             1 0 Affichage image par rapport à l'origine de l'écran
             1 1 Affichage image par rapport à la position graphique actuelle
             2 0 données d'image d'affichage à partir du fichier spécifié FLIC
             2 1 données d'image d'affichage de la mémoire tampon de fg_imagebuf
             4 0 Utiliser les données de la palette dans le fichier flac
             4 1 Ignorer les données de la palette dans le fichier flac

Tous les autres bits sont réservés et doivent être zéro pour garantir la compatibilité avec les futures versions. La routine fg_showflic renvoie une valeur de 0 en cas de succès, 1 si le fichier spécifié n'a pas été trouvé, et 2 si le fichier est pas un fichier flac.

Exemple 9-6 est un lecteur de fichiers flac simple. Il utilise le standard VGA / MCGA

mode graphique 256 couleurs (mode 19) pour lire le fichier flac GLASS.FLI, l'un des exemples fournis avec Autodesk Animator. Le coin supérieur gauche du fichier flac sera à l'origine de l'écran, avec un retard entre les images tel que défini dans l'en-tête du fichier flac.

Exemple 9-6.
          #include <fastgraf.h>
           #include <stdio.h>
          void main (void);
void main (void)
           {
             statut int;
fg_initpm ();
             fg_setmode (19);
status = fg_showflic ( "GLASS.FLI", 1,0);
             if (état == 0) fg_waitkey ();
fg_setmode (3);
             fg_reset ();
if (état == 1)
                printf ( "GLASS.FLI introuvable. \ n");
             else if (status == 2)
                printf ( "GLASS.FLI est pas un FLI ou d'un fichier FLC. \ n");
           }


Fastgraph inclut des routines supplémentaires de soutien de FLIC similaires à ceux pour

fichiers PCX et GIF. La routine de fg_flichead lit le fichier spécifié de FLIC


Guide de 194 Fastgraph utilisateur


tête de 128 octets (informations complètes sur l'en-tête apparaît à l'annexe H). La fonction fg_flicmode détermine le mode vidéo optimal pour la lecture d'un fichier flac. Son seul argument est un tableau de 128 octets contenant un en-tête de fichier flac retourné par fg_flichead. En cas de succès, elle renvoie le numéro de mode vidéo optimal pour jouer l'image flac. Si le tableau ne contient pas un en-tête de fichier flac valide, fg_flicmode renvoie -1. La routine fg_flicsize renvoie les dimensions de l'image de l'en-tête flac. Son premier argument est un 128-byte-tête FLIC tableau, et deux autres arguments reçoivent la largeur de l'image et la taille en pixels. Exemple 9-7 utilise ces trois routines pour obtenir des informations sur le fichier GLASS.FLI. Il affiche le nombre optimal de mode vidéo pour la lecture du fichier flac, ainsi que les dimensions de l'image.

Exemple 9-7.
#include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
        void main (void);
void main ()
         {
           int mode, le statut;
           Largeur int, hauteur;
           tête unsigned char [128];
fg_initpm ();
           status = fg_flichead ( "GLASS.FLI", en-tête);
           if (état == -1) {
              printf ( "Impossible d'ouvrir GLASS.FLI \ n.");
              sortie (1);
               }
           else if (status == -2) {
              printf ( "GLASS.FLI est pas un FLI ou d'un fichier FLC. \ n");
              sortie (1);
               }
mode = fg_flicmode (tête);
           printf ( "mode d'affichage optimal est% d \ n"., mode);
fg_flicsize (en-tête, et la largeur, et hauteur);
           printf ( "Taille de l'image est de% d par% d pixels. \ n", largeur, hauteur);
         }


bas niveau des routines de Fastgraph fournissent flic la possibilité d'afficher FLIC

fichiers d'une image à la fois. Ceci est souhaitable lorsque votre programme doit effectuer d'autres tâches entre les images, ou pour jouer deux ou plusieurs fichiers flic en même temps. Pour utiliser bas niveau des routines de Fastgraph flic, appelez fg_flicopen pour chaque fichier flac. Le premier argument fg_flicopen est le nom du fichier flac. Le second argument est un tableau de 16 octets qui recevra un descripteur de contexte pour le fichier flac. Vous devez créer un descripteur de contexte avec fg_flicopen pour chaque fichier flac vous accéderez avec les routines de fichiers flic bas niveau (le nombre de fichiers flic vous pouvez avoir ouvert à un moment donné est limité par le spécificateur FICHIERS dans votre fichier CONFIG.SYS ). Le descripteur de contexte est ensuite transmis à d'autres routines pour accéder au fichier flac. En cas de succès, fg_flicopen remplit le descripteur de contexte, positionne le fichier flac à la première image, et renvoie zéro. le

Chapitre 9: Image Fichiers 195


les valeurs possibles de retour d'erreur sont -1 (fichier non trouvé) et -2 (le fichier est pas un FLI ou d'un fichier FLC).

La routine de fg_flicplay joue un ou plusieurs cadres à partir d'un fichier flac et

laisse le fichier placé au début de la trame suivante. Ses trois arguments sont les mêmes que pour fg_showflic sauf le premier argument est un descripteur de contexte au lieu d'un nom de fichier flac. Les progrès de routine fg_flicskip plus de cadres de fichiers. Flic Son premier argument est le contexte descripteur de fichier flac, et son second argument est le nombre d'images à sauter (si le nombre d'images est négative, la position du fichier est remis à la première image). Les deux routines renvoient le nombre d'images joué, ce qui peut être inférieur au nombre d'images demandées si le fichier de fin d'atteinte. dernière bas niveau FLIC routine, fg_flicdone de Fastgraph, ferme un fichier flac précédemment ouvert avec fg_flicopen. Son seul argument est le contexte descripteur du fichier flac.

Exemple 9-8 est similaire à l'exemple 9-6, mais il joue le fichier GLASS.FLI

une image à la fois à l'aide de bas niveau des routines de Fastgraph flic. Il ouvre le fichier flac avec fg_flicopen, qui renvoie un contexte descriptif de 16 octets pour le fichier. Si le fichier a été ouvert avec succès, le programme joue chaque trame en appelant fg_flicplay dans une boucle, en attente d'une frappe entre chaque trame (à noter que le masque de bits transmis à fg_flicplay a bit 0 ensemble, car il est généralement pas trop de sens pour retarder entre les cadres lors de la lecture des cadres individuellement). Finalement, nous arrivons à la fin de fichier, indiqué par une valeur de retour de fg_flicplay de zéro. Lorsque cela se produit, le programme appelle fg_flicdone et sort.

Exemple 9-8.
#include <fastgraf.h>
           #include <stdio.h>
          void main (void);
void main (void)
           {
             int trames;
             statut int;
             contexte de char [16];
fg_initpm ();
             fg_setmode (19);
status = fg_flicopen ( "GLASS.FLI", contexte);
             if (état == 0) {
                 faire {
                   images = fg_flicplay (contexte, 1,1);
                   fg_waitkey ();
                    }
                tandis que (cadres> 0);
                fg_flicdone (contexte);
                 }
fg_setmode (3);
             fg_reset ();
if (état == -1)
                printf ( "GLASS.FLI introuvable. \ n");
             else if (status == -2)   

Guide de l'utilisateur 196 Fastgraph


printf ( "GLASS.FLI est pas un FLI ou d'un fichier FLC. \ n");
           }


Pixel Fichiers Run

Fastgraph fournit également son propre format de fichier d'image en mode indépendant appelé

pixel Format exécuté. fichiers Pixel exécuter sont utiles dans les programmes qui doivent fonctionner dans différents modes vidéo (mais avec la même résolution) car vous pouvez utiliser les mêmes fichiers d'image pour les modes deux couleurs que pour les modes 256 couleurs. Deux variantes du format pixel d'exécution existent - fichiers standard pixel d'exécution (fichiers SPR) et les fichiers compressés de pixels exécuter (fichiers PPR). Le format pixel d'exécution emballé ne supporte pas les 256 images couleur mais produira un fichier plus petit si l'image a 16 couleurs ou moins. les fichiers de pixels exécuter ne comprennent pas un en-tête ou toute autre information de palette de couleurs.

La meilleure façon d'illustrer le format de fichier d'exécution de pixel est un exemple.

Supposons que nous voulons afficher un petit triangle dont le périmètre est une couleur différente de celle de son intérieur. Pour créer l'équivalent pixel d'exécution standard de cette image, nous devons inscrire le triangle dans une zone rectangulaire. Par conséquent, la représentation de pixel de notre triangle pourrait se présenter comme suit:

 .  .  .  . *.  .  .  .
                              .  .  . * X * .  .  .
                              .  . * Xxx *.  .
                              . * Xxxxx *.
                              * * * * * * * * *
Comme le montre ce diagramme, l'image de notre triangle est neuf pixels de large à son

base et cinq pixels de haut. Les pixels indiqués par un astérisque (*) sont le périmètre du triangle, tandis que celles qui sont indiquées par un x représentent ses points intérieurs. Les pixels affichés comme des périodes (.) Ne font pas partie du triangle lui-même, mais ils font partie de l'image. Dans cet exemple, nous pouvons les traiter comme des pixels de fond.

Si nous commençons dans le coin inférieur gauche de l'image et de passer à la

droit, nous pourrions représenter la première rangée de l'image comme neuf pixels de couleur "astérisque". Un tel groupe de pixels consécutifs de même couleur est appelé une course de pixels, donc un seul passage de pixel décrit la première ligne de l'image. La ligne ci-dessus celui-ci est un peu plus complexe. Il se compose de cinq points de pixels: un pixel de couleur "période", suivie par l'une des couleurs "astérisque", puis cinq de la couleur "x", l'une des couleurs "astérisque", et enfin l'une des couleurs «période».

Alors que nous pourrions construire séries de pixels séparés pour chaque ligne de l'image,

notez que trois des cinq lignes dans notre triangle commencent avec le même pixel de couleur que le pixel plus à droite de la rangée précédente. Les formats pixel d'exécution de Fastgraph vous permettent de tirer parti de cette propriété en permettant pixel pistes pour envelopper d'une rangée à l'autre. Cela signifie que nous pouvons représenter la course de pixel de couleur «période» étendant à partir du côté droit de la deuxième rangée sur le côté gauche de la troisième rangée en une seule série de trois pixels.

Une course de pixel standard (SPR) fichier est rien de plus qu'une telle séquence de

(Couleur, compter) paires, comme le montre le schéma ci-dessous.

Chapitre 9: Image Fichiers 197


octet 0 couleur pour la course 1
1 chef d'accusation pour la course 1
2 couleurs pour la course 2
3 compte pour la course 2


2n-2 couleurs pour la course n
2n-1 chef d'accusation pour la course n


Chaque couleur est une valeur entre 0 et 255 spécifiant l'index de couleur pour ce pixel terme. Chaque chef d'accusation est une valeur entre 0 et 255 spécifiant la longueur en pixels de ce pixel terme. Si un seul passage dépasse 255 pixels, il doit être divisé en deux ou plusieurs pistes. Par exemple, nous pourrions représenter une course de pixels de longueur 265 comme une course de longueur 255 suivie d'une course de longueur 10 de la même couleur. Notez que l'espace en octets nécessaires pour stocker une image SPR est deux fois le nombre de pistes.

fg_showspr affiche de routine de Fastgraph un fichier SPR. Son premier argument

est le nom du fichier contenant l'image (il peut inclure un nom de chemin). Le nom du fichier doit se terminer par un caractère nul, donc les programmeurs BASIC, FORTRAN et Pascal auront besoin de stocker un octet nul comme le dernier caractère de la chaîne de nom de fichier. Le second argument est la largeur en pixels de l'image. Les affichages de routine fg_showspr l'image de telle sorte que son coin inférieur gauche est à la position du curseur graphique. Les valeurs de retour possibles pour fg_showspr sont succès (0) et fichier non trouvé (1). Pour créer un fichier SPR, utilisez la routine fg_makespr. Ses arguments et les valeurs de retour sont les mêmes que pour fg_makepcx et fg_makegif.

Exemple 9-9 utilise fg_showspr et fg_makespr pour créer un nouveau fichier SPR à partir

lignes sélectionnées d'un 16-couleur fichier 320x200 SPR existant. Semblable à des exemples 9-1 et 9-4, le programme utilise le fichier CORAL.SPR pour créer NEW.SPR, mais il pourrait facilement être étendu à travailler avec tous les fichiers SPR. L'appel à fg_move établit le coin inférieur gauche de l'écran que la position du curseur graphique (contraste avec le coin supérieur gauche étant le point PCX, GIF et flic référence). Le programme appelle ensuite fg_showspr pour afficher l'image. Après avoir attendu pendant une séquence de touches, le programme appelle fg_makespr pour créer un fichier SPR nommé NEW.SPR de rangées de pixels 80 à 99 de l'image originale. Dans le cas où le programme rencontre des problèmes, il affiche un message d'erreur avant de quitter.

Exemple 09.09.
#include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
          void main (void);
void main ()   

Guide de l'utilisateur 198 Fastgraph


 {
             int new_mode, old_mode;
             int READ_STATUS, write_status;
fg_initpm ();
             new_mode = fg_bestmode (320,200,1);
             if (new_mode <0 || new_mode == 12) {
                printf ( "Ce programme nécessite une 320");
                ( "le mode x 200 graphiques couleur \ n".) printf;
                sortie (1);
                 }
             fg_getmode old_mode = ();
             fg_setmode (new_mode);
             fg_move (0199);
READ_STATUS = fg_showspr ( "CORAL.SPR", 320);
             fg_waitkey ();
             si (== READ_STATUS 0)
                write_status = fg_makespr (0,319,80,99, "NEW.SPR");
              autre
                write_status = 1;
fg_setmode (old_mode);
             fg_reset ();
si (== READ_STATUS 1)
                printf ( "CORAL.SPR introuvable. \ n");
             if (write_status == 1)
                printf ( "NEW.SPR pas créé. \ n");
           }


Si vous avez une image qui utilise uniquement les 16 premiers indices de couleur (0 à 15),

vous pouvez utiliser emballés piste de pixel (PPR) le format d'image de Fastgraph. Ce format emballe deux valeurs de couleur dans chaque octet de couleur, donc il faut trois octets au lieu de quatre pour représenter deux séries de pixels. Cela signifie un fichier PPR est 25% plus petit que son équivalent de SPR. Dans chaque série de trois octets, les quatre bits de poids fort du premier octet contiennent la couleur de la première manche, et les quatre bits de poids faible contiennent la couleur de la deuxième manche. Le deuxième octet contient la longueur de la première manche, et le troisième octet contient la longueur de la deuxième manche.

Le schéma suivant illustre la structure du fichier de pixel emballé.

Dans cet exemple, le fichier est supposé contenir n pixels pistes, où n est un nombre pair. Si n est impair, l'octet de décalage pour le dernier élément est 3n / 2 (tronquée) au lieu de 3n / 2-1, et les quatre bits de poids faible du dernier octet de couleur (qui est, la couleur de pixel run n + 1) sont ignorés.

7 4 3 0
octet 0 couleur pour la course 1 couleur pour la course 2
1 chef d'accusation pour la course 1
2 compte pour la course 2
3 couleurs pour la course 3 couleurs pour la course 4   
                                               Chapitre 9: Image Fichiers 199


4 compte pour la course 3
5 compte pour la course 4


3n 2-3 couleur / pour la course n-1 couleur pour la course n
3n 2-2 comte / pour la course n-1
3n count / 2-1 pour la course n


La structure du fichier PPR permet des valeurs de couleur entre 0 et 15,

et exécuter des longueurs entre 0 et 255. L'espace en octets nécessaires pour stocker une image au format PPR est de 1,5 fois le nombre de pistes, par rapport à deux fois le nombre de pistes pour le format SPR.

L'affichage fg_showppr et fg_makeppr routines et créer des fichiers PPR,

respectivement.Leurs arguments et les valeurs de retour sont les mêmes que celles de fg_showspr et fg_makespr. Si nous voulions afficher les fichiers PPR au lieu de fichiers SPR dans l'exemple 9-9, tout ce qui est nécessaire est en train de changer le fg_showspr et fg_makespr appelle à fg_showppr et fg_makeppr.

fg_dispfile affiche de routine à la fois SPR et PPR dossiers de Fastgraph.  le

premier de ses trois arguments est le nom du fichier image (il peut inclure un nom de chemin). Le nom du fichier doit se terminer par un caractère nul, donc les programmeurs BASIC, FORTRAN et Pascal auront besoin de stocker un octet nul comme le dernier caractère de la chaîne de nom de fichier. Le second argument est la largeur de l'image en pixels, et le troisième argument définit le format d'image (qui est, SPR ou PPR). Comme avec d'autres routines d'affichage pixel de l'exécution, fg_dispfile affiche l'image de telle sorte que son coin inférieur gauche est à la position du curseur graphique.

Exemple 9-10 montre comment utiliser fg_dispfile pour afficher une image

stockée dans un fichier pixel de l'exécution. Le programme affiche deux images identiques, l'un dans un fichier SPR et l'autre dans un fichier PPR. Chaque image est une image du fond de la mer et certains coraux, comme on pourrait être utilisé pour l'arrière-plan dans un aquarium. Le programme fonctionne dans un mode graphique 320x200, et les images de remplir tout l'écran.

L'image SPR est dans le fichier CORAL.SPR. Le programme fg_move utilise pour établir

le coin inférieur gauche de l'écran comme la position graphique du curseur et appelle ensuite fg_dispfile pour afficher l'image. La valeur du troisième argument de fg_dispfile dit Fastgraph le format d'image. Une valeur de 0 indique que le fichier contient une image au format SPR, tandis qu'une valeur de 1 indique une image au format PPR. Comme mentionné précédemment, l'image remplit tout l'écran, de sorte que sa largeur est de 320 pixels.

Après avoir attendu pendant une séquence de touches, le programme efface l'image précédente de

l'écran et appelle ensuite fg_dispfile pour afficher l'image PPR à partir du fichier CORAL.PPR. Le programme laisse la deuxième image sur l'écran jusqu'à ce qu'un autre keypress, au moment où il restaure le mode vidéo et écran attributs et retours originaux à DOS. Guide de l'utilisateur 200 Fastgraph


Exemple 9-10.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  int old_mode, new_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_move (0199);
                  fg_dispfile ( "CORAL.SPR", 320,0);
                  fg_waitkey ();
fg_erase ();
                  fg_dispfile ( "CORAL.PPR", 320,1);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


L'utilitaire INSTANTANÉ distribué avec Fastgraph est une fin et rester

programme résident (TSR) qui peut capturer des images d'écran en mode graphique et de les enregistrer dans des fichiers SPR. Ainsi, vous pouvez facilement créer des fichiers avec INSTANTANÉ et les afficher avec fg_showspr ou fg_dispfile. Un autre utilitaire TSR, GrabRGB, est utile pour capturer les valeurs des couleurs RVB à partir d'images de 256 couleurs. L'annexe A contient une description complète des utilitaires INSTANTANÉ et GrabRGB.


Afficher Patterns

Exemple 9-10 fonctionne bien dans les modes graphiques vidéo avec 16 ou 256

couleurs disponibles. Cependant, dans les quatre couleurs CGA graphiques modes de l'image résultante est pas trop bon à cause de nos choix de couleurs limitées, et ce sera encore pire dans le mode graphique Hercules. La fg_pattern routine Fastgraph vous permet d'associer un motif de tramage (en fait, toute séquence de pixels) avec l'un des 256 indices de couleur de Fastgraph apparaissant dans une carte pixel de l'exécution. Lors de l'affichage d'un fichier SPR ou PPR, Fastgraph utilisera le modèle associé à cet indice de couleur au lieu d'afficher la couleur elle-même.

 Chapitre 9: Image Fichiers 201


 La routine fg_pattern nécessite deux arguments entiers - un indice de couleur

(Entre 0 et 255) et le motif d'affichage défini pour que l'indice de couleur. La structure d'un motif d'affichage ressemble à la structure de la mémoire vidéo, et est donc dépendant du mode vidéo en cours. Les sections suivantes répertorient les modes d'affichage initiaux et expliquent comment construire de nouveaux modèles d'affichage pour différents modes graphiques vidéo.

modes quatre couleurs graphiques CGA

 Dans les modes graphiques quatre couleurs CGA (modes 4 et 5), le motif d'affichage

se compose d'un compteur de décalage de 8 bits suivi d'un motif de pixels de 8 bits. Chaque pixel prend une valeur comprise entre 0 et 3, de sorte que le motif représente quatre pixels. En rangées de pixels numérotées paires, Fastgraph utilise le motif de pixel lui-même. Dans impaires rangées de pixels, Fastgraph fait tourner le modèle original à la gauche du nombre de bits spécifié par le nombre de changement de vitesse.

 Par exemple, si nous utilisons la valeur par défaut CGA palette de couleurs, nous pourrions

créer une teinte plus foncée de cyan en alternant pixels cyan (couleur 1, 01 binaire) avec des pixels blancs (couleur 3, 11 binaires), comme indiqué ici:


 01 11 01 11


Si nous convertissons ce modèle de pixel à son équivalent hexadécimal, on obtient la valeur 77.

 Pour compléter le modèle d'affichage, il faut déterminer le nombre de changement de vitesse.  Si

nous utilisons un compte de décalage de zéro, l'affichage résultant sera simplement une série de cyan et des lignes verticales blanches. Ce que nous avons vraiment besoin est un effet de damier où un pixel blanc est au-dessus et en dessous de chaque pixel cyan, et vice versa.Si nous faisons tourner le motif d'un pixel (deux bits) vers la gauche, nous allons obtenir l'effet désiré. Autrement dit, un compteur de décalage de deux produit des motifs de pixels suivants:

lignes paires 01 11 01 11
                      lignes impaires 11 01 11 01

Combinant le compte de décalage avec le motif de pixels donne le motif d'affichage 0277 hex. Le comptage de décalage est normalement un multiple de deux; Notez qu'un zéro des résultats de comptage de décalage dans le même motif étant appliqué à toutes les lignes de pixels.

Pour les modes de quatre couleurs graphiques les CGA, fg_setmode établit la

motifs d'affichage initiaux suivants:

couleur compte de décalage hexadécimal
                     index et modèle équivalent
0 0 00000000 0000
                       1 0 01010101 0055
                       2 0 10101010 00AA
                       3 0 11111111 00FF

Ces valeurs sont répétées comme nécessaire de définir des indices de couleur 4 à 255. Autrement dit, couleurs 4, 8, 12, ..., 252 utilisent les mêmes valeurs par défaut que la couleur 0. Couleurs 5, 9, 13, ..., 253 utilisation les mêmes défauts que la couleur 1, et ainsi de suite. A noter également que le Guide 202 Fastgraph utilisateur


modèle 0000 représente quatre pixels de couleur 0, 0055 représente quatre pixels de couleur 1, 00AA représente quatre pixels de couleur 2, et 00FF représente quatre pixels de couleur 3.

CGA mode deux graphiques en couleur

Dans le mode graphique en deux couleurs CGA (mode 6), le motif d'affichage aussi

se compose d'un compteur de décalage de 8 bits suivi d'un motif de pixels de 8 bits. Chaque pixel prend la valeur 0 ou 1, de sorte que le motif représente huit pixels. En rangées de pixels numérotées paires, Fastgraph utilise le motif de pixel lui-même. Dans impaires rangées de pixels, Fastgraph fait tourner le modèle original à la gauche du nombre de bits spécifié par le nombre de changement de vitesse.

Par exemple, nous pourrions créer une nuance de blanc en alternant

pixels noirs (couleur 0) avec des pixels blancs (couleur 1), comme montré ici:


0 1 0 1 0 1 0 1


Si nous convertissons ce modèle de pixel à son équivalent hexadécimal, on obtient la valeur 55.

Pour compléter le modèle d'affichage, il faut déterminer le nombre de changement de vitesse.  nous

doit faire pivoter le motif d'un pixel (un bit) vers la gauche pour obtenir l'effet de damier, comme dans les modes graphiques CGA quatre couleurs. Autrement dit, un nombre de décalage d'un produit des motifs de pixels suivants:

lignes paires 0 1 0 1 0 1 0 1
                    lignes impaires 1 0 1 0 1 0 1 0

Combinant le compte de décalage avec le motif de pixels donne le motif d'affichage 0155 hex.

Pour le mode deux couleurs graphiques CGA, fg_setmode établit la première

motifs d'affichage de telle sorte que tous les indices de couleur à numérotation paire sont affectées à la valeur 0000, alors que tous les indices de rang impair couleur sont affectés de la valeur 00FF. Notez que modèle 0000 représente huit pixels de couleur 0, et 00FF représente huit pixels de couleur 1.

mode 16 graphique couleur Tandy / PCjr

Dans le mode 16-graphique couleur Tandy / PCjr (mode 9), le motif d'affichage

consiste également en un compteur à décalage à 8 bits suivi d'un motif de pixels de 8 bits. Chaque pixel prend une valeur comprise entre 0 et 15, de sorte que le motif représente deux pixels. En rangées de pixels numérotées paires, Fastgraph utilise le motif de pixel lui-même. Dans impaires rangées de pixels, Fastgraph fait tourner le modèle original à la gauche du nombre de bits spécifié par le nombre de changement de vitesse.

Par exemple, nous pourrions créer une nuance de bleu en alternant bleu

pixels (couleur 1, 0001 binaire) avec des pixels blancs (couleur 15, 1111 binaires), comme indiqué ici:


0001 1111   
                                               Chapitre 9: Image Fichiers 203


Si nous convertissons ce modèle de pixel à son équivalent hexadécimal, nous obtenons la valeur 1F.

Pour compléter le modèle d'affichage, il faut déterminer le nombre de changement de vitesse.

En utilisant le même processus que dans les modes les graphiques CGA, il faut faire pivoter le motif d'un pixel (quatre bits) vers la gauche pour obtenir l'effet de damier. Autrement dit, un compteur de décalage de quatre donne les motifs de pixels suivants:

lignes paires 0001 1111
                       lignes impaires 1111 0001

Combinant le compte de décalage avec le motif de pixels donne le motif d'affichage 041F hex. Le nombre de changement de vitesse est normalement zéro ou quatre; Notez qu'un zéro des résultats de comptage de décalage dans le même motif étant appliqué à toutes les lignes de pixels.

Pour les modes graphiques 16-couleur Tandy / PCjr, fg_setmode établit la

motifs initiaux d'affichage de telle sorte que la couleur 0 est attribuée la valeur 0000 (deux pixels de couleur 0), la couleur 1 reçoit la valeur 0011 (deux pixels de couleur 1), la couleur 2 reçoit la valeur 0022 (deux pixels de 2 couleurs), et ainsi de suite. Ces valeurs sont répétées comme nécessaire de définir des indices de couleur 16 à 255. C'est, les couleurs 0, 16, 32, ..., 240 utilisent les mêmes valeurs par défaut que la couleur 0. Couleurs 1, 17, 33, ..., 241 utilisation les mêmes défauts que la couleur 1, et ainsi de suite.

modes graphiques Hercules

La structure des modèles d'affichage pour les modes les graphiques Hercules

(modes 11 et 12) est le même que deux des modes les graphiques CGA. Pour le mode graphique Hercules standard (mode 11), s'il vous plaît se référer à la discussion des CGA deux couleurs (mode 6) des modèles d'affichage. Pour le Hercules mode graphique basse résolution (mode 12), s'il vous plaît se référer à la discussion des quatre couleurs CGA (mode 4) des modèles d'affichage.

modes / VGA / SVGA 16 couleurs graphiques EGA

Dans les modes les EGA / VGA / SVGA 16 couleurs graphiques (modes 13 à 16, 18, 28 et

29), le motif d'affichage se compose de deux valeurs de couleur de 4 bits (par souci de cohérence avec les autres modes vidéo, nous passons toujours le motif d'affichage comme une quantité de 16 bits ou 32 bits). Chaque pixel prend une valeur comprise entre 0 et 15 (0 et 5 en mode graphique monochrome EGA), de sorte que le motif représente deux pixels. En même- rangées de pixels numérotées, Fastgraph utilise le motif de pixel lui-même. Dans les lignes de pixels impaires, Fastgraph fait pivoter le motif initial d'un pixel (quatre bits) vers la gauche.

Par exemple, nous pourrions créer une nuance de bleu en alternant bleu

pixels (couleur 1, 0001 binaire) avec des pixels blancs (couleur 15, 1111 binaires), comme indiqué ici:


0001 1111


Si nous convertissons ce modèle de pixel à son équivalent hexadécimal, nous obtenons la valeur 1F. Le compte de décalage à quatre bits implicite produit les motifs de pixels suivants: Guide de l'utilisateur 204 Fastgraph


lignes paires 0001 1111
                       lignes impaires 1111 0001

Extension du motif de pixels à une quantité de 16 bits ou 32 bits donne le motif d'affichage 001F hex.

Pour les modes graphiques 16 couleurs les EGA / VGA / SVGA, fg_setmode établit la

motifs initiaux d'affichage de telle sorte que la couleur 0 est attribuée la valeur 0000 (deux pixels de couleur 0), la couleur 1 reçoit la valeur 0011 (deux pixels de couleur 1), la couleur 2 reçoit la valeur 0022 (deux pixels de 2 couleurs), et ainsi de suite. Ces valeurs sont répétées comme nécessaire de définir des indices de couleur 16 à 255. C'est, les couleurs 0, 16, 32, ..., 240 utilisent les mêmes valeurs par défaut que la couleur 0. Couleurs 1, 17, 33, ..., 241 utilisation les mêmes défauts que la couleur 1, et ainsi de suite.

MCGA / VGA mode graphique 2 couleurs

Dans le MCGA / mode graphique VGA à deux couleurs (mode 17), le motif d'affichage

se compose de deux valeurs de couleur de 1 bit (par souci de cohérence avec les autres modes vidéo, nous passons toujours le motif d'affichage comme une quantité de 16 bits ou 32 bits). Chaque pixel prend la valeur 0 ou 1, de sorte que le motif représente deux pixels. En même- rangées de pixels numérotées, Fastgraph utilise le motif de pixel lui-même. Dans les lignes de pixels impaires, Fastgraph fait tourner le modèle original d'un pixel (un bit) vers la gauche.

Par exemple, nous pourrions créer une nuance de blanc en alternant

pixels noirs (couleur 0) avec des pixels blancs (couleur 1), comme montré ici:


0 1


Si nous convertissons ce modèle de pixel à son équivalent hexadécimal, nous obtenons la valeur 01. Le nombre de décalage d'un bit implicite produit les motifs de pixels suivants:

lignes paires 0 1
                          lignes impaires 1 0

Extension du motif de pixels à une quantité de 16 bits ou 32 bits donne le motif d'affichage 0001 hex.

Pour le mode deux couleurs graphique VGA / MCGA, fg_setmode établit la

les modèles d'affichage initiaux de telle sorte que tous les indices de couleur à numérotation paire sont affectées à la valeur 0000 (deux pixels de couleur 0), tandis que tous les indices de rang impair couleur sont affectés de la valeur 0003 (11 binaire ou deux pixels de la couleur 1).

modes graphiques 256 couleurs

Les modes graphiques 256 couleurs (modes 19 à 27) offrent 262144

couleurs différentes, de sorte que le tramage est rarement (voire jamais) nécessaires. Pour cette raison, fg_pattern n'a pas d'effet dans ces modes vidéo.

Chapitre 9: Image Fichiers 205


Un exemple

Exemple 9-11 illustre l'utilisation de motifs d'affichage dans plusieurs graphiques

modes. Ce programme fonctionne dans un mode graphique couleur 320x200 et affiche l'image CORAL.PPR avec un ou plusieurs des indices de couleur redéfinie. Si le programme fonctionne dans le CGA mode quatre couleurs standard (mode 4), il redéfinit les 16 premiers motifs d'affichage en utilisant la routine fg_pattern et les valeurs dans le tableau CGApatterns. Dans le mode Tandy / PCjr 16 couleurs graphiques (mode 9) et le mode graphique basse résolution EGA (mode 13), le programme redéfinit l'indice de couleur 15 pour produire un motif de tramage gris et blanc en alternance. Dans le MCGA 256- mode couleur (mode 19), les modèles d'affichage ne sont pas disponibles, de sorte que le programme fg_setrgb utilise pour définir l'indice de couleur 15 comme légèrement teinte plus foncée de gris que la valeur par défaut pour la couleur 7.

Exemple 9-11.
#include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
              void main (void);
int CGApatterns [] = {
                 0x0000,0x00FF, 0x00FF, 0x00FF,
                 0x02BB, 0x0000,0x0222,0x0255,
                 0x00FF, 0x00FF, 0x00FF, 0x0055,
                 0x00AA, 0x00AA, 0x00FF, 0x0277
                  };
void main ()
               {
                 Couleur int;
                 int old_mode, new_mode;
fg_initpm ();
                 new_mode = fg_bestmode (320,200,1);
                 if (new_mode <0 || new_mode == 12) {
                    printf ( "Ce programme nécessite une 320");
                    ( "le mode x 200 graphiques couleur \ n".) printf;
                    sortie (1);
                     }
fg_getmode old_mode = ();
                 fg_setmode (new_mode);
if (new_mode == 4) {
                    fg_palette (0,0);
                    pour (couleur = 0; couleur <16; couleur ++)
                       fg_pattern (couleur, CGApatterns [color]);
                     }
                 else if (new_mode == 9 || new_mode == 13)
                    fg_pattern (15,0x04F7);
                  autre
                    fg_setrgb (15,38,38,38);
fg_move (0199);
                 fg_showppr ( «CORAL.PPR», 320); 

Guide de l'utilisateur 206 Fastgraph


fg_waitkey ();
fg_setmode (old_mode);
                 fg_reset ();
               }


Contrôle de l'image Buffer Size

Par défaut, tous affichage du fichier image et de création de routines de Fastgraph

utiliser un tampon 4096 octets interne. Ce tampon fournit une zone de stockage intermédiaire, ce qui permet d'effectuer plus efficace tamponnée I / O lors de la lecture ou l'écriture des fichiers d'image. La routine de fg_imagebuf vous permet de définir votre propre tampon à cet effet (la taille du tampon est limitée à 64K octets en mode réel et en mode protégé 16 bits). Grandes tampons font généralement l'affichage de l'image et la création plus rapide. Cela est particulièrement vrai en mode protégé et lors de la lecture des fichiers flic. Appel fg_setmode réinitialise le tampon de fg_imagebuf à sa taille 4K par défaut.

La routine de fg_imagebuf ne pas allouer le stockage de l'interne

tampon. Au contraire, il définit simplement le tableau ou allouée dynamiquement bloc de mémoire à utiliser comme tampon. Le premier argument passé à fg_imagebuf est l'adresse de ce bloc de tableau ou de la mémoire, et le second argument est la taille de la mémoire tampon interne en octets, représentée comme un entier non signé. Dans les modes 32 bits, l'adresse est passé comme un proche de pointeur ordinaire, tandis que dans les modes 16 bits, il est passé comme un pointeur loin (segmenté). Fastgraph utilise un pointeur loin dans les modes 16 bits pour éviter de gaspiller l'espace précieux dans le segment de données par défaut, et il entraîne presque toujours la possibilité d'utiliser un tampon plus grand. Dans les programmes Pascal en mode réel, l'espace pour le buffer interne doit être allouée de façon dynamique à la procédure GetMem car elle fournit la seule façon de transmettre quelque chose par référence loin dans Pascal. programmes Pascal en mode protégé peuvent utiliser GetMem ou la fonction GlobalAllocPtr d'allouer la mémoire tampon. programmes BASIC doivent passer le tampon d'image en tant que chaîne de longueur fixe.

Exemple 9-12 montre comment utiliser fg_imagebuf pour définir un tampon plus grand lorsque

afficher le fichier CORAL.PCX. Dans cet exemple, nous allons utiliser un tableau statique 20,000 octets comme le tampon d'image. Cette taille a été choisie car elle est plus grande que la taille du fichier PCX, alors fg_showpcx peut lire le fichier PCX ensemble en une seule passe.

Exemple 9-12.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
#ifdef FG32
               char buffer [20000];
                #autre
               carboniser loin tampon [20000];
                #fin si
void main ()
                {
                  int old_mode; 
                                               Chapitre 9: Image Fichiers 207


fg_initpm ();
                  if (fg_testmode (19,1) == 0) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques MCGA \ n".) printf;
                     sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (19);
                  fg_imagebuf (tampon, 20000);
                  fg_showpcx ( "CORAL.PCX", 0);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


Vous ne devez pas créer des tampons séparés pour chaque image que vous affichez ou

Créer. Une fois que vous définissez un tampon d'image interne avec fg_imagebuf, Fastgraph utilisera ce tampon jusqu'à ce que votre programme se termine, ou jusqu'à ce que vous appelez fg_imagebuf avec une taille de tampon égal à zéro.

Il est également possible d'afficher PCX, GIF et images FLI / FLC directement à partir de

le tampon pointé par fg_imagebuf. Cela peut être très utile, par exemple, lorsque nous avons besoin d'afficher plusieurs fois le même fichier d'image parce que nous ne lisons le fichier à partir du disque une fois. Pour ce faire, le bit 2 du paramètre flags lors de l'utilisation PCX, GIF, ou FLI / FLC routines d'affichage d'image de Fastgraph. Ceci indique Fastgraph pour récupérer les données d'image provenant de la mémoire tampon de fg_imagebuf plutôt qu'à partir du fichier lui-même. Dans les applications en mode protégé, en utilisant cette méthode fournit habituellement de meilleures performances, en particulier lors de l'affichage des fichiers FLI ou FLC. Exemple 9-13 montre comment afficher une image PCX stockée dans la mémoire tampon de fg_imagebuf.

Exemple 9-13.
#include <fastgraf.h>
             #include <io.h>
              #include <stdio.h>
              #include <stdlib.h>
             void main (void);
#ifdef FG32
             char buffer [20000];
              #autre
             carboniser loin tampon [20000];
              #fin si
void main ()
              {
                int file_size;
                int old_mode;
                 * FILE stream;
fg_initpm ();
                if (fg_testmode (19,1) == 0) {   

Guide de l'utilisateur 208 Fastgraph


printf ( "Ce programme nécessite une 320");
                   ( "le mode x 200 graphiques MCGA \ n".) printf;
                   sortie (1);
                    }
flux = fopen ( "CORAL.PCX", "rb");
                file_size = (int) (filelength (fileno (flux)));
                fread (tampon, 1, file_size, flux);
                fclose (flux);
fg_getmode old_mode = ();
                fg_setmode (19);
fg_imagebuf (tampon, file_size);
                fg_showpcx ( "", 4);
                fg_waitkey ();
fg_setmode (old_mode);
                fg_reset ();
              }


Dans l'exemple 9-13, nous utilisons un tableau de 20.000 octets pour le tampon de fg_imagebuf.

Le réseau utilisé avec fg_imagebuf doit être suffisante pour maintenir le fichier image toute grande. Notez que nous passons la taille réelle du fichier à fg_imagebuf (dans cet exemple, nous supposons que la taille du fichier ne dépasse pas 20.000 octets). Il est crucial que vous spécifiez la taille réelle du fichier lors de l'affichage de 256 couleurs fichiers PCX donc Fastgraph peut localiser l'étendue (256 couleurs) les données de la palette qui pourraient suivre les données d'image. Vous devez également spécifier la taille réelle du fichier lors de l'utilisation de bas niveau des routines de soutien de Fastgraph flic jouer images flic de la mémoire tampon de fg_imagebuf. Pour les autres types de fichiers d'images, nous pouvons spécifier la taille du fichier ou la taille du tampon.

Il est pas nécessaire de passer un nom de fichier pour les routines d'affichage d'image si

les données d'image réside dans le tampon de fg_imagebuf. En d'autres termes, les routines d'affichage d'image ignorer l'argument de nom de fichier lorsque le bit 2 de l'argument flags est réglé. Cependant, vous devez toujours inclure un argument "lieu de titulaire", où l'on pourrait attendre d'un nom de fichier. Nous vous recommandons d'utiliser la chaîne vide comme dans l'appel fg_showpcx d'exemple 9-13, bien que toute chaîne peut être utilisée à la place.

La taille maximale du fichier d'image, nous pouvons afficher à partir du fg_imagebuf

le tampon est bien sûr limitée à la taille du tampon. Bien que ce soit pas en cause dans le mode 32 bits protégé, il n'impose une restriction importante en mode réel et en mode protégé 16 bits. La taille de la mémoire tampon de fg_imagebuf est limitée à 64K octets dans des environnements 16 bits, ce qui signifie cette fonction ne concerne que les fichiers d'image qui sont 64K ou moins si vous utilisez le mode réel ou en mode protégé 16 bits.


Résumé des Routines de fichier image

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph. Les fonctions d'affichage d'image et de création appliquent uniquement aux modes graphiques vidéo.

Chapitre 9: Fichiers d'images 209


FG_DISPFILE affiche une image stockée dans une course de pixel standard ou emballé

fichier. L'image est positionnée de sorte que son coin inférieur gauche est à la position graphique actuelle.

FG_FLICDONE ferme le fichier flac associé au contexte spécifié

descripteur.

FG_FLICHEAD lit un en-tête de fichier flac dans un tampon de 128 octets.
FG_FLICMODE détermine le mode vidéo optimal pour l'image FLIC

associé à l'en-tête de fichier flac spécifié. Le mode optimal est le mode 256- graphique de couleur ayant la plus basse résolution est supérieure ou égale aux dimensions de l'image.

FG_FLICOPEN ouvre un fichier flac pour un traitement ultérieur par Fastgraph de

autres bas niveau fichier flac routines de soutien. En cas de succès, le pointeur de fichier sera positionné au début de la première image.

FG_FLICPLAY affiche les prochains un ou plusieurs images dans un fichier flac

précédemment ouvert avec fg_flicopen.

FG_FLICSIZE renvoie les dimensions de l'image associée à la FLIC

spécifiée tête du fichier flac.

FG_FLICSKIP avance un ou plusieurs cadres dans un fichier flac précédemment ouvert

avec fg_flicopen. Si la dernière image joué par fg_flicplay affiche le cadre de la mémoire tampon de fg_imagebuf, la position du cadre sera ajusté dans le tampon de fg_imagebuf. Dans le cas contraire, la position du fichier flac lui-même sera ajusté.

FG_GIFHEAD lit tête global du fichier GIF et premier en-tête locale en

un tampon de 23 octets.

FG_GIFMODE détermine le mode vidéo optimal pour l'affichage d'un fichier GIF.

Le mode optimal est le mode vidéo ayant la résolution la plus basse est supérieure ou égale aux dimensions de l'image.

FG_GIFPAL récupère la palette d'une image stockée dans un fichier GIF.  le

les valeurs de la palette sont renvoyées en tant que composants de couleur RVB, chaque entre 0 et 63. Si le fichier GIF comprend une palette locale pour la première image, fg_gifpal retourne les valeurs de la palette locale. Sinon, fg_gifpal retourne les valeurs de la palette globale du fichier GIF.

FG_GIFRANGE retourne les étendues d'image pour l'image GIF associée à

l'en-tête de fichier GIF spécifié.

FG_IMAGEBUF spécifie la taille et l'adresse du tampon utilisé en interne

lors de la création ou l'affichage GIF, les fichiers PCX, FLI / FLC ou SPR / PPR. interne par défaut tampon taille Fastgraph est 4096 octets. l'affichage ou la création image est généralement plus rapide quand un tampon plus grand est utilisé, en particulier en mode protégé ou lors de la lecture des fichiers flic. Dans des environnements de 16 bits, la taille de la mémoire tampon de fg_imagebuf est limitée à 64K octets.

FG_LOADPCX charge une image PCX dans la mémoire tampon virtuelle active. 

Guide de l'utilisateur 210 Fastgraph


FG_MAKEGIF crée un fichier GIF à partir de la zone rectangulaire spécifiée

la page vidéo active ou tampon virtuel. Les extrêmes de la région sont exprimés en unités d'espace d'écran. Cette routine est significatif que dans 16 couleurs et 256- modes graphiques de couleurs.

FG_MAKEPCX crée un fichier PCX de la région rectangulaire spécifiée

la page vidéo active ou tampon virtuel. Les extrêmes de la région sont exprimés en unités d'espace d'écran.

FG_MAKEPPR crée un fichier pixel d'exécution emballé à partir de la forme rectangulaire spécifiée

région de la page vidéo active ou tampon virtuel. Les extrêmes de la région sont exprimés en unités d'espace d'écran.

FG_MAKESPR crée un fichier standard pixel de l'exécution de la spécifiée

zone rectangulaire de la page vidéo active ou tampon virtuel. Les extrêmes de la région sont exprimés en unités d'espace d'écran.

FG_PATTERN définit un modèle d'affichage pour une utilisation lors de l'affichage pixel run

fichiers en mode vidéo qui offrent 16 ou moins de couleurs.

FG_PCXHEAD lit un en-tête de fichier PCX dans un tampon de 128 octets.
FG_PCXMODE détermine le mode vidéo optimal pour l'affichage d'un fichier PCX.

Le mode optimal est le mode vidéo compatible avec la résolution la plus basse est supérieure ou égale aux dimensions de l'image.

FG_PCXPAL extrait la palette d'une image stockée dans un fichier PCX, et

nombre de couleurs dans la palette. Les valeurs de la palette sont renvoyées en tant que composants de couleur RVB, chaque entre 0 et 63. Si le fichier PCX comprend un (256 couleurs) palette étendue, fg_pcxpal retourne les valeurs dans la palette étendue. Sinon, fg_pcxpal retourne les valeurs de la palette de 16 couleurs dans l'en-tête de PCX.

FG_PCXRANGE retourne les étendues d'image pour l'image PCX associée à

l'en-tête de fichier PCX spécifié.

FG_SHOWGIF affiche une image stockée dans un fichier GIF.
FG_SHOWFLIC affiche une image stockée dans un FLI ou d'un fichier FLC (collectivement

appelé fichiers CIDF).

FG_SHOWPCX affiche une image stockée dans un fichier PCX.

FG_SHOWPPR affiche une image stockée dans un fichier pixel d'exécution emballé. L'image

sera positionné de sorte que son coin inférieur gauche est à la position du curseur graphique de la page vidéo active ou tampon virtuel.

FG_SHOWSPR affiche une image stockée dans un fichier pixel d'exécution standard.  le

image sera positionnée de sorte que son coin inférieur gauche est à la position du curseur graphique de la page vidéo active ou tampon virtuel.



chapitre 10


Images bitmap 212 Guide de l'utilisateur Fastgraph


aperçu

Dans ce chapitre, nous allons continuer notre discussion sur les images en se concentrant

sur une classe importante d'images appelées images bitmap. Fastgraph comprend des routines pour afficher, récupérer et manipuler des images bitmap dans des formats mode- spécifiques et en mode indépendant. Ce chapitre traitera des routines Fastgraph qui traitent avec les deux catégories d'images bitmap.

Affichage des images bitmap est un élément essentiel de l'animation avec

Fastgraph. Alors que les fichiers d'image décrits dans le chapitre précédent sont utiles pour l'affichage de milieux ou d'importer des images à partir d'autres sources, une séquence d'animation ne peut atteindre sa vitesse à travers les routines d'affichage d'image bitmap décrites dans ce chapitre, ainsi que les programmes de transfert de bloc du chapitre suivant .


Mode indépendant Images bitmap

Cette section discutera des routines d'affichage d'image qui utilisent le même

format d'image bitmap pour tous les modes graphiques vidéo. Une autre classe de routines, décrit dans la section suivante, utilisez des formats différents pour différents modes vidéo. Bien que ces routines d'affichage d'image en mode indépendant sont plus généraux, ils atteignent cette généralité à la cause de la vitesse d'exécution. Cela peut notamment être un problème si l'image est grande, ou si la vitesse est essentielle dans une application (comme dans les graphiques de style arcade). Pour de nombreux programmes, cependant, les routines de mode indépendant offrent toutes les capacités d'affichage d'image est nécessaire.

Commençons par revenir à un exemple d'une image très simple - la

triangle introduit dans le chapitre précédent:

 .  .  .  . *.  .  .  .
                              .  .  . * X * .  .  .
                              .  . * Xxx *.  .
                              . * Xxxxx *.
                              * * * * * * * * *

Rappelons que le périmètre du triangle est une couleur différente de celle de ses pixels intérieurs, et d'utiliser cette image avec Fastgraph, nous devons inscrire le triangle dans une zone rectangulaire. Comme précédemment, notre triangle est neuf pixels de large à sa base et de cinq pixels de haut. Les pixels indiqués par un astérisque (*) sont le périmètre du triangle, tandis que celles qui sont indiquées par un x représentent ses points intérieurs. Nous devons faire la distinction entre ces pixels, car ils seront différentes couleurs. Les pixels affichés comme des périodes (.) Ne font pas partie du triangle lui-même. Ils sont nécessaires pour rendre l'image rectangulaire, donc du point de vue Fastgraph ils sont en effet partie de l'image.

La fg_drawmap routine Fastgraph est une routine appropriée pour attirer notre

triangle.Pour utiliser fg_drawmap, nous devons créer des bitmaps séparés pour chaque couleur dans l'image (à l'exception des points utilisés pour remplir la zone rectangulaire, qui sont considérées comme transparentes). Dans cet exemple, nous allons donc besoin de deux bitmaps - un pour les points de périmètre, et un pour les points intérieurs. Brisons l'image dans ces deux bitmaps.

Chapitre 10: Bitmap Images 213


 .  .  .  . *.  .  .  .  .  .  .  .  .  .  .  .  .
                 .  .  .*. *. .  .  .  .  .  . X .  .  .  .
                 .  . *.  .  . *.  .  .  .  . xxx.  .  .
                 . *.  .  .  .  . *.  .  . xxxxx.  .
                * * * * * * * * *.  .  .  .  .  .  .  .  .
souligne périmètre points intérieurs
L'étape suivante consiste à convertir ces deux bitmaps dans leur binaire

représentations.Tout comme il y a huit bits dans un octet, nous allons créer une structure de données (un tableau dans ce cas) avec chaque octet de maintien huit pixels. Les bits qui sont fixés (1) indiquent le pixel correspondant apparaîtra affichée dans la couleur associée à ce bitmap. Les bits sont remis à zéro (0) quittent le pixel correspondant inchangé. La taille de chaque tableau bitmap doit être d'au moins 10 octets car chaque bitmap contient cinq lignes avec neuf pixels dans chaque rangée (qui est, deux octets sont nécessaires pour chaque ligne de l'image). Par conséquent, lorsque nous convertissons ces bitmaps à leurs représentations binaires, et par la suite à leur équivalent hexadécimal, les résultats apparaîtront comme indiqué ici. Les bits de caractères gras représentent l'image réelle; les autres bits sont des bits de remplissage nécessaires pour compléter chaque ligne des bitmaps après le neuvième pixel. Tous les bits de remplissage doivent être nuls.


0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 08 00
0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 14 00
0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 22 00
0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 41 00
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 80 FF
bitmap périmètre


0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 00
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 08 00
0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1C 00
0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 3E 00
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 00
bitmap intérieur
La question suivante est l'ordre dans lequel les bitmaps sont stockés dans la

les structures de données correspondantes. Étant donné que notre structure de données est un tableau, il est seulement nécessaire de montrer la relation entre les indices des structures bitmap ci-dessus. Le schéma suivant montre l'ordre de l'indice pour le cas d'une à deux colonnes par cinq rangées bitmap.


[8] [9]   

Guide de l'utilisateur 214 Fastgraph


[6] [7]
[4] [5]
[2] [3]
[0] [1]


A partir de ce diagramme, on voit le premier élément de la matrice (à savoir la

élément avec l'indice [0]) représente le coin inférieur gauche de l'image. La progression de l'indice continue ensuite à droite jusqu'à la fin de la première rangée. Il reprend alors à l'élément le plus à gauche de la deuxième rangée et continue vers la droite jusqu'à la fin de cette ligne. Elle se poursuit de cette manière pour toutes les lignes restantes.

Nous sommes maintenant prêts à présenter un exemple de programme pour afficher notre triangle.

Le programme utilisera la fg_drawmap routine Fastgraph, qui attend trois arguments. Le premier argument est le tableau bitmap (transmis par référence), le second est la largeur de l'image bitmap en octets, et le dernier est la hauteur de l'image bitmap en rangées de pixels. Le fg_drawmap affiche de routine l'image de telle sorte que son coin inférieur gauche est à la position graphique du curseur sur la page vidéo active. La routine n'a pas d'effet dans les modes texte vidéo. En outre, fg_drawmap affiche l'image en utilisant l'indice de couleur actuelle, ce qui signifie que nous aurons besoin d'appeler fg_drawmap une fois pour chaque couleur dans l'image.

Exemple 10-1 fonctionne dans un mode graphique 320x200 de couleur (il pourrait être fait pour

exécuté en mode 12 aussi, mais cela irait à l'encontre de l'objectif de l'exemple). Après avoir établi le mode vidéo, le programme fg_rect utilise pour remplir tout l'écran avec un rectangle gris (blanc CGA). Ensuite, le programme établit (156,101) comme étant la position du curseur graphique; ce qui provoque le triangle centré sur l'écran. Les deux appels à fg_drawmap, une pour chaque couleur dans l'image, en fait afficher le triangle. Notez surtout comment fg_setcolor est utilisé avant chaque appel à fg_drawmap pour définir l'indice de couleur actuelle. Le résultat est un triangle avec un périmètre bleu (cyan dans ACG) et l'intérieur vert (magenta CGA).

Exemple 10-1.
#include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
           void main (void);
carboniser périmètre [] = {
              0xFF, 0x80,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00
               };
           omble intérieur [] = {
              0x00,0x00,0x3E, 0x00,0x1C, 0x00,0x08,0x00,0x00,0x00
               };
void main ()
            {
              int old_mode, new_mode; 
                                         Chapitre 10: Bitmap Images 215


fg_initpm ();
              new_mode = fg_bestmode (320,200,1);
              if (new_mode <0 || new_mode == 12) {
                 printf ( "Ce programme nécessite une 320");
                 ( "le mode x 200 graphiques couleur \ n".) printf;
                 sortie (1);
                  }
fg_getmode old_mode = ();
              fg_setmode (new_mode);
fg_setcolor (7);
              fg_rect (0,319,0,199);
fg_move (156,101);
              fg_setcolor (1);
              fg_drawmap (périmètre, 2,5);
              fg_setcolor (2);
              fg_drawmap (intérieur, 2,5);
              fg_waitkey ();
fg_setmode (old_mode);
              fg_reset ();
            }


Il convient de mentionner que fg_drawmap ne réalise pas l'écrêtage lorsque

afficher une image. Si vous voulez que l'image soit contraint par les limites d'écrêtage actuelles, utilisez fg_clipmap au lieu de fg_drawmap. La routine de fg_clipmap prend les trois mêmes arguments que fg_drawmap, mais il est pas aussi rapide que fg_drawmap en raison de la charge supplémentaire requise lors de l'exécution de l'image écrêtage.

Les différents bitmaps de couleurs utilisées par fg_drawmap n'ont pas tous être le

même taille.Dans notre exemple de triangle, le périmètre est de 9 pixels de large par 5 pixels de haut, mais l'intérieur est à seulement 5 pixels de large par 3 pixels de haut. Par conséquent, le bitmap pour les pixels intérieurs ne nécessite qu'un seul octet pour chacun de ses trois rangées, de sorte que nous pouvons stocker dans un tableau à trois octets. Sa structure serait:


[2] 08
[1] 1C
[0] 3E


Exemple 10-2 est similaire à l'exemple 10-1, mais il utilise un tableau à trois octets

pour le bitmap intérieur. Notez le deuxième appel à fg_move dans cet exemple. Il est nécessaire parce que la rangée du bas de l'image bitmap intérieur plus petit correspond à la deuxième ligne de la plus grande périmètre bitmap. En d'autres termes, le bitmap intérieur doit être affiché une ligne au-dessus du bitmap de périmètre.

Exemple 10-2.
#include <fastgraf.h>   

Guide de 216 Fastgraph utilisateur


#include <stdio.h>
            #include <stdlib.h>
           void main (void);
carboniser périmètre [] = {
              0xFF, 0x80,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00
               };
           omble intérieur [] = {
              0x3E, 0x1C, 0x08
               };
void main ()
            {
              int old_mode, new_mode;
fg_initpm ();
              new_mode = fg_bestmode (320,200,1);
              if (new_mode <0 || new_mode == 12) {
                 printf ( "Ce programme nécessite une 320");
                 ( "le mode x 200 graphiques couleur \ n".) printf;
                 sortie (1);
                  }
fg_getmode old_mode = ();
              fg_setmode (new_mode);
fg_setcolor (7);
              fg_rect (0,319,0,199);
fg_move (156,101);
              fg_setcolor (1);
              fg_drawmap (périmètre, 2,5);
              fg_move (156,100);
              fg_setcolor (2);
              fg_drawmap (intérieur, 1,3);
              fg_waitkey ();
fg_setmode (old_mode);
              fg_reset ();
            }


Dans l'exemple 10-2, le temps nécessaire pour exécuter le deuxième appel à fg_move

peut ne pas être vaut le gain de 7 octets. Lorsque l'espace du tableau est critique, ou lorsque les images sont plus grandes, l'utilisation de petits bitmaps pour certaines couleurs peut être plus précieux.

Pourtant, une autre possibilité, par exemple 10-2 serait de déplacer les éléments

du bitmap intérieur de deux pixels vers la gauche. De cette manière, le bitmap soit aligné sur le côté gauche de la matrice, comme le bitmap de périmètre est. Les trois valeurs composant le bitmap intérieur deviendraient alors F8, 70 et 20. Nous aimerions aussi avoir besoin de changer la coordonnée x dans le deuxième appel à fg_move 156-158.

Chapitre 10: Bitmap Images 217


Spécifiques à chaque mode Images bitmap

Cette section discutera des routines d'affichage d'image qui utilisent pixelisée

formats d'image spécifiques à chaque mode vidéo texte et des graphiques. Les différents formats d'image ressemblent étroitement à la structure de mémoire vidéo dans chaque mode, de sorte que ces routines sont beaucoup plus rapides que d'afficher bitmaps en mode indépendant avec fg_drawmap. Si vous utilisez les bitmaps spécifiques au mode dans un programme qui prend en charge plusieurs modes vidéo, il y aura une programmation supplémentaire qui ne soit pas nécessaire lors de l'utilisation des bitmaps en mode indépendant. Habituellement, cependant, vos efforts seront récompensés avec des graphismes nettement plus rapides.

Nous démontrons l'utilisation des bitmaps spécifiques au mode dans les modes avec graphiques

le familier triangle deux couleurs dont la représentation pixel apparaît ci-dessous.

 .  .  .  . *.  .  .  .
                              .  .  . * X * .  .  .
                              .  . * Xxx *.  .
                              . * Xxxxx *.
                              * * * * * * * * *
Comme précédemment, notre triangle est neuf pixels de large à sa base et cinq pixels

haute.Les pixels indiqués par un astérisque (*) sont le périmètre du triangle, tandis que celles qui sont indiquées par un x représentent ses points intérieurs. Nous devons faire la distinction entre ces pixels, car ils seront différentes couleurs. Les pixels affichés comme des périodes (.) Ne font pas partie du triangle lui-même. Ils sont nécessaires pour rendre l'image rectangulaire, donc du point de vue Fastgraph ils sont en effet partie de l'image.


Images régulières

La fg_drwimage routine Fastgraph affiche spécifique en mode régulier

images bitmap (par régulière, nous entendons une image qui est ni coupé, ni tourné). Ses arguments et l'ordre de l'indice de la matrice bitmap sont les mêmes que pour fg_drawmap. La différence majeure est la structure bitmap - nous combinons les informations pour toutes les couleurs en un seul bitmap, d'une manière compatible avec la structure de mémoire vidéo pour les différents modes. Comme avec les autres routines d'affichage d'image, fg_drwimage affiche l'image sur la page vidéo active ou tampon virtuel avec son coin inférieur gauche à la position graphique du curseur (ou la position du curseur de texte pour les modes de texte). Nous allons maintenant examiner l'utilisation de fg_drwimage dans plusieurs modes vidéo.

modes quatre couleurs graphiques CGA

Dans les modes graphiques quatre couleurs CGA (modes 4 et 5), chaque pixel peut

supposons une valeur comprise entre 0 et 3. Cela signifie qu'il faut deux bits pour représenter un pixel, ou en d'autres termes, chaque octet de mémoire vidéo contient quatre pixels. Notre image de triangle est neuf pixels de large, de sorte que trois octets sont nécessaires pour chaque ligne de l'image. Parce que l'image est de cinq pixels de haut, nous avons besoin d'un réseau de bitmap d'au moins 15 octets (cinq lignes fois trois octets par ligne) pour contenir l'image.

représentation binaire de l'image et son équivalent hexadécimal pour la

modes graphiques quatre couleurs CGA sont présentés ici. Les valeurs binaires en gras représentent l'image réelle; les autres sont les bits de remplissage nécessaires pour compléter chaque ligne de l'image bitmap après le neuvième pixel. Nous avons codé le périmètre Guide 218 Fastgraph utilisateur


pixels pour être la couleur 1 (01 binaire) et les pixels intérieurs à être de couleur 2 (10 binaire). Tout pixel dont la valeur est égale à zéro (00 binaire) est transparent et laisser ainsi le contenu de la mémoire vidéo à cette position inchangée.


00 00 00 00 01 00 00 00 00 00 00 00 00 40 00
00 00 00 01 10 01 00 00 00 00 00 00 01 90 00
00 00 01 10 10 10 01 00 00 00 00 00 06 00 A4
00 01 10 10 10 10 10 01 00 00 00 00 1A A9 00
01 01 01 01 01 01 01 01 01 00 00 00 55 55 40


Exemple 10-3 utilise ce bitmap mode spécifique pour afficher le triangle

le mode standard CGA-quatre couleurs graphiques (mode 4). Après avoir établi le mode vidéo, le programme fg_rect utilise pour remplir tout l'écran avec un rectangle blanc. Ensuite, le programme établit (156,101) comme étant la position du curseur graphique; ce qui provoque le triangle centré sur l'écran. L'appel à fg_drwimage produit un triangle avec un périmètre de cyan (couleur 1) et un intérieur magenta (couleur 2).

Exemple 10-3.
#include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
            void main (void);
omble triangle [] = {
               0x55,0x55,0x40, 0x1A, 0xA9,0x00, 0x06,0xA4,0x00,
               0x01,0x90,0x00, 0x00,0x40,0x00
                };
void main ()
             {
               int old_mode;
fg_initpm ();
               if (fg_testmode (4,1) == 0) {
                  printf ( "Ce programme nécessite une 320");
                  ( "le mode x 200 graphiques CGA \ n".) printf;
                   sortie (1);
                   }
fg_getmode old_mode = ();
               fg_setmode (4);
fg_setcolor (7);
               fg_rect (0,319,0,199);
fg_move (156,101);
               fg_drwimage (triangle, 3,5);
               fg_waitkey (); 
                                         Chapitre 10: Bitmap Images 219


fg_setmode (old_mode);
               fg_reset ();
             }


CGA mode deux graphiques en couleur

Dans les deux couleurs CGA Mode (mode 6) graphique, chaque pixel peut prendre la

les valeurs 0 ou 1. Cela signifie qu'il suffit d'un seul bit pour représenter un pixel, de sorte que chaque octet de la mémoire vidéo contient huit pixels. Notre image de triangle est neuf pixels de large, de sorte que deux octets sont nécessaires pour chaque ligne de l'image. Parce que l'image est de cinq pixels de haut, nous avons besoin d'un réseau de bitmap d'au moins 10 octets (cinq lignes fois deux octets par ligne) pour contenir l'image.

représentation binaire de l'image et son équivalent hexadécimal pour la

deux couleurs mode graphique CGA sont présentés ici. Les valeurs binaires en gras représentent l'image réelle; les autres sont les bits de remplissage nécessaires pour compléter chaque ligne de l'image bitmap après le neuvième pixel. Nous avons codé les deux pixels de périmètre et les pixels intérieurs à être de couleur 1. Tout pixel dont la valeur est zéro est transparente et va donc laisser le contenu de la mémoire vidéo à cette position inchangée.


0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 08 00
0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 1C 00
0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 3E 00
0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 00 7F
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 80 FF


Exemple 10-4 utilise ce bitmap mode spécifique pour afficher le triangle

le mode deux couleurs graphiques CGA (mode 6). Après avoir établi le mode vidéo, le programme établit (316.101) que la position du curseur graphiques; ce qui provoque le triangle centré sur l'écran. L'appel à fg_drwimage produit un triangle solide.

Exemple 04.10.
#include <fastgraf.h>
                  #include <stdio.h>
                  #include <stdlib.h>
                 void main (void);
omble triangle [] = {
                    0xFF, 0x80, 0x7F, 0x00, 0x3E, 0x00,
                    0x1C, 0x00, 0x08,0x00
                     };
void main ()
                  {
                    int old_mode; 

Guide de 220 Fastgraph utilisateur


fg_initpm ();
                    if (fg_testmode (6,1) == 0) {
                       printf ( "Ce programme nécessite une");
                       ( «mode graphique CGA \ n".) printf;
                        sortie (1);
                        }
fg_getmode old_mode = ();
                    fg_setmode (6);
fg_move (316,101);
                    fg_drwimage (triangle, 2,5);
                    fg_waitkey ();
fg_setmode (old_mode);
                    fg_reset ();
                  }


mode 16 graphique couleur Tandy / PCjr

La structure de bitmaps spécifique en mode pour les 16 couleurs Tandy / PCjr

Mode (mode 9) graphique est la même que la structure bitmap mode spécifique pour la / / SVGA modes EGA-VGA 16 graphiques couleur discutées plus loin dans cette section.

modes graphiques Hercules

La structure de bitmaps spécifique en mode pour les modes les graphiques Hercules

(modes 11 et 12) est le même que deux des modes les graphiques CGA. Pour le mode graphique Hercules standard (mode 11), s'il vous plaît se référer à la discussion des CGA deux couleurs (mode 6) bitmaps. Pour le Hercules mode graphique basse résolution (mode 12), s'il vous plaît se référer à la discussion des quatre couleurs CGA (mode 4) bitmaps.

modes / VGA / SVGA 16 couleurs graphiques EGA

Dans les modes les natifs EGA et VGA graphiques (modes 13 à 18) et le

modes graphiques SVGA 16 couleurs (modes 28 et 29), chaque pixel peut prendre une valeur entre 0 et 15. Cela signifie qu'il faut quatre bits pour représenter un pixel, de sorte que chaque octet du bitmap détient deux pixels. Notre image de triangle est neuf pixels de large, de sorte que cinq octets sont nécessaires pour chaque ligne de l'image. Parce que l'image est de cinq pixels de haut, nous avons besoin d'un réseau de bitmap d'au moins 25 octets (cinq lignes fois cinq octets par ligne) pour contenir l'image.

Dans ces modes, il est facile d'élaborer la représentation hexadécimale d'une

bitmap sans produire d'abord son équivalent binaire. En effet, une valeur de pixel et un chiffre hexadécimal occupent chacune quatre bits. représentation hexadécimale du triangle pour ces modes vidéo est montré ici. Les pixels en gras représentent l'image réelle; les autres sont les valeurs de charge nécessaires pour compléter chaque ligne de l'image bitmap après le neuvième pixel. Nous avons choisi d'afficher les pixels périphériques de couleur 1 et les pixels intérieurs de couleur 2. Tout pixel dont la valeur est zéro est transparente et va donc laisser le contenu de la mémoire vidéo à cette position inchangée.

Chapitre 10: Bitmap Images 221


00 00 10 00 00
00 01 21 00 00
00 12 22 10 00
01 22 22 21 00
11 11 11 11 10


Exemple 10-5 est similaire à l'exemple 10-3, mais il utilise le EGA 320x200

mode graphique (mode 13) et du bitmap mode spécifique juste construit pour afficher le triangle. L'appel à fg_drwimage produit un triangle avec un périmètre bleu (couleur 1) et un intérieur vert (couleur 2).

Exemple 10-5.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
omble triangle [] = {
                  0x11,0x11,0x11,0x11,0x10,
                  0x01,0x22,0x22,0x21,0x00,
                  0x00,0x12,0x22,0x10,0x00,
                  0x00,0x01,0x21,0x00,0x00,
                  0x00,0x00,0x10,0x00,0x00
                   };
void main ()
                {
                  int old_mode;
fg_initpm ();
                  if (fg_testmode (13,1) == 0) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques EGA \ n".) printf;
                      sortie (1);
                      }
fg_getmode old_mode = ();
                  fg_setmode (13);
fg_setcolor (7);
                  fg_rect (0,319,0,199);
fg_move (156,101);
                  fg_drwimage (triangle, 5,5);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
               }   

Guide de l'utilisateur 222 Fastgraph


modes graphiques 256 couleurs

Dans les modes graphiques 256 couleurs (modes 19 à 27), chaque pixel peut prendre

une valeur comprise entre 0 et 255 (FF hex). Cela signifie qu'il faut huit bits pour représenter un pixel ou chaque octet de la mémoire vidéo contient un pixel. Notre image de triangle est neuf pixels de large, de sorte que neuf octets sont nécessaires pour chaque ligne de l'image. Parce que l'image est de cinq pixels de haut, nous avons besoin d'un réseau de bitmap d'au moins 45 octets (cinq lignes fois neuf octets par ligne) pour contenir l'image. Notez que nous aurons jamais besoin des bits de remplissage dans les modes vidéo 256 couleurs.

Il est particulièrement simple à développer le bitmap pour une image dans le 256-

modes de couleurs, car chaque octet détient exactement un pixel. représentation hexadécimale du triangle pour les modes graphiques de 256 couleurs est montré ici. Comme précédemment, nous avons codé les pixels périphériques comme la couleur 1 (01 hex) et les pixels intérieurs à être de couleur 2 (02 hex). Tout pixel dont la valeur est égale à zéro est transparente et laisser ainsi le contenu de la mémoire vidéo à cette position inchangée.


00 00 00 00 01 00 00 00 00
00 00 00 01 02 01 00 00 00
00 00 01 02 02 02 01 00 00
00 01 02 02 02 02 02 01 00
01 01 01 01 01 01 01 01 01


Exemple 10-6 est également similaire à l'exemple 10-3, mais il utilise la MCGA 256-

le mode graphique couleur (mode 19) et du bitmap mode spécifique juste construit pour afficher le triangle. L'appel à fg_drwimage produit un triangle avec un périmètre bleu (couleur 1) et un intérieur vert (couleur 2).

Exemple 10-6.
#include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
             void main (void);
omble triangle [] = {
                0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
                0x00,0x01,0x02,0x02,0x02,0x02,0x02,0x01,0x00,
                0x00,0x00,0x01,0x02,0x02,0x02,0x01,0x00,0x00,
                0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,
                0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00
                 };
void main ()
              {
                int old_mode;
fg_initpm (); 
                                         Chapitre 10: Bitmap Images 223


if (fg_testmode (19,1) == 0) {
                   printf ( "Ce programme nécessite une 320");
                   ( "le mode x 200 graphiques MCGA \ n".) printf;
                    sortie (1);
                    }
fg_getmode old_mode = ();
                fg_setmode (19);
fg_setcolor (7);
                fg_rect (0,319,0,199);
fg_move (156,101);
                fg_drwimage (triangle, 9,5);
                fg_waitkey ();
fg_setmode (old_mode);
                fg_reset ();
              }


Parfois, vous devrez peut-être inclure des pixels noirs qui ne sont pas transparents

dans une image bitmap mode spécifique. La meilleure façon de le faire est d'utiliser fg_putimage, que nous allons décrire brièvement. Une autre possibilité est d'utiliser fg_palette ou fg_setrgb pour faire un index utilisé de couleur noire et ensuite utiliser cet indice de couleur pour les non-transparents pixels noirs. Par exemple, fg_palette appelant (8,0) dans un mode graphique 16 couleurs affichera la couleur 8 pixels que le noir. De même, fg_setrgb (248,0,0,0) dans un mode graphique 256 couleurs affichera la couleur 248 pixels que le noir. Le choix des couleurs et 8 248 dans ces exemples est arbitraire; toute couleur utilisé fera. Une autre possibilité est d'utiliser les cartes de masquage discutés plus loin dans ce chapitre.

tampons virtuels

La structure de bitmaps spécifique en mode pour les tampons virtuels est le

identique à la structure bitmap mode spécifique pour les modes graphiques de 256 couleurs discutés dans la section précédente.

Modes de texte

Vous pouvez également utiliser la routine de fg_drwimage pour afficher des images en texte vidéo

Modes (modes 0, 1, 2, 3 et 7). Comme on pouvait s'y attendre, la structure de l'image dans les modes de texte est assez différent de modes graphiques les. Dans le chapitre 5, nous avons vu que chaque cellule de caractère sur l'écran est en fait constitué d'un caractère et un attribut. La valeur de caractère détermine ce caractère est affiché, tandis que la valeur d'attribut contrôle l'apparence du personnage. La structure de l'attribut est la suivante:

les bits d'attribut
0-3 couleur de premier plan
                      la couleur d'arrière-plan 4-6
                       7 clignotant
La structure de l'image en mode texte utilisé avec fg_drwimage se compose également d'un

série de caractères et attributs. Par exemple, le Guide de la figure suivante 224 Fastgraph utilisateur


illustre la structure d'une image qui est de trois caractères de large et deux personnages de haut.


omble attr omble attr omble attr
omble attr omble attr omble attr


Pour illustrer l'utilisation de fg_drwimage en mode texte vidéo, nous affichons

l'expression "bonjour là" sur deux lignes différentes dans le centre de l'écran. En outre, supposons que nous aimerions que le premier caractère de chaque mot à apparaître dans la couleur de premier plan 1, la deuxième couleur 2, et ainsi de suite. Notre image se composera de deux lignes chacune contenant cinq caractères, et chaque caractère nécessite deux octets de stockage (un pour le caractère et l'autre pour son attribut), donc nous allons avoir besoin d'un tableau de 20 octets pour la tenue de l'image. Le tableau ne tient pas vraiment une image bitmap comme dans les modes graphiques les, de sorte que dans le texte Modes le premier argument passé à fg_drwimage est plutôt appelé le réseau d'image. Dans notre exemple, la structure de la matrice d'image est la suivante:


'H' 1 'e' 2 'l' 3 'l' 4 'o' 5
'T' 1 'h' 2 'e' 3 'r' 4 'e' 5


L'ordre de l'indice que fg_drwimage utilise des modes de texte est le même que pour les modes graphiques les. Pour nos cinq rangs image en deux colonnes par, cela signifie que les indices de tableau seront numérotées comme suit:


[10] [11] [12] [13] [14] [15] [16] [17] [18] [19]
[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]


En fonction des valeurs de caractère et d'attribut dans la matrice d'image,

fg_drwimage peut afficher de nouveaux personnages et attributs, de nouveaux personnages en laissant les attributs existants inchangés, de nouveaux attributs laissant le caractère existant inchangé, ou de laisser à la fois le caractère existant et attribuer inchangé dans la mémoire vidéo. Pour garder un caractère ou attribut existant, il suffit de spécifier une valeur de 0 dans l'élément correspondant de la matrice d'image. Cette capacité est analogue au fait que de valeur zéro pixels en mode graphique bitmaps laissent mémoire vidéo inchangé.

Exemple 10-7 illustre l'utilisation de fg_drwimage dans la couleur 80 colonnes

en mode texte (mode 3). Après avoir établi le mode vidéo et en faisant le curseur invisible, le programme appelle fg_drwimage pour afficher le "bonjour là" image juste discuté (noter que nous passons les dimensions de la matrice d'image que le nombre d'octets, et non pas le nombre de caractères). Le programme attend une frappe et appelle ensuite à nouveau fg_drwimage, le passage d'un réseau d'image différente (appelée "image") de la même taille. Ce tableau change la première lettre des deux mots de minuscules en majuscules (en laissant l'attribut inchangé), et il rend les caractères restants ont le même attribut que le premier caractère. Cela se fait en partie en utilisant des caractères de valeur zéro et les attributs de quitter la mémoire vidéo inchangée. Après avoir attendu une autre touche, le programme sort.

Chapitre 10: Bitmap Images 225


Exemple 10-7.
#include <fastgraf.h>
                   void main (void);
carboniser bonjour [] = {
                      'T', 1, 'h', 2, 'e', ​​3, 'r', 4, 'e', ​​5,
                      'H', 1, 'e', ​​2, 'l', 3, 'l', 4, 'o', 5
                       };
l'image char [] = {
                      'T', 0, 0,1, 0,1, 0,1, 0,1,
                      'H', 0, 0,1, 0,1, 0,1, 0,1
                       };
void main ()
                    {
                      int old_mode;
fg_initpm ();
                      fg_getmode old_mode = ();
                      fg_setmode (3);
                      fg_cursor (0);
fg_locate (12,37);
                      fg_drwimage (bonjour, 10,2);
                      fg_waitkey ();
fg_drwimage (image, 10,2);
                      fg_waitkey ();
fg_setmode (old_mode);
                      fg_reset ();
                    }


Images détourées

La routine de fg_drwimage ne fonctionne pas écrêtage lors de l'affichage d'un

image. Si vous voulez que l'image soit contraint par les limites d'écrêtage (tel qu'établi par l'appel le plus récent à fg_setclip), utilisez fg_clpimage au lieu de fg_drwimage. La routine prend fg_clpimage les trois mêmes arguments que fg_drwimage et affiche également l'image de telle sorte que son coin inférieur gauche est à la position du curseur graphique. Contrairement à fg_drwimage, la routine de fg_clpimage n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte. En raison de la charge supplémentaire impliqué dans la vérification des limites d'écrêtage, fg_clpimage est pas aussi rapide que fg_drwimage.


Images inversée

La routine de fg_revimage affiche une image inversée (qui est, en miroir

autour de l'axe-y) sans écrêtage. Il prend les trois mêmes arguments que fg_drwimage et affiche également l'image de telle sorte que son coin inférieur gauche est au Guide de l'utilisateur 226 Fastgraph


les graphiques position du curseur. La routine de fg_revimage n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.


Inversée Images détourées

La routine fg_flpimage combine les effets de la fg_revimage et

routines fg_clpimage - il affiche une image inversée contraint par les limites d'écrêtage actuelles. Il faut environ les trois mêmes arguments que fg_drwimage et affiche également l'image de telle sorte que son coin inférieur gauche est à la position du curseur graphique. Comme la routine fg_clpimage, fg_flpimage n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.


Images Sans pixels transparents

La routine de fg_putimage est le même que celui fg_drwimage sauf qu'il ne

considérer la couleur 0 pixels pour être transparent. Parce qu'il n'a pas besoin de vérifier les pixels transparents, fg_putimage est plus rapide que fg_drwimage. Utilisation de fg_putimage est recommandé pour les cas où la transparence est pas un problème.


Quelques exemples

Exemple 10-8 illustre l'utilisation de fg_drwimage, fg_clpimage,

fg_revimage, fg_flpimage et fg_putimage en mode quatre couleurs graphique standard CGA (mode 4). Le programme utilise chacune de ces routines pour afficher une petite flèche blanche, comme illustré sur cette carte de pixels:

 .  .  .  .  .  . *.  .  .
                             .  .  .  .  .  . * *.  .
                            * * * * * * * * *.
                             * * * * * * * * * *
                            * * * * * * * * *.
                             .  .  .  .  .  . * *.  .
                             .  .  .  .  .  . *.  .  .

Comme précédemment, nous devons d'abord convertir cette image à un bitmap. L'image est de dix pixels de large et sept de haut. En mode 4, chaque pixel occupe deux bits, donc nous avons besoin d'un réseau de 21 octets (7 lignes par 3 colonnes) pour stocker l'image. Puisque nous voulons faire de la flèche blanche, chaque pixel sera affiché dans la couleur 3 (11 binaire). Voici le bitmap et son équivalent hexadécimal pour l'image de la flèche en mode 4 (l'image réelle est en gras).


00 00 00 00 00 00 11 00 00 00 00 00 00 00 0C
00 00 00 00 00 00 11 11 00 00 00 00 00 00 0F
11 11 11 11 11 11 11 11 11 00 00 00 FF FF C0
11 11 11 11 11 11 11 11 11 11 00 00 FF FF F0
11 11 11 11 11 11 11 11 11 00 00 00 FF FF C0
00 00 00 00 00 00 11 11 00 00 00 00 00 00 0F   
                                         Chapitre 10: Bitmap Images 227


00 00 00 00 00 00 11 00 00 00 00 00 00 00 0C


Après avoir établi le mode vidéo, le programme remplit l'écran avec

Couleur 1 pixels et définit une zone de découpage. Il fg_drwimage utilise ensuite pour afficher la flèche pointant vers la droite et fg_clpimage de faire la même chose, mais en ce qui concerne les limites d'écrêtage. Parce que le bord gauche de la flèche est affichée à x = 10 et le droit d'écrêtage limite est à x = 15, l'appel à fg_clpimage ne tire les six premières colonnes de la flèche (qui est, il ne tire pas la tête de flèche).

Ensuite, par exemple 10-8 fg_revimage utilise pour afficher la flèche pointant vers la

à gauche.Pour permettre la charge des pixels, nous devons établir la position graphique du curseur deux pixels vers la gauche de la position utilisée par fg_drwimage si nous voulons que la pointe de la flèche pointant vers la gauche pour l'aligner sur la queue de la flèche pointant vers le droite. Le programme fg_flpimage utilise ensuite pour afficher une flèche pointant vers la gauche en ce qui concerne les limites d'écrêtage. L'appel à fg_flpimage affiche la tête de flèche et les deux premières colonnes de l'arbre de flèche. Enfin, le programme fg_putimage utilise pour afficher la flèche pointant vers la droite écrêté sans pixels transparents (ce qui produit une bordure noire autour de la flèche).

Exemple 10-8.
#include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
            void main (void);
omble flèche [] = {
               0x00,0x0C, 0x00, 0x00,0x0F, 0x00, 0xFF, 0xFF, 0xC0,
               0xFF, 0xFF, 0xF0, 0xFF, 0xFF, 0xC0, 0x00,0x0F, 0x00,
               0x00,0x0C, 0x00
                };
void main ()
             {
               int old_mode;
fg_initpm ();
               if (fg_testmode (4,1) == 0) {
                  printf ( "Ce programme nécessite une 320");
                  ( "le mode x 200 graphiques CGA \ n".) printf;
                   sortie (1);
                   }
fg_getmode old_mode = ();
               fg_setmode (4);
               fg_setcolor (1);
               fg_fillpage ();
               fg_setclip (0,15,0,199);
fg_move (10,10);
               fg_drwimage (flèche, 3,7);
               fg_move (10,20);
               fg_clpimage (flèche, 3,7); 

Guide de 228 Fastgraph utilisateur


fg_move (8,30);
               fg_revimage (flèche, 3,7);
               fg_move (8,40);
               fg_flpimage (flèche, 3,7);
               fg_move (8,50);
               fg_putimage (flèche, 3,7);
               fg_waitkey ();
fg_setmode (old_mode);
               fg_reset ();
             }


Exemple 10-9 est identique à l'exemple 10-8, mais on utilise la basse résolution,

mode graphique EGA (mode 13). Si nous avons changé le numéro de mode spécifié dans les appels à fg_testmode et fg_setmode, le programme serait également fonctionner dans un mode graphique couleur 16-. Dans ces modes, nous stockons deux pixels par octet dans le tableau bitmap, donc nous avons besoin d'un réseau de 35 octets (7 lignes par 5 colonnes) pour stocker l'image. Voici équivalent hexadécimal du bitmap pour l'image de la flèche en mode 13, suivi par le programme pour l'afficher.


00 00 00 00 F0
00 00 00 00 FF
FF FF FF FF F0
FF FF FF FF FF
FF FF FF FF F0
00 00 00 00 FF
00 00 00 00 F0


Exemple 10-9.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
omble flèche [] = {
                  0x00,0x00,0x00,0xF0,0x00,
                  0x00,0x00,0x00,0xFF, 0x00,
                  0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
                  0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                  0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
                  0x00,0x00,0x00,0xFF, 0x00,
                  0x00,0x00,0x00,0xF0,0x00
                   };
void main ()
               {   
                                         Chapitre 10: Bitmap Images 229


int old_mode;
fg_initpm ();
                  if (fg_testmode (13,1) == 0) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques EGA \ n".) printf;
                      sortie (1);
                      }
fg_getmode old_mode = ();
                  fg_setmode (13);
                  fg_setcolor (1);
                  fg_fillpage ();
                  fg_setclip (0,15,0,199);
fg_move (10,10);
                  fg_drwimage (flèche, 5,7);
                  fg_move (10,20);
                  fg_clpimage (flèche, 5,7);
                  fg_move (8,30);
                  fg_revimage (flèche, 5,7);
                  fg_move (8,40);
                  fg_flpimage (flèche, 5,7);
                  fg_move (8,50);
                  fg_putimage (flèche, 5,7);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


Récupération d'images

Parfois, il est nécessaire de récupérer une image de la mémoire vidéo et un magasin

dans un ou plusieurs tableaux sous forme d'image bitmap. Fastgraph comprend deux routines, fg_getmap et fg_getimage, à cette fin. La routine de fg_getmap récupère pixels de l'indice de couleur actuelle et les stocke dans le format bitmap indépendante mode- utilisée par fg_drawmap. La routine de fg_getimage récupère une image et le stocke dans le format spécifique en mode bitmap utilisé par fg_drwimage, fg_clpimage, fg_revimage, fg_flpimage et fg_putimage. Les arguments à fg_getmap et fg_getimage sont respectivement analogues à celles des fg_drawmap et fg_drwimage: le premier est un tableau (transmis par référence) pour recevoir le bitmap, le second est la largeur de l'image bitmap en octets, et la dernière est la hauteur de la bitmap en rangées de pixels. Avec soit la routine, la position graphique du curseur sur la page vidéo active définit le coin inférieur gauche de l'image à récupérer.

Si nous voulons utiliser fg_getmap pour récupérer une image contenant plus d'un

la couleur, il faut appeler la routine une fois par couleur. Dans ce cas, nous voulons habituellement passer différents tableaux bitmap à fg_getmap (ou peut-être différents décalages dans le même tableau). Cela peut sembler inhabituel au début, mais il est parallèle le comportement de la routine de fg_drawmap. Autrement dit, pour afficher une image multicolore en utilisant fg_drawmap, nous devons l'appeler une fois pour chaque couleur dans l'image. Guide de l'utilisateur 230 Fastgraph


Exemple 10-10 montre une utilisation typique de la routine de fg_getmap.  le

programme affiche le mot «texte» dans le coin supérieur gauche de l'écran en utilisant un mode 320x200 graphique. Il utilise fg_getmap pour récupérer le mot comme une image, puis l'affiche dans une nouvelle position avec la routine de fg_drawmap. Regardons maintenant le programme, et ensuite nous allons examiner de plus près les coordonnées de l'écran et la structure de la matrice bitmap.

Exemple 10-10.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  omble bitmap [32];
                  int old_mode, new_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_setcolor (9);
                  fg_text ( "text", 4);
                  fg_waitkey ();
fg_move (0,7);
                  fg_getmap (bitmap, 4,8);
                  fg_move (4,15);
                  fg_drawmap (bitmap, 4,8);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


Dans tous les graphiques 320x200 modes vidéo, les caractères individuels sont 8 pixels

de large et 8 pixels de haut. Cela signifie que le coin inférieur gauche de la cellule (0,0) de caractère est référencé par les coordonnées d'écran (0,7). Par conséquent, ce sont les coordonnées du premier appel à fg_move. L'image récupérée dans l'exemple 10-10 est de quatre caractères (32 pixels de large), donc nous avons besoin d'un réseau de bitmap capable de contenir 8 rangées de 32 pixels (4 octets) chacun. Notre réseau de bitmap est donc un tableau de 32 octets, logiquement structuré pour avoir 4 colonnes et 8 lignes. Ces valeurs sont la largeur et la hauteur des arguments passés à fg_getmap et fg_drawmap.

Chapitre 10: Bitmap Images 231


Après il récupère l'image, par exemple 10-10 affiche une ligne ci-dessous

et une cellule de caractère de la moitié (quatre pixels) à droite de sa position initiale. En d'autres termes, le programme affiche l'image de quatre pixels à droite de la cellule (1,0) de caractère. Le coin inférieur gauche de cette cellule est référencée par les coordonnées d'écran (0.15), de sorte que l'image doit apparaître à la position (4,15). Ceux-ci sont les coordonnées du deuxième appel à fg_move.

Par exemple 10 à 11 illustre l'utilisation de fg_getmap et pour récupérer fg_drawmap

et afficher une image en deux couleurs. Cet exemple est similaire à l'exemple 10-10, mais ce programme dessine d'abord un rectangle dans le coin supérieur gauche de l'écran, puis affiche le mot "texte" sur le dessus du rectangle dans une couleur différente. Chaque personnage dans un mode vidéo 320x200 graphique est de 8 pixels de large et 8 pixels de haut, de sorte que le rectangle doit être de 32 pixels de large (4 caractères fois 8 pixels par caractère) et 8 pixels de haut. L'image de récupérer sera la même taille que le rectangle.

L'image récupérée dans l'exemple 10-10 exigeait un tableau de 32 octets, logiquement

structuré pour avoir 4 colonnes et 8 lignes. Exemple 10-11 récupère une image de la même structure, mais l'image contient deux couleurs au lieu d'un seul. Cela signifie que nous devons deux tableaux de 32 octets, une pour chaque couleur, pour contenir l'image. Nous pourrions utiliser à la place un seul tableau de 64 octets et transmettre un décalage dans ce tableau (en particulier, et bitmap [32]) pour le traitement de la deuxième couleur.

Exemple 10-11.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  omble bitmap1 [32], bitmap2 [32];
                  int old_mode, new_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_setcolor (7);
                  fg_rect (0,31,0,7);
                  fg_setcolor (9);
                  fg_text ( "text", 4);
                  fg_waitkey ();
fg_move (0,7);
                  fg_setcolor (7);
                  fg_getmap (bitmap1,4,8);
                  fg_setcolor (9); 

Guide de l'utilisateur 232 Fastgraph


fg_getmap (bitmap2,4,8);
fg_move (4,15);
                  fg_setcolor (7);
                  fg_drawmap (bitmap1,4,8);
                  fg_setcolor (9);
                  fg_drawmap (bitmap2,4,8);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


Exemple 10-12 est similaire à l'exemple 10-11, mais il utilise fg_getimage et

fg_drwimage au lieu de fg_getmap et fg_drawmap pour récupérer et afficher l'image. C'est, il utilise le lieu de la recherche d'images et d'affichage des routines de mode indépendant mode spécifique. Lors de l'utilisation des routines propres à chaque mode, la taille de l'image bitmap nécessaire pour maintenir l'image dépend du mode vidéo. Pour les programmes qui fonctionnent dans un seul mode vidéo, les largeurs de bitmap sont constantes, mais quand un programme doit être exécuté dans plusieurs modes vidéo, la largeur est variable. La fg_imagesiz routine Fastgraph calcule le nombre d'octets nécessaires pour stocker une image bitmap de dimensions spécifiées mode spécifique. Ses deux arguments entiers spécifient la largeur de l'image et la taille en pixels.

Le programme calcule la largeur d'image en octets par passage d'une hauteur de 1 à

fg_imagesiz. La taille du tableau bitmap dans l'exemple 10-12 est de 256 octets, la taille requise dans les modes graphiques 256 couleurs (32 octets fois 8 octets). D'autres modes vidéo nécessitent moins de mémoire, de sorte que dans ces modes seulement une partie de la matrice bitmap seront effectivement utilisées. La largeur de l'image est ensuite utilisée dans les appels à la fois fg_getimage et fg_drwimage.

Exemple 10-12.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  omble bitmap [256];
                  int old_mode, new_mode;
                  Largeur int;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
                   fg_getmode old_mode = ();  fg_setmode (new_mode);  width = (int) fg_imagesiz (32,1);  Chapitre 10: Bitmap Images 233 


 fg_setcolor (7);
                   fg_rect (0,31,0,7);
                   fg_setcolor (9);
                   fg_text ( "text", 4);
                   fg_waitkey ();
 fg_move (0,7);
                   fg_getimage (bitmap, largeur, 8);
                   fg_move (4,15);
                   fg_drwimage (bitmap, largeur, 8);
                   fg_waitkey ();
 fg_setmode (old_mode);
                   fg_reset ();
                }


Bien que cet exemple utilise un tableau pour stocker l'image, il est généralement préférable d'allouer de la mémoire dynamique à cette fin. Nous aurions pu faire cela dans l'exemple 10-12 en appelant fg_imagesiz avec des arguments de 32 (largeur) et 8 (hauteur). La valeur de retour de la routine serait alors nous dire le nombre d'octets que nous aurions besoin d'allouer.

 Nous pouvons également utiliser fg_getimage pour récupérer des images dans les modes texte vidéo.  Dans

modes de texte, cependant, il y a quelques différences que nous devons prendre en considération lors de l'utilisation fg_getimage. En premier lieu, la position du curseur de texte, et non la position du curseur graphique définit le coin inférieur gauche de l'image. Par conséquent, nous devons utiliser fg_locate au lieu de fg_move pour définir l'emplacement de l'image. Deuxièmement, la largeur de l'image est toujours deux fois le nombre de caractères par ligne d'image (ce qui est, pour chaque personnage, nous avons un octet de caractère et un octet d'attribut). La routine de fg_getmap n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

 Exemple 10-13 montre une simple utilisation de fg_getimage en mode texte.  Ce

programme est similaire à l'exemple 10-12, mais il fonctionne dans un mode texte de 80 colonnes au lieu d'un mode 320x200 graphique. Comme précédemment, le programme permettra de récupérer les quatre caractères "texte" comme une image à partir du coin supérieur gauche de l'écran, puis l'afficher dans un endroit différent. Parce que l'image se compose de quatre caractères dans une rangée, la largeur de l'image est de 8 octets et la hauteur de l'image est 1.

 Exemple 10-13.
 #include <fastgraf.h>
                  #include <stdio.h>
                  #include <stdlib.h>
                  void main (void);
 void main ()
                  {
                     int old_mode;
                     l'image char [8];
 fg_initpm ();
                     fg_getmode old_mode = (); 

Guide de l'utilisateur 234 Fastgraph


 if (fg_testmode (3,1))
                        fg_setmode (3);
                     else if (fg_testmode (7,1))
                        fg_setmode (7);
                     autre {
                        printf ( "Ce programme nécessite \ n");
                        printf ( "un affichage de 80 colonnes. \ n");
                        sortie (1);
                        }
                     fg_cursor (0);
 fg_setattr (9,7,0);
                     fg_text ( "text", 4);
                     fg_waitkey ();
 fg_locate (0,0);
                     fg_getimage (image, 8,1);
                     fg_locate (1,1);
                     fg_drwimage (image, 8,1);
                     fg_waitkey ();
 fg_setmode (old_mode);
                     fg_reset ();
                  }


 Enfin, voici une astuce qui est à retenir.  Dans le EGA et VGA natif

modes graphiques (13 à 18) et les modes 16 couleurs SVGA graphiques (28 et 29), les routines pour l'affichage et la récupération de bitmaps spécifique en mode peut varier de 10% à 20% plus rapide si les graphismes actuels position x est encore nombre. En effet, ces routines doivent effectuer un alignement bitmap supplémentaire lors de l'affichage ou de la récupération des images à partir de pixels impairs.


Inversant bitmaps

 affichage spécifique en mode de Fastgraph mode indépendant et image pixelisée

routines attendent les images pour être stockées en commençant par la rangée du bas et poursuivre vers le haut. Cette convention est souvent contraire à la "haut en bas" ordre des lignes utilisées dans d'autres bibliothèques graphiques. La routine fg_invert inverse l'ordre des lignes d'images bitmap, donc un "haut en bas" image devient un "bas en haut" image, ou vice versa. Ce sera souvent plus facile d'importer ces images à partir d'autres sources pour une utilisation avec bitmaps routines d'affichage d'image de Fastgraph. Notez que fg_invert ne modifie pas l'orientation pour les bitmaps routines d'affichage d'image de Fastgraph; il renverse simplement l'ordre des lignes de l'image elle-même.

 La routine de fg_invert nécessite trois arguments.  La première est l'adresse

du tableau contenant les données d'image bitmap spécifique en mode en mode indépendant ou. L'image inversée résultant est stocké dans ce même tableau. Les deuxième et troisième arguments indiquent respectivement la largeur et la hauteur bitmap en octets.

 Exemple 10 à 14 est une version modifiée de l'exemple 10-6 qui définit la

Les données bitmap de triangle commençant par la rangée supérieure et se rendant vers le bas. Pour afficher cette image avec la routine de fg_drwimage de Fastgraph, nous devons

 Chapitre 10: Bitmap Images 235


traduire l'image bitmap du "bas vers le haut" le format. Le programme effectue cette traduction avec fg_invert immédiatement après le réglage du mode vidéo (bien que cela pourrait être fait à tout moment avant d'appeler fg_drwimage). Autre que l'appel fg_invert supplémentaire et l'ordre des données bitmap, par exemple 10-14 est le même que l'exemple 10-6.

 Exemple 10-14.
 #include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
              void main (void);
 omble triangle [] = {
                 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
                 0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,
                 0x00,0x00,0x01,0x02,0x02,0x02,0x01,0x00,0x00,
                 0x00,0x01,0x02,0x02,0x02,0x02,0x02,0x01,0x00,
                 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
                 };
 void main ()
              {
                 int old_mode;
 fg_initpm ();
                 if (fg_testmode (19,1) == 0) {
                    printf ( "Ce programme nécessite une 320");
                    ( "le mode x 200 graphiques MCGA \ n".) printf;
                    sortie (1);
                    }
 fg_getmode old_mode = ();
                 fg_setmode (19);
                 fg_invert (triangle, 9,5);
 fg_setcolor (7);
                 fg_rect (0,319,0,199);
 fg_move (156,101);
                 fg_drwimage (triangle, 9,5);
                 fg_waitkey ();
 fg_setmode (old_mode);
                 fg_reset ();
              }


 On notera que fg_invert peut également être utilisé pour créer des versions inversées de toute

mode indépendant ou image bitmap mode spécifique. Cela signifie que vous pouvez créer des versions de bitmaps en miroir autour de l'axe x, un peu analogue à la façon dont fg_revimage affiche des images en miroir autour de l'axe-y. Guide de l'utilisateur 236 Fastgraph


Conversion de bitmaps spécifiques à chaque mode

 Plus tôt dans ce chapitre, nous avons présenté un format d'image bitmap qui était

indépendamment du mode vidéo (ces images sont affichées avec fg_drawmap ou fg_clipmap). Bien que ce format fonctionne bien pour les images avec une ou deux couleurs, la performance peut se dégrader de manière significative si l'image contient beaucoup de couleurs. Dans cette section, nous montrons comment "un pixel par octet" mode spécifique bitmap format de Fastgraph utilisé avec les modes graphiques 256 couleurs et des tampons virtuels peut fournir une autre façon d'utiliser les mêmes données d'image dans les modes vidéo multiples.

 La base de ce système est de stocker tous les bitmaps dans le "un pixel par

byte "le format. Lorsque vous utilisez les modes graphiques 256 couleurs ou des tampons virtuels, nous utilisons simplement le" un pixel par octet "bitmaps avec la famille de fg_drwimage des routines parce que les bitmaps sont déjà dans le format attendu. Cependant, lorsque vous utilisez les modes graphiques avec moins couleurs, nous devons traduire les bitmaps à un format adapté à ces modes de routine fg_pack de Fastgraph fournit un moyen facile de le faire. il convertit les images bitmap dans le format "un pixel par octet" au format bitmap mode spécifique pour la vidéo en cours Mode. les bitmaps convertis peut alors être affiché avec la famille de fg_drwimage.

 deux premiers arguments de la routine de fg_pack sont les adresses de la source

et les tableaux destination bitmap. Le tableau source contient le "un pixel par octet" image bitmap, et le réseau de destination recevra l'image spécifique en mode converti (il est important de vous assurer que le réseau de destination est assez grand pour contenir l'image convertie). Les deux derniers arguments de fg_pack spécifient la largeur et la hauteur en pixels de l'image source. Dans les modes graphiques 256 couleurs, ou quand un tampon virtuel est actif, fg_pack simplement des copies des sources tableau contenu au tableau de destination.

 Exemple 10-15 montre comment vous pouvez utiliser les mêmes données bitmap en 256 couleurs et

modes graphiques 16 couleurs. Nous définissons notre triangle bitmap familière dans le format spécifique en mode couleur 256-, comme dans l'exemple 10-6. Le programme affiche d'abord le bitmap de triangle dans le VGA standard / MCGA 320x200 mode graphique 256 couleurs (mode 19) sur un fond gris. Après une séquence de touches, le programme passe au mode graphique 320x200 16 couleurs EGA / VGA (mode 13). Dans ce mode, fg_drwimage attend deux pixels par octet bitmap, donc nous devons appeler fg_pack pour convertir les données bitmap à ce format. Nous stockons le bitmap résultant dans le tableau de triangle16 et encore utiliser fg_drwimage pour afficher le bitmap de triangle.

 Exemple 10-15.
 #include <fastgraf.h>
              void main (void);
 omble triangle [] = {
                 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
                 0x00,0x01,0x02,0x02,0x02,0x02,0x02,0x01,0x00,
                 0x00,0x00,0x01,0x02,0x02,0x02,0x01,0x00,0x00,
                 0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,
                 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00
                 };
              omble triangle16 [25];
 void main ()
              {
                                          Chapitre 10: Bitmap Images 237


 int old_mode;
 fg_initpm ();
                 fg_getmode old_mode = ();
 fg_setmode (19);
                 fg_setcolor (7);
                 fg_fillpage ();
                 fg_move (156,101);
                 fg_drwimage (triangle, 9,5);
                 fg_waitkey ();
 fg_setmode (13);
                 fg_setcolor (7);
                 fg_fillpage ();
                 fg_pack (triangle, triangle16,9,5);
                 fg_move (156,101);
                 fg_drwimage (triangle16,5,5);
                 fg_waitkey ();
 fg_setmode (old_mode);
                 fg_reset ();
              }


Notez que le bitmap 256 couleurs est neuf octets de large et cinq octets de hauteur. Lorsque nous convertissons l'image au format spécifique au mode 16 couleurs, la largeur de la bitmap est réduite à cinq octets parce que deux pixels sont emballés dans chaque octet. Le second pixel dans le dernier octet de chaque ligne devient une charge pixel transparent (qui est, sa valeur est égale à zéro).

 Comme vous pouvez le deviner, la routine de fg_unpack de Fastgraph effectue le contraire

fonction de fg_pack. Autrement dit, il convertit une image bitmap à partir du format spécifique au mode de fonctionnement du mode vidéo actuel au format "un pixel par octet". La routine de fg_unpack est conçu comme une fonction d'assistance pour l'affichage mode- images spécifiques dans des tampons virtuels lors de l'utilisation des modes vidéo avec moins de 256 couleurs. Quand un tampon virtuel est actif, fg_drwimage attend toujours le bitmap pour être dans le format «un pixel par octet", quel que soit le mode vidéo actuel. La routine de fg_unpack il est facile de convertir des images à ce format avant de les afficher dans un tampon virtuel.

 deux premiers arguments de la routine de fg_unpack sont les adresses de la

la source et la destination des tableaux bitmap. Le tableau source contient l'image bitmap mode- spécifique, et le réseau de destination recevra l'image convertie "un pixel par octet". Le dernier argument de fg_unpack spécifie la taille de la matrice source en octets. Comme fg_pack, fg_unpack simplement copie les sources tableau contenu au tableau de destination dans les modes graphiques 256 couleurs ou quand un tampon virtuel est actif.

 Exemple 10-16 illustre comment utiliser fg_unpack à mode spécifique convertir

bitmaps au format de mémoire virtuelle. Le programme utilise le 10-pixel par pixel 7-flèche bitmap d'exemple 10-9 et fonctionne dans le mode graphique 320x200 16 couleurs EGA / VGA (mode 13). Dans ce mode, deux pixels sont emballés dans chaque octet bitmap, de sorte que la taille de la matrice d'une image bitmap 5x7, soit 35 octets. L'appel à fg_unpack convertit l'image spécifique en mode dans le 35-octet flèche tableau dans une image "d'un pixel par octet" format, stocker le résultat dans le 70 tableau d'octets arrow256. Guide de l'utilisateur 238 Fastgraph


Nous allons créer un tampon virtuel de 70 octets - juste assez grand pour contenir le 10x7 flèche bitmap - et afficher le bitmap arrow256 en elle contre un bleu clair (couleur 9) fond. Enfin, nous allons utiliser fg_vbpaste pour afficher le contenu du tampon virtuel dans le milieu de l'écran.

 Exemple 10-16.
 #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main (void);
 omble flèche [] = {
                   0x00,0x00,0x00,0xF0,0x00,
                   0x00,0x00,0x00,0xFF, 0x00,
                   0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
                   0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                   0xFF, 0xFF, 0xFF, 0xFF, 0xF0,
                   0x00,0x00,0x00,0xFF, 0x00,
                   0x00,0x00,0x00,0xF0,0x00
                   };
                arrow256 char [70];
 #ifdef FG32
                char buffer [70];
                #autre
                carboniser loin tampon [70];
                #fin si
 void main ()
                {
                   poignée int;
                   int old_mode;
 fg_initpm ();
                   if (fg_testmode (13,1) == 0) {
                      printf ( "Ce programme nécessite une 320");
                      ( "le mode x 200 graphiques EGA \ n".) printf;
                      sortie (1);
                      }
 fg_getmode old_mode = ();
                   fg_setmode (13);
                   fg_unpack (flèche, arrow256,35);
 fg_vbinit ();
                   handle = fg_vbdefine (tampon, 10,7);
                   fg_vbopen (poignée);
                   fg_setcolor (9);
                   fg_fillpage ();
                   fg_move (0,6);
                   fg_drwimage (arrow256,10,7);
 fg_vbpaste (0,9,0,6,156,101);
                   fg_waitkey (); 
                                          Chapitre 10: Bitmap Images 239


 fg_vbclose ();
                   fg_setmode (old_mode);
                   fg_reset ();
                }


Bitmap Scaling et Shearing

 La routine de fg_scale de Fastgraph exécute mise à l'échelle horizontale et verticale

images bitmap. Il attend une bitmap source stockée dans le format "un pixel par octet" des modes 256 couleurs de Fastgraph, et il renvoie un bitmap élargi ou réduit dans le même format. Pour redimensionner des images dans les modes graphiques avec moins de 256 couleurs, vous devez d'abord utiliser fg_unpack pour convertir le bitmap au format attendu par fg_scale, effectuer la mise à l'échelle, et enfin utiliser fg_pack pour convertir l'image à l'échelle vers le format spécifique en mode. Parce que les tampons virtuels de Fastgraph utilisent également le pixel par format d'octet, vous pouvez également utiliser fg_scale à l'échelle des images stockées dans des tampons virtuels.

 La routine de fg_scale a six arguments.  Les deux premiers spécifiez le

les adresses de source et de destination des tableaux bitmap. Le tableau source contient la (unscaled) image bitmap d'origine; le tableau de destination recevra le (échelle) bitmap élargie ou réduite. Les deux bitmaps sont stockés dans le format "un pixel par octet". Les troisième et quatrième arguments spécifient la largeur et la hauteur en pixels de l'image unscaled, tandis que les cinquième et sixième arguments font la même chose pour l'image à l'échelle résultant.

 Exemple 10-17 montre comment développer et réduire les images bitmap avec

fg_scale. Le programme affiche un rectangle bleu 64x40 lumière avec une bordure blanche et le mot SCALE centrée à l'intérieur, dans le coin supérieur gauche de l'écran. Il récupère le contenu du rectangle en tant que bitmap mode spécifique en utilisant fg_getimage. Le premier appel de fg_scale augmente la taille de ce bitmap en 10 pixels dans les deux directions, ce qui signifie l'image de 64x40 devient une image de 74x50. Le programme affiche ensuite le bitmap étendu dans le coin inférieur gauche de l'écran en utilisant fg_putimage. Le deuxième appel de fg_scale réduit le bitmap d'origine par un facteur de deux pour créer une image bitmap 32x20. Le bitmap réduit est ensuite affiché dans le coin en bas à droite, à nouveau en utilisant fg_putimage. Notez que par exemple 10-17 fonctionne en mode 19, qui est un mode graphique 256 couleurs, de sorte que fg_getimage enregistre automatiquement l'image d'origine dans le format "un pixel par octet" attendu par fg_scale.

 Exemple 10-17.
 #include <fastgraf.h>
      void main (void);
 source de char [64 * 40], dest [74 * 50];
 void main ()
      {
         / * Initialisation de l'environnement vidéo * /
 fg_initpm ();
         fg_setmode (19);
 / * Dessiner un rectangle bleu avec une bordure blanche épaisse * /

Guide de l'utilisateur 240 Fastgraph


 fg_setcolor (9);
         fg_rect (0,63,0,39);
         fg_setcolor (15);
         fg_boxdepth (5,5);
         fg_box (0,63,0,39);
         fg_move (32,20);
         fg_justify (0,0);
         fg_print ( "SCALE", 5);
 / * Récupérer le rectangle comme un mode spécifique bitmap * /
 fg_move (0,39);
         fg_getimage (source, 64,40);
         fg_waitkey ();
 / * Étendre le bitmap de 10 pixels dans chaque direction et * /
         / * Puis l'afficher dans le coin inférieur gauche de l'écran * /
 fg_move (0199);
         fg_scale (source, dest, 64,40,74,50);
         fg_putimage (dest, 74,50);
         fg_waitkey ();
 / * Réduire le bitmap d'origine de 50% dans chaque direction et * /
         / * Puis l'afficher dans le coin inférieur droit de l'écran * /
 fg_move (288,199);
         fg_scale (source, dest, 64,40,32,20);
         fg_putimage (dest, 32,20);
         fg_waitkey ();
 / * Restauration 80x25 mode texte et la sortie * /
 fg_setmode (3);
         fg_reset ();
      }


 Shearing peut être considéré comme ancrage un coin d'un rectangle

région et en étirant le coin opposé horizontalement ou verticalement. Par exemple, bitmaps contenant du texte ou d'autres caractères peuvent être cisaillés horizontalement vers la droite pour un effet italiques. Une image cisaillée sera toujours plus grande que l'image d'origine, et il contiendra des zones vides triangulaires au niveau de ses coins. Les zones vides seront remplis de couleurs 0 pixels, ce qui signifie qu'ils seront transparents lorsque vous affichez une image cisaillée avec la famille de fg_drwimage de routines. Comme fg_scale, fg_shear attend bitmaps dans le format "un pixel par octet» et peut également être utilisé avec des images stockées dans des tampons virtuels.

 La routine de fg_shear a six arguments.  Les deux premiers spécifiez le

les adresses de source et de destination des tableaux bitmap. Le tableau source contient l'image bitmap d'origine; le réseau de destination recevra le bitmap cisaillé. Les deux bitmaps sont stockés dans le format "un pixel par octet". Les troisième et quatrième arguments spécifient la largeur et la hauteur en pixels de l'image originale. Pour cisailles horizontales, le cinquième argument spécifie le

 Chapitre 10: Bitmap Images 241


largeur en pixels de l'image bitmap cisaillé résultant. Pour ciseaux verticaux, il spécifie la hauteur résultante.

 L'argument fg_shear finale définit le type de cisaillement.  Quatre cisaillement distinctes

types sont disponibles:

 * Cisaillement horizontal gauche (bord inférieur de la région est tendue vers la droite)
    * Cisaillement horizontal droit (bord supérieur de la région est tendue vers la droite)
    * Cisaillement vertical gauche (bord gauche de la région est tendue vers le haut)
    * Cisaillement vertical droit (bord droit de la région est tendue vers le haut)

Le type est sélectionné par une valeur comprise entre 0 et 3, correspondant respectivement aux quatre types de cisaillement ci-dessus. Par exemple, le type de cisaillement 2 représente un cisaillement vertical gauche.

 Exemple 10-18 affiche un rectangle bleu 64x40 lumière avec une bordure blanche

et le mot CISAILLEMENT centré à l'intérieur, dans le coin supérieur gauche de l'écran. Il récupère le contenu du rectangle en tant que bitmap mode spécifique en utilisant fg_getimage. Le programme appelle ensuite fg_shear pour effectuer une 16-pixel cisaillement droite horizontale, qui étend le bord supérieur de l'image 16 pixels vers la droite. Cela produit une image bitmap 80x40, qui est ensuite affichée dans le coin inférieur gauche de l'écran avec fg_putimage. Parce que cet exemple fonctionne en mode 19, qui est un mode graphique 256 couleurs, fg_getimage enregistre automatiquement l'image d'origine dans le format "un pixel par octet" attendu par fg_shear.

 Exemple 10-18.
 #include <fastgraf.h>
      void main (void);
 source de char [64 * 40], dest [80 * 40];
 void main ()
      {
         / * Initialisation de l'environnement vidéo * /
 fg_initpm ();
         fg_setmode (19);
 / * Dessiner un rectangle bleu avec une bordure blanche épaisse * /
 fg_setcolor (9);
         fg_rect (0,63,0,39);
         fg_setcolor (15);
         fg_boxdepth (5,5);
         fg_box (0,63,0,39);
         fg_move (32,20);
         fg_justify (0,0);
         fg_print ( "CISAILLEMENT", 5);
 / * Récupérer le rectangle comme un mode spécifique bitmap * /
 fg_move (0,39);
         fg_getimage (source, 64,40);
         fg_waitkey (); 

Guide de 242 Fastgraph utilisateur


 / * Bitmap de cisaillement horizontale et à droite 16 pixels * /
         / * Puis l'afficher dans le coin inférieur gauche de l'écran * /
 fg_move (0199);
         fg_shear (source, dest, 64,40,80,1);
         fg_putimage (dest, 80,40);
         fg_waitkey ();
 / * Restauration 80x25 mode texte et la sortie * /
 fg_setmode (3);
         fg_reset ();
      }


 Il est possible d'utiliser fg_shear pour rudimentaire rotation bitmap.  Tonte

une image à gauche horizontalement puis verticalement à droite par le même montant faire pivoter une image dans le sens antihoraire. De même, le cisaillement horizontal à droite et puis à gauche verticalement va tourner dans le sens horaire.

 tampons virtuels utilisent le même format "un pixel par octet" attendu par

fg_scale et fg_shear. Cela signifie que vous pouvez passer des adresses de tampon virtuelles à ces fonctions et d'appliquer les opérations de mise à l'échelle et de cisaillement sur les tampons virtuels. Notez toutefois que les modes 16 bits limitent la taille des tableaux passés à fg_scale et fg_shear à 64K octets, ce qui signifie que vous ne pouvez pas appliquer ces fonctions pour les tampons virtuels plus grandes. En outre, l'adresse d'un tampon virtuel en mode réel est un segment: paire offset, vous devez donc utiliser le modèle de mémoire à grande échelle ou des images de cisaillement résidant dans des tampons virtuels dans des programmes en mode réel.

 Exemple 10-19 montre comment à l'échelle le contenu d'un tampon virtuel.

Le programme crée deux tampons virtuelles - l'un est 320x200 pixels et l'autre est un quart de cette taille, ou 80x50 pixels. L'image CORAL.PCX est chargé dans le tampon virtuel 320x200 en utilisant la routine de fg_loadpcx puis copié dans la page visuelle. Le programme appelle ensuite fg_scale, en lui passant les deux adresses de tampons virtuels, pour réduire l'image à un quart de sa taille originale. L'image résultante est stockée dans le tampon virtuel 80x50 et finalement copié dans le coin inférieur gauche de la page visuelle.

 Exemple 10-19.
 #include <fastgraf.h>
          #include <stdio.h>
          #include <stdlib.h>
          #if defined (__ TURBOC__)
          #include <alloc.h>
          #autre
          #include <malloc.h>
          #fin si
          void main (void);
 void main ()
          {
             int handle1, handle2;
          #if defined (__ WATCOMC__) ||  défini (__ HIGHC__)
             char * buffer1, * buffer2;
          #else
                                          Chapitre 10: Bitmap Images 243


 carboniser loin * buffer1, loin * buffer2;
          #fin si
 fg_initpm ();
             fg_setmode (19);
             fg_vbinit ();
 #if defined (__ WATCOMC__) ||  défini (__ HIGHC__)
             buffer1 = (char *) malloc (320 * 200);
             buffer2 = (char *) malloc (80 * 50);
          #elif défini (__ TURBOC__)
             buffer1 = (char loin *) farmalloc (320L * 200L);
             buffer2 = (char loin *) farmalloc (80L * 50L);
          #autre
             buffer1 = (char loin *) halloc (320L * 200L, 1);
             buffer2 = (char loin *) halloc (80L * 50L, 1);
          #fin si
             if (buffer1 == NULL || buffer2 == NULL)
             {
                fg_setmode (3);
                fg_reset ();
                printf ( "Impossible de créer les tampons virtuels. \ n");
                sortie (1);
             }
             handle1 = fg_vbdefine (buffer1,320,200);
             handle2 = fg_vbdefine (buffer2,80,50);
 fg_vbopen (handle1);
             fg_loadpcx ( "CORAL.PCX", 0);
             fg_vbpaste (0,319,0,199,0,199);
             fg_waitkey ();
 fg_scale (buffer1, buffer2,320,200,80,50);
             fg_vbopen (handle2);
             fg_vbpaste (0,79,0,49,0,199);
             fg_waitkey ();
 fg_vbclose ();
             fg_setmode (3);
             fg_reset ();
          }


 Dans l'exemple 10-19, nous avons créé les tampons virtuels avec fg_vbdefine, donc nous

connaissait leurs adresses. Que faire si nous étions en utilisant le mode BASIC ou réel Pascal et les avons créés avec fg_vballoc? Dans ce cas, les adresses tampons virtuels ne seraient pas immédiatement disponibles pour le programme. Heureusement, il existe une solution facile. La fonction de fg_vbaddr de Fastgraph renvoie l'adresse de la mémoire tampon virtuelle spécifiée; son seul argument est la poignée de tampon virtuel. Dans les modes 16 bits, l'adresse sera un véritable segment des modes: paire offset ou sélecteur de mode protégé: paire offset. Dans les modes de 32 bits, ce sera un décalage dans le segment de données par défaut. Si vous utilisez fg_vballoc dans l'exemple 10-19, la création et l'adresse de la mémoire tampon de récupération virtuelle pourrait se faire comme suit:

 carboniser loin * buffer1, loin * buffer2; 

Guide de l'utilisateur 244 Fastgraph


 handle1 = fg_vballoc (320,200);
    handle2 = fg_vballoc (80,50);
    if (handle1 <0 || handle2 <0) {
       fg_setmode (3);
       fg_reset ();
       printf ( "Impossible de créer les tampons virtuels. \ n");
       sortie (1);
       }
    buffer1 = (char loin *) fg_vbaddr (handle1);
    buffer2 = (char loin *) fg_vbaddr (handle2);

Les états de libérer la mémoire allouée aux tampons virtuels serait:

 fg_vbclose ();
    fg_vbfree (handle1);
    fg_vbfree (handle2);


Pixel Plans Run

 Les bitmaps utilisés avec le fg_drawmap, fg_drwimage et routines connexes

peut consommer de l'espace de tableau assez rapidement. Cela est particulièrement vrai si l'image est grande ou contient beaucoup de couleurs. Par exemple, une image en mode indépendant pixelisée qui occupe la totalité de l'écran en mode graphique 320x200 nécessite 8000 octets d'espace par couleur. Fastgraph fournit un autre appelé cartes de pixels exécuter de format d'image en mode indépendant, qui sont plus efficaces en termes d'espace. cartes de pixels exécuter sont structurées comme les fichiers de pixels exécuter introduits dans le chapitre précédent, mais l'image réside dans un tableau à la place d'un fichier.

 Revenons à notre exemple de triangle familier et montrent comment nous pourrions utiliser un

pixel carte pour afficher fonctionner.

 .  .  .  .  *.  .  .  .
                              .  .  .  * X * .  .  .
                              .  .  * Xxx *.  .
                              .  * Xxxxx *.
                              * * * * * * * * *

Comme précédemment, les pixels indiqués par un astérisque (*) sont le périmètre du triangle, tandis que celles qui sont indiquées par un x représentent ses points intérieurs. Les pixels affichés comme des périodes (.) Ne font pas partie du triangle lui-même, mais ils font partie de la carte pixel de l'exécution.

 En utilisant le format standard pixel d'exécution introduite dans le chapitre précédent,

nous voyons qu'il faut 16 pixels pistes pour stocker l'image de notre triangle comme une carte pixel de l'exécution. Si nous voulons afficher les pixels périphériques de couleur 1, les pixels intérieurs de couleur 2, et la zone de remplissage de couleur 7, la carte pixel d'exécution devrait contenir 16 ensembles de (couleur, count) paires: (1,9), ( 7,1), (1,1), (2,5), (1,1), (7,3), (1,1), (2,3), (1,1), (7, 5), (1,1), (2,1), (1,1), (7,7), (1,1) et (7,4). Contrairement aux formats d'image bitmap déjà discuté, cartes de pixels exécuter ne comportent aucune disposition pour les couleurs transparentes.

 La fg_display routine Fastgraph affiche une image stockée comme une course de pixel

carte. La routine fg_display attend trois arguments. Le premier est un tableau contenant les pistes de pixels (transmis par référence), le second est le nombre de

 Chapitre 10: Bitmap Images 245


pixel fonctionne dans le réseau, et la troisième est la largeur en pixels de l'image. Comme avec les autres routines d'affichage d'image, fg_display affiche l'image de telle sorte que son coin inférieur gauche est à la position graphique du curseur sur la page vidéo active ou tampon virtuel. Encore une fois, le format de la carte pixel d'exécution est le même que celui d'un fichier pixel d'exécution standard. En outre, tous les motifs d'affichage définis par fg_pattern sont également valables pour fg_display.

 Exemple 10-20 utilise la routine de fg_display pour afficher le triangle en tant que

pixel carte de l'exécution dans un mode graphique 320x200. Le programme affiche le triangle sur un fond de couleur 7, de sorte que le choix de la couleur 7 pour la zone de remplissage était important. Si une autre couleur ont été choisis, la zone de remplissage ne se fondre dans l'arrière-plan.

 Exemple 10-20.
 #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main (void);
 omble triangle [] = {
                   1,9, 7,1, 1,1, 2,5, 1,1, 7,3, 1,1, 2,3,
                   1,1, 7,5, 1,1, 2,1, 1,1, 7,7, 1,1, 7,4
                   };
 void main ()
                {
                   int old_mode, new_mode;
 fg_initpm ();
                   new_mode = fg_bestmode (320,200,1);
                   if (new_mode <0 || new_mode == 12) {
                      printf ( "Ce programme nécessite une 320");
                      ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
 fg_getmode old_mode = ();
                   fg_setmode (new_mode);
 fg_setcolor (7);
                   fg_rect (0,319,0,199);
 fg_move (156,101);
                   fg_display (triangle, 16,9);
                   fg_waitkey ();
 fg_setmode (old_mode);
                   fg_reset ();
                }


 Comme vous pouvez le deviner, Fastgraph offre également un pixel d'image emballé run carte

le format analogue au format de fichier d'exécution de pixel emballé introduit dans le chapitre précédent. Exemple 10 à 21 est identique à l'exemple 10-20, mais elle utilise plutôt que fg_displayp fg_display pour afficher l'image. Notez l'utilisation du Guide 246 Fastgraph utilisateur


nombres hexadécimaux pour définir les valeurs de couleur emballés, ce qui est évidemment pas nécessaire, mais certainement plus facile à lire que d'exprimer les quantités que les nombres décimaux. Comme fg_display, tous les motifs d'affichage définis par fg_pattern appliquent également à fg_displayp.

 Exemple 10-21.
 #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main (void);
 omble triangle [] = {
                   0x17,9,1, 0x12,1,5, 0x17,1,3, 0x12,1,3,
                   0x17,1,5, 0x12,1,1, 0x17,1,7, 0x17,1,4
                   };
 void main ()
                {
                   int old_mode, new_mode;
 fg_initpm ();
                   new_mode = fg_bestmode (320,200,1);
                   if (new_mode <0 || new_mode == 12) {
                      printf ( "Ce programme nécessite une 320");
                      ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
 fg_getmode old_mode = ();
                   fg_setmode (new_mode);
 fg_setcolor (7);
                   fg_rect (0,319,0,199);
 fg_move (156,101);
                   fg_displayp (triangle, 16,9);
                   fg_waitkey ();
 fg_setmode (old_mode);
                   fg_reset ();
                }


 Les deux fg_display et fg_displayp nécessitent l'image pixel de l'exécution pour être stocké

dans un tableau. Dans les exemples 10-20 et 10-21, l'image est définie dans le programme lui-même. Nous pouvons également utiliser ces routines en place de fg_dispfile lorsque l'image est stockée dans un fichier si on lit d'abord le contenu du fichier dans un tableau. Exemple 10-22 démontre cette procédure. Le programme affiche deux images identiques stockées dans des fichiers, un au format pixel de fonctionnement standard et l'autre au format pixel de course emballé.

 La première image, au format pixel de l'exécution standard, est dans le fichier CORAL.SPR.

Notez le programme doit ouvrir le fichier pour la lecture en mode binaire ( "rb" dans l'appel à fopen). Le programme lit tout le contenu du fichier dans le tableau pixel_runs, dont la taille doit être au moins aussi grande que la taille du fichier.

 Chapitre 10: Bitmap Images 247


Parce que l'image est stockée au format pixel d'exécution standard, le nombre de pixels pistes est la moitié de la taille du fichier. Le programme utilise ensuite fg_move pour établir le coin inférieur gauche de l'écran comme la position graphique du curseur et appelle ensuite fg_display pour afficher l'image. L'image remplit tout l'écran, de sorte que sa largeur est de 320 pixels.

 Après avoir attendu pendant une séquence de touches, le programme affiche la même manière la seconde

image. Cette image est dans le fichier CORAL.PPR et sont stockées au format pixel d'exécution emballés. Parce que l'image est emballé, le nombre de pixels pistes est de deux tiers la taille du fichier. Le programme efface alors l'image précédente de l'écran et des appels fg_displayp pour afficher l'image. Après une autre touche, le programme restaure le mode vidéo et écran attributs et retours originaux à DOS.

 Exemple 10-22.
 #include <fastgraf.h>
             #include <io.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main (void);
 pixel_runs char [20000];
 void main ()
             {
                * FILE stream;
                int file_size, run_count;
                int old_mode, new_mode;
 fg_initpm ();
                new_mode = fg_bestmode (320,200,1);
                if (new_mode <0 || new_mode == 12) {
                   printf ( "Ce programme nécessite une 320");
                   ( "le mode x 200 graphiques couleur \ n".) printf;
                   sortie (1);
                   }
 fg_getmode old_mode = ();
                fg_setmode (new_mode);
 flux = fopen ( "CORAL.SPR", "rb");
                file_size = (int) (filelength (fileno (flux)));
                fread (pixel_runs, sizeof (char), file_size, flux);
                fclose (flux);
                run_count = file_size / 2;
                fg_move (0199);
                (fg_display pixel_runs, run_count, 320);
                fg_waitkey ();
 flux = fopen ( "CORAL.PPR", "rb");
                file_size = (int) (filelength (fileno (flux)));
                fread (pixel_runs, sizeof (char), file_size, flux);
                fclose (flux);
                run_count = file_size / 3 * 2;
                fg_erase ();
                (fg_displayp pixel_runs, run_count, 320); 

Guide de l'utilisateur 248 Fastgraph


 fg_waitkey ();
 fg_setmode (old_mode);
                fg_reset ();
             }


Cartes masquants

 Il est impossible d'inclure la couleur 0 pixels dans une image affichée avec

fg_drwimage, fg_clpimage, fg_revimage ou fg_flpimage. En effet, ces routines considèrent la couleur 0 pixels pour être transparent, ce qui signifie ces pixels ne modifient pas les pixels correspondants dans la mémoire vidéo. Il y a des moments, cependant, quand vous voulez couleur 0 pixels pour être destructeur, ou remplacer le contenu de la mémoire vidéo.

 Considérons à nouveau l'image de la flèche de l'exemple 10-8.  Dans cet exemple, nous

affiché un blanc (couleur 3) du contre un noir (couleur 0) fond en mode quatre couleurs graphique standard CGA. Supposons, cependant, que nous voulons faire tout le contraire - afficher un noir (couleur 0) flèche contre un blanc (couleur 3) fond. Nous pourrions de l'utilisation des cours fg_putimage, fg_drawmap, ou l'une des routines pour l'affichage des cartes de pixels courir, mais ces méthodes ne prennent pas en charge l'écrêtage ou inverser une image. Il y a, cependant, quatre routines Fastgraph conçus spécialement à cet effet. Ces routines sont fg_drawmask, fg_clipmask, fg_revmask et fg_flipmask.

 Chacune de ces routines utilise une structure de données appelée une carte de masquage.  UNE

masquage carte est une structure similaire à une carte pixel de l'exécution, mais il ne comprend pas les informations sur les couleurs. Au lieu de cela, il se compose d'une série de pixels court qui alternent entre des pixels protégés et non protégés. Un exemple pourrait mieux clarifier ce point.

 Encore une fois, voici l'image de la flèche de l'exemple 10-8.
 .  .  .  .  .  .  *.  .  .
                             .  .  .  .  .  .  * *.  .
                             * * * * * * * * *.
                             * * * * * * * * * *
                             * * * * * * * * *.
                             .  .  .  .  .  .  * *.  .
                             .  .  .  .  .  .  *.  .  .

Cette fois, cependant, nous voulons que la flèche apparaisse dans la couleur 0. En d'autres termes, nous avons besoin des pixels "période" (.) Pour protéger la mémoire vidéo, alors que nous voulons que les pixels "astérisque" (*) à la mémoire de zéro vidéo. En regardant ce problème du point de vue d'un pixel de carte de course, nous avons une série alternée de «protéger» et «zéro» fonctionne. On n'a pas besoin des informations sur les couleurs de pixels, juste que ce soit pour protéger ou mettre à zéro la mémoire vidéo.

 Telle est précisément la structure d'une carte de masquage.  A partir de la partie inférieure

coin gauche de l'image et de passer à la droite, enveloppant à la ligne suivante en cas de besoin, nous pourrions représenter cette image comme une carte de masquage avec 6 pixels protégés, 1 pixel mis à zéro, 9 pixels protégées, 2 remises à zéro pixels, et ainsi de suite. D'une manière générale, la structure d'une feuille de masquage se présente comme suit.

 Chapitre 10: Bitmap Images 249


 [1] longueur de 1ère manche de protection
 [2] longueur du 1er zéro run
 [3] longueur du 2ème manche de protection
 [4] longueur de 2ème manche zéro
 .
                                        .
                                        .
 [N-2] longueur de course finale de protection
 [N-1] longueur de course finale zéro


 En regardant ce diagramme, nous voyons les éléments de tableau paires détiennent la

longueur des «protéger» fonctionne, et les éléments impairs détiennent la longueur des «zéro» fonctionne. Si vous avez besoin de la première manche pour être une course "zéro", il suffit d'inclure une "protection" run de longueur zéro comme le premier élément du tableau. Si la course finale est une course «protéger», vous ne devez inclure une longueur de zéro "zéro" de l'exécution à la fin du tableau.Enfin, si les deux types d'exécution dépasse 255 pixels, vous devez diviser cela en deux ou plusieurs séries de pixels. Dans ce cas, assurez-vous d'inclure une course de longueur nulle de l'autre type entre les deux éléments du tableau.

Exemple 10-23 illustre l'utilisation d'une carte de masquage par fg_drawmask,

fg_clipmask, fg_revmask et fg_flipmask en mode quatre couleurs graphique standard CGA (mode 4) pour dessiner un noir (couleur 0) flèche sur un fond blanc. Ces quatre routines sont respectivement analogues aux fg_drwimage, fg_clpimage, fg_revimage et fg_flpimage, mais ils utilisent des cartes de masquage plutôt que bitmaps. Le premier argument de chaque routine est le masquage carte réseau (passé par référence), le second argument est le nombre de pistes (qui est, le nombre d'éléments) dans le masquage carte réseau, et le troisième argument est la largeur en pixels de l'image.

Exemple 10-23.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
omble flèche [] = {6,1,9,2,2,9,1,19,7,2,8,1};
void main ()
                {
                  int old_mode;
fg_initpm ();
                  if (fg_testmode (4,1) == 0) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques CGA \ n".) printf;
                      sortie (1);
                     }   

Guide de l'utilisateur 250 Fastgraph


fg_getmode old_mode = ();
                  fg_setmode (4);
                  fg_setclip (0,15,0,199);
fg_setcolor (3);
                  fg_rect (0,319,0,199);
fg_move (10,10);
                  fg_drawmask (flèche, 12,10);
                  fg_move (10,20);
                  fg_clipmask (flèche, 12,10);
                  fg_move (10,30);
                  fg_revmask (flèche, 12,10);
                  fg_move (10,40);
                  fg_flipmask (flèche, 12,10);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


L'une des caractéristiques les plus utiles de cartes de masquage est leur capacité à effacer

une partie de mémoire vidéo avant de placer une image là. Cette technique fournit un moyen simple efficace pour inclure la couleur 0 pixels dans une image. Il est particulièrement efficace lors de l'affichage des images tramées de grande taille ou parce que la carte de masquage est généralement beaucoup plus faible que le bitmap requis par fg_drawmap ou de ses routines associées. Exemple 10-24 illustre ce processus dans le CGA mode quatre couleurs graphiques standard (mode 4) en affichant l'image de notre flèche sur un fond coloré. Dans cet exemple, la flèche a un blanc (couleur 3) périmètre et un noir (couleur 0) intérieur.

Le programme affiche la flèche en deux étapes. Il utilise d'abord fg_drawmask à

effacer la mémoire vidéo où la flèche sera affichée. Il tire ensuite le périmètre de la flèche à l'aide fg_drwimage. Les pixels intérieurs dans le bitmap de périmètre sont transparents, mais étant donné que nous venons concentrions que la mémoire vidéo, ils apparaissent en couleur 0. Notez que nous pourrions améliorer cet exemple en créant une carte de masquage plus petit qui ne vaut que pour le rectangle d'inscrire l'intérieur de la flèche. Autrement dit, on n'a pas besoin à zéro la mémoire vidéo dans le périmètre de la flèche parce que nous allons immédiatement afficher d'autres pixels là.

Exemple 10-24.
#include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
            void main (void);
carboniser Arrow_white [] = {
               0x00,0x0C, 0x00, 0x00,0x0F, 0x00, 0xFF, 0xFC, 0xC0,
               0xC0,0x00,0x30, 0xFF, 0xFC, 0xC0, 0x00,0x0F, 0x00,
               0x00,0x0C, 0x00
                };
carboniser arrow_black [] = {6,1,9,2,2,9,1,19,7,2,8,1}; 
                                         Chapitre 10: Bitmap Images 251


void main ()
             {
               int old_mode;
fg_initpm ();
               if (fg_testmode (4,1) == 0) {
                  printf ( "Ce programme nécessite une 320");
                  ( "le mode x 200 graphiques CGA \ n".) printf;
                   sortie (1);
                   }
fg_getmode old_mode = ();
               fg_setmode (4);
fg_setcolor (2);
               fg_rect (0,319,0,199);
fg_move (10,10);
               fg_drawmask (arrow_black, 12,10);
               fg_drwimage (Arrow_white, 3,7);
               fg_waitkey ();
fg_setmode (old_mode);
               fg_reset ();
             }


Résumé de l'image bitmap d'affichage Routines

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

Pour toutes les routines d'image bitmap, les images sont affichées ou extraites afin

leur coin inférieur gauche est à la position du curseur graphique (ou de la position du curseur de texte pour les routines qui fonctionnent également en mode texte vidéo). Dans des environnements de 16 bits, la taille des éventuels tableaux transmis à ces routines est limitée à 64K octets.

FG_CLIPMAP affiche une image rognée stockée sous forme de bitmap en mode indépendant.

Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_CLIPMASK affiche une image rognée stockée sous forme de carte de masquage.  Ce

routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_CLPIMAGE affiche une image rognée stockée sous forme de bitmap mode spécifique.

Couleur 0 pixels sont considérés comme transparents. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_DISPLAY affiche une image stockée dans l'exécution de pixel standard Fastgraph

le format, où l'image se trouve dans un tableau. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte. Guide de l'utilisateur 252 Fastgraph


FG_DISPLAYP affiche une image stockée dans emballés piste de pixel de Fastgraph

le format, où l'image se trouve dans un tableau. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_DRAWMAP affiche une image stockée sous forme de bitmap en mode indépendant.  Ce

routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_DRAWMASK affiche une image stockée sous forme de carte de masquage. Cette routine a

aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_DRWIMAGE affiche une image stockée sous forme de bitmap mode spécifique. Couleur 0

les pixels sont considérés comme transparents.

FG_FLIPMASK affiche une image écrêté inversée stockée sous forme de carte de masquage.

Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_FLPIMAGE affiche une image écrêté inversée stockée comme un mode spécifique

bitmap. Couleur 0 pixels sont considérés comme transparents. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_GETIMAGE récupère une image en tant que bitmap mode spécifique.

FG_GETMAP récupère une image en tant que bitmap en mode indépendant. Cette routine

n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_IMAGESIZ détermine le nombre d'octets requis pour stocker un mode-

image bitmap spécifique des dimensions spécifiées.

FG_INVERT intervertit l'ordre des lignes d'un mode spécifique ou en mode indépendant

image bitmap, donc un "haut en bas" image devient un "bas en haut" image, ou vice versa.

FG_PACK convertit un bitmap dans le format "un pixel par octet" utilisé dans

modes graphiques 256 couleurs et des tampons virtuels au format spécifique en mode bitmap pour le mode vidéo actuel.

FG_PUTIMAGE affiche une image stockée sous forme de bitmap mode spécifique.  Non

le soutien est prévu pour les pixels transparents.

FG_REVIMAGE affiche une image inversée stockée sous forme de bitmap mode spécifique.

Couleur 0 pixels sont considérés comme transparents. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_REVMASK affiche une image inversée stockée sous forme de carte de masquage.  Ce

routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_SCALE agrandit ou réduit une image bitmap stockée dans le "un pixel

par octet format ".

FG_SHEAR cisaille une image bitmap stockée dans le "un pixel par octet"

format.

FG_UNPACK convertit une image bitmap mode spécifique à la "un pixel par

octet format "utilisé dans les modes graphiques 256 couleurs et des tampons virtuels.

Chapitre 10: Bitmap Images 253


FG_VBADDR renvoie l'adresse de la mémoire tampon virtuelle spécifiée. En 16 bits

modes, l'adresse sera un véritable segment des modes: paire offset ou sélecteur de mode protégé: paire offset. Dans les modes de 32 bits, ce sera un décalage dans le segment de données par défaut. Guide de l'utilisateur 254 Fastgraph



Chapitre 11


Bloc-transfert Routines Guide de l'utilisateur 256 Fastgraph


aperçu

Les routines Fastgraph décrites dans ce chapitre copier des blocs rectangulaires

entre les zones de mémoire vidéo, entre les tampons virtuels, entre la mémoire conventionnelle et la mémoire vidéo, ou entre la mémoire conventionnelle et les tampons virtuels. Ces routines sont parfois appelés Blit ou BitBlt routines dans d'autres documents. Les blocs-transferts sont utiles dans de nombreuses applications graphiques, mais ils sont particulièrement importants dans l'animation.

Fastgraph fournit plusieurs types de routines de transfert de bloc, chaque

optimisé pour son but spécifique. Du fait que ces routines sont souvent utilisés dans des contextes de vitesse critique, ils ne remplissent pas écrêtage. Si nécessaire, l'écrêtage peut généralement être fait au niveau de l'application en ajustant le bloc coordonnées pour tenir dans la zone de découpage.

Ce chapitre discutera des routines de transfert de bloc de Fastgraph en détail.

Les informations présentées ici, combinée à la page vidéo, mémoire virtuelle, et les routines de gestion de l'image des trois chapitres précédents, fournira les outils dont nous avons besoin pour les techniques d'animation présentés dans le chapitre suivant.


Plein transfert

simple routine de transfert de blocs de Fastgraph est fg_copypage, introduit en

Chapitre 8. Les transferts de routine fg_copypage l'ensemble de contenu d'une page vidéo à un autre. Le premier argument est le numéro de la page vidéo source, et le second argument est le numéro de la page de destination vidéo. Les pages peuvent être des pages vidéo physiques, virtuels ou logiques. Si les pages à la fois la source et la destination sont des pages logiques, les pages doivent exister dans le même type de mémoire. Par exemple, vous ne pouvez pas copier une page logique dans la mémoire étendue à une page logique dans la mémoire conventionnelle. La routine de fg_copypage travaille toujours avec des pages vidéo, même si un tampon virtuel est actif.

Exemple 11-1 illustre l'utilisation de fg_copypage dans une couleur 320x200

le mode graphique. Le programme affiche le mot «test» dans le milieu de la page visuelle (page 0) puis fg_allocate utilise pour créer une page vidéo virtuel (page 1). La page virtuelle est nécessaire dans le cas où le programme est en cours d'exécution dans un mode vidéo avec une seule page physique. Ensuite, le programme fg_copypage utilise pour transférer le contenu des pages visuelles à la page 1. Après avoir attendu pendant une séquence de touches, le programme efface la page visuelle, attend une autre touche, et copie le contenu de la page 1 retour à la page visuelle. Il libère alors la page et sorties virtuelles.

Exemple 11-1.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  int new_mode, old_mode;
fg_initpm (); 
                                  Chapitre 11: Bloc-transfert Routines 257


new_mode = fg_bestmode (320,200,2);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_setcolor (7);
                  fg_rect (0,319,0,199);
                  fg_setcolor (9);
                  fg_locate (12,18);
                  fg_text ( "test", 4);
                  fg_waitkey ();
fg_allocate (1);
                  fg_copypage (0,1);
                  fg_erase ();
                  fg_waitkey ();
fg_copypage (1,0);
                  fg_waitkey ();
fg_freepage (1);
                  fg_setmode (old_mode);
                  fg_reset ();
                }


Limites d'octets

La mémoire vidéo, comme la mémoire vive standard, est divisé en unités

appelés octets. En mode texte, chaque octet détient soit un caractère ou un attribut. Dans les modes graphiques, chaque octet de mémoire vidéo détient un ou plusieurs pixels horizontalement contigus. Si deux pixels adjacents horizontaux sont stockés dans différents octets, nous disons une limite d'octet existe entre les deux pixels.

Le nombre de pixels par octet dépend du mode vidéo étant utilisé, de sorte que

l'emplacement des limites d'octets dépend également du mode vidéo. Autrement dit, une limite d'octet dans un mode graphique CGA est pas nécessairement une limite d'octet dans un mode graphique VGA. Le tableau suivant résume le nombre de pixels par octet de mémoire vidéo et les octets des séquences limites pour chaque mode graphique vidéo pris en charge. Notez que toute coordonnée horizontale dont la valeur est un multiple de 8 est toujours une limite d'octet, quel que soit le mode vidéo.

Mode pixels coordonnées horizontales
                    nombre par octet de limites d'octet
4 4 0, 4, 8, 12, ..., 316
                       5 4 0, 4, 8, 12, ..., 316
                       6 8 0, 8, 16, 24, ..., 632
                       9 2 0, 2, 4, 6, ..., 318
                      11 8 0, 8, 16, 24, ..., 712
                      12 4 0, 4, 8, 12, ..., 316   

Guide de l'utilisateur 258 Fastgraph


13 8 0, 8, 16, 24, ..., 312
                      14 8 0, 8, 16, 24, ..., 632
                      15 8 0, 8, 16, 24, ..., 632
                      16 8 0, 8, 16, 24, ..., 632
                      17 8 0, 8, 16, 24, ..., 632
                      18 8 0, 8, 16, 24, ..., 632
                      19 1 0, 1, 2, 3, ..., 319
                      20 1 0, 4, 8, 12, ..., 316
                      21 1 0, 4, 8, 12, ..., 316
                      22 1 0, 4, 8, 12, ..., 316
                      23 1 0, 4, 8, 12, ..., 316
                      24 1 0, 1, 2, 3, ..., 639
                      25 1 0, 1, 2, 3, ..., 639
                      26 1 0, 1, 2, 3, ..., 799
                      27 1 0, 1, 2, 3, ..., 1023
                      28 8 0, 8, 16, 24, ..., 792
                      29 8 0, 8, 16, 24, ..., 1 016
routines de transfert de bloc sont souvent utilisés dans des séquences d'animation nécessitant

graphiques de haute performance, de sorte que ces routines doivent être aussi efficaces que possible. À cette fin, Fastgraph va forcer leurs coordonnées pixel horizontal octet frontières, ce qui élimine la nécessité de traiter tous les pixels individuellement. Fastgraph accomplit ceci en réduisant les coordonnées minimales horizontales à une limite d'octet et étendant les coordonnées maximales horizontales au dernier pixel dans un octet de mémoire vidéo. Puisque nous parlons de coordonnées de pixels et non pas des cellules de caractères, l'ajustement de coordonnées se produit uniquement dans les modes graphiques vidéo. Concevoir une application pour des transferts de blocs se produisent sur les limites d'octet peut prendre une planification supplémentaire, mais ce sera du temps bien dépensé.

Un exemple pourrait mieux contribuer à expliquer cette caractéristique importante.  dans le

modes graphiques 16 couleurs EGA / VGA / SVGA (modes 13 à 18, 28 et 29), les limites d'octet se produisent à chaque huitième pixel. Ainsi, lorsque vous utilisez les routines de transfert de bloc dans ces modes, Fastgraph réduit au minimum x coordonnées au multiple inférieur de huit. De même, il étend leur maximum x coordonnées au multiple supérieur de huit ans, moins un pixel. Autrement dit, si un minimum coordonnée x est de 10 et un maximum de coordonnée x est 30, Fastgraph ajustera ces valeurs à 8 et 31 respectivement. Si les coordonnées x étaient à l'origine 8 et 31, Fastgraph serait de les laisser inchangés.

Dans les modes graphiques 256 couleurs les MCGA et SVGA (modes 19 et 24 à 27)

chaque pixel occupe un octet distinct de la mémoire vidéo, de sorte Fastgraph n'a pas besoin d'ajuster les coordonnées horizontales. Cependant, dans les modes les XVGA graphiques (modes 20 à 23), un certain ajustement de coordonnées peut être nécessaire. Les modes de XVGA stocker quatre pixels à chaque adresse de mémoire vidéo, un dans chacun des quatre plans de bits. Le numéro de plan de bits pour un pixel dont la coordonnée horizontale est x est donnée par la quantité x modulo 4. Dans les modes de XVGA, la source et la destination minimum coordonnées x doit faire référence à des pixels dans le même plan de bits. Autrement dit, la relation

xmin_source modulo 4 = 4 modulo xmin_destination

doit être vrai. Dans le cas contraire, Fastgraph réduit la valeur x destination minimale au même plan de bits que la valeur x source minimale.

Chapitre 11: Bloc-transfert Routines 259


Banks double SVGA

L'accès à la mémoire vidéo en mode graphique SVGA est contrôlée par un

système bancaire qui mappe des blocs de 64Ko contigus de mémoire vidéo dans un espace d'adressage segmenté. En d'autres termes, le référencement d'un octet spécifique dans la mémoire vidéo nécessite un numéro de banque et une adresse dans cette banque. Certains chipsets SVGA fournissent séparé lire et écrire des registres bancaires, tandis que d'autres effectuent les opérations à travers le même registre de la banque.

Si un chipset prend en charge lecture et d'écriture séparées banques, bloc de Fastgraph

des routines de transfert peuvent copier la zone de source directement à la région de destination. Cependant, les chipsets qui emploient un registre bancaire unique exigent que ces routines copient la région de source à un tampon intermédiaire et puis copiez le contenu du tampon à la destination. Cela rend évidemment une opération de transfert de bloc plus lent sur les chipsets mono-bancaires. Bit 3 de la valeur de retour de fg_svgastat sera réglé si le SVGA chipset actif prend en charge lecture séparée et écrire les banques.


La vidéo "Hidden" page

Certaines des routines de transfert de bloc de Fastgraph référencer une page vidéo appelé

la page cachée. La fg_sethpage routine Fastgraph définit quelle page vidéo sera utilisé comme page cachée. Cette routine prend comme seul argument une valeur entière spécifiant le numéro de page cachée. Si vous utilisez une page vidéo virtuel pour la page cachée, vous devez appeler fg_sethpage après l'attribution de cette page. Il y a aussi une routine fg_gethpage nommée qui renvoie le numéro de page cachée, comme spécifié dans l'appel le plus récent à fg_sethpage, comme sa valeur de fonction. La routine de fg_gethpage ne prend aucun argument.


Sauvegarde et restauration de blocs

Les deux prochaines routines de transfert de bloc, nous allons discuter sont fg_save et

fg_restore. Les transferts fg_save de routine d'une région rectangulaire de la page vidéo actif (tel que défini dans l'appel le plus récent à fg_setpage) à la même position sur la page vidéo cachée (tels que définis dans l'appel le plus récent à fg_sethpage). La routine de fg_restore exécute la tâche complémentaire - elle transfère une région rectangulaire de la page cachée à la page active. Chacun de ces routines nécessite quatre arguments qui définissent les coordonnées du bloc à transférer, dans l'ordre minimum x, maximum x, y minimum et maximum de y. Dans les modes de texte, les coordonnées sont exprimées en quantités d'espace de caractères (lignes et colonnes). Dans les modes graphiques, ils sont exprimés en valeurs (pixels) de l'espace de l'écran, avec le x coordonnées étendu aux limites d'octet si nécessaire. Il existe également des versions de l'espace mondial de ces routines nommées fg_savew et fg_restorew disponible dans les modes graphiques. Les routines fg_restore, fg_restorew, fg_save et fg_savew travaillent toujours avec des pages vidéo, même si un tampon virtuel est actif.

Exemple 11-2 illustre l'utilisation de fg_save, fg_restore et fg_sethpage

en mode texte vidéo 80 colonnes. Après avoir établi le mode vidéo (notez les appels à fg_testmode précisent que deux pages vidéo sont nécessaires), le programme remplit l'écran avec le texte, puis attend une touche. Suite à cela, le programme affiche une petite fenêtre pop-up invitant à une autre touche. Après avoir attendu la seconde frappe, le programme efface la fenêtre pop-up par le Guide de l'utilisateur 260 Fastgraph


restaurer le contenu de l'écran d'origine, puis attend encore une autre touche avant de revenir à DOS. Nous présenterons le programme maintenant, et ensuite l'analyser en détail.

Exemple 11-2.
#include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
              void main (void);
void main ()
               {
                 int rangée;
                 int old_mode;
                 chaîne char [17];
fg_initpm ();
                 fg_getmode old_mode = ();
if (fg_testmode (3,2))
                    fg_setmode (3);
                 else if (fg_testmode (7,2))
                    fg_setmode (7);
                  autre {
                    printf ( "Ce programme nécessite \ n");
                    printf ( "un affichage de 80 colonnes. \ n");
                     sortie (1);
                     }
                 fg_cursor (0);
                 fg_setattr (9,7,0);
pour (rang = 0; rangée <25; rangée ++) {
                    sprintf (string, "Ceci est la ligne% 2d", rangée);
                    fg_locate (ligne, 0);
                    fg_text (string, 16);
                    fg_text (string, 16);
                    fg_text (string, 16);
                    fg_text (string, 16);
                    fg_text (string, 16);
                     }
                 fg_waitkey ();
fg_allocate (1);
                 fg_sethpage (1);
                 fg_save (32,47,11,13);
                 fg_setcolor (1);
                 fg_rect (32,47,11,13);
                 fg_setattr (15,1,0);
                 fg_locate (12,33);
                 fg_text ( «Appuyez sur une touche.", 14);
                 fg_waitkey ();
fg_restore (32,47,11,13);
                 fg_waitkey (); 
                                  Chapitre 11: Bloc-transfert Routines 261


fg_freepage (1);
                 fg_setmode (old_mode);
                 fg_reset ();
               }


Exemple 11-2 établit d'abord le mode vidéo et fg_cursor utilise pour faire

le curseur du BIOS invisible. Il exécute ensuite une boucle qui remplit chaque ligne de l'écran avec la phrase "Ceci est la ligne n", où n est le numéro de ligne (entre 0 et 24). Ensuite, le programme utilise fg_allocate pour créer Page vidéo 1 comme une page vidéo virtuelle. Ceci est nécessaire dans le cas où le programme est en cours d'exécution en mode 7, qui n'a qu'une seule vraie la page (si le programme est en cours d'exécution en mode 3, fg_allocate n'a pas d'effet). Le programme fait alors la page 1, la page cachée en appelant fg_sethpage.

Après avoir configuré la page vidéo cachée, mais avant d'afficher le pop-up

fenêtre, par exemple 11-2 fg_save utilise pour enregistrer le contenu actuel de la zone que la fenêtre pop-up va remplacer. Les copies de routine fg_save cette région à la page cachée. Le programme affiche alors la fenêtre pop-up dans le milieu de l'écran et laisse là jusqu'à ce qu'une touche est enfoncée. À la suite de cela, le programme fg_restore utilise pour remplacer la fenêtre pop-up avec le contenu original de cette région. Ceci efface efficacement la fenêtre pop-up et restaure l'écran d'origine. Le programme attend ensuite une autre touche, après quoi il libère la page virtuelle et retourne au DOS.

L'exemple suivant, 11-3, est similaire à l'exemple 11-2, mais il fonctionne dans un

320x200 en mode au lieu d'un mode texte graphique couleur. Les principales différences entre ce programme et l'exemple 11-2 sont l'utilisation du texte de 40 colonnes et l'utilisation de l'espace de l'écran des coordonnées au lieu de caractère coordonne l'espace dans les appels à fg_save, fg_restore et fg_rect. Notez que l'appel à fg_allocate crée une page virtuelle si le programme est en cours d'exécution en mode 4, 9 ou 19. Dans les modes 13 et 20, qui ont respectivement quatre et huit pages physiques, fg_allocate ne fait rien.

Exemple 11-3.
#include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
            void main (void);
void main ()
             {
               int rangée;
               int new_mode, old_mode;
               chaîne char [21];
fg_initpm ();
               new_mode = fg_bestmode (320,200,2);
               if (new_mode <0 || new_mode == 12) {
                  printf ( "Ce programme nécessite une 320");
                  ( "le mode x 200 graphiques couleur \ n".) printf;
                   sortie (1);
                   }
               fg_getmode old_mode = ();
               fg_setmode (new_mode); 

Guide de l'utilisateur 262 Fastgraph


fg_setcolor (7);
               fg_rect (0,319,0,199);
               fg_setcolor (9);
pour (rang = 0; rangée <25; rangée ++) {
                  sprintf (string, "Ceci est la ligne% 2d", rangée);
                  fg_locate (ligne, 0);
                  fg_text (string, 20);
                  fg_text (string, 20);
                   }
               fg_waitkey ();
fg_allocate (1);
               fg_sethpage (1);
               fg_save (96,223,88,111);
               fg_setcolor (1);
               fg_rect (96,223,88,111);
               fg_setcolor (15);
               fg_locate (12,13);
               fg_text ( «Appuyez sur une touche.", 14);
               fg_waitkey ();
fg_restore (96,223,88,111);
               fg_waitkey ();
fg_freepage (1);
               fg_setmode (old_mode);
               fg_reset ();
             }


A Plus Routine Block Transfer général

Les fg_save et fg_restore routines chaque copie une zone rectangulaire à partir

une seule page vidéo sur la même position sur une autre page vidéo. Que faire si vous devez copier la région à une position différente sur une autre page de la vidéo, ou le copier ailleurs sur la page vidéo même? Fastgraph fournit une routine plus générale de transfert de bloc nommé fg_transfer. La fg_transfer copies de routine d'une région rectangulaire sur une page vidéo à une position quelconque sur une page vidéo (cependant, il ne peut pas copier chevauchement des blocs sur la page vidéo même). Comme fg_save et fg_restore, fg_transfer fonctionne en mode texte et des graphiques vidéo. Dans les modes graphiques, fg_transfer étend ses coordonnées x aux limites d'octet si nécessaire. La routine de fg_transfer travaille toujours avec des pages vidéo, même si un tampon virtuel est actif (utilisation fg_vbcut et fg_vbpaste pour copier des blocs entre les tampons virtuels et des pages vidéo ou fg_vbcopy pour copier des blocs entre les tampons virtuels).

La routine de fg_transfer nécessite huit arguments entiers. Les quatre premiers

arguments définissent la région à copier, dans le même ordre que prévu par fg_save et fg_restore. Les deux arguments suivants définissent le coin inférieur gauche de la destination du bloc, tandis que les deux derniers arguments spécifient respectivement la source et la destination des numéros de page vidéo. En bref, des copies de fg_transfer la région spécifiée à partir de la page source à la position indiquée sur la page de destination.

Chapitre 11: Bloc-transfert Routines 263


Exemple 11-4 est identique à l'exemple 11-2, mais elle utilise plutôt fg_transfer

que fg_save et fg_restore. Nous avons arbitrairement choisi de copier la région écrasée par la fenêtre pop-up dans le coin inférieur gauche de la page cachée (page 1). Lorsque nous copions cette région revenir à la page visuelle, nous copions à partir du coin inférieur gauche de la page cachée à la position originale sur la page visuelle (page 0). Cette séquence est représentée dans le schéma suivant.

(11,32) (11,47) (22,0) (22,15)
                                premier appel
              Ceci est la ligne 11 ------------> Ceci est la ligne 11
              Ceci est la ligne 12 Ceci est la ligne 12
              Ceci est la ligne 13 <------------ Ceci est la ligne 13
                                  deuxième appel
            (13,32) (13,47) (24,0) (24,15)
Page visuelle (0) page cachée (1)

Pour copier une région à une nouvelle position, puis revenir à sa position initiale, notons la façon dont nous faisons les cinquième et sixième arguments dans le premier appel à fg_transfer les mêmes valeurs que les premier et quatrième arguments dans le second appel. De même, les cinquième et sixième arguments dans le deuxième appel doivent être les mêmes que les premier et quatrième arguments dans le premier appel. Avec tout ce que hors de la voie, voici par exemple 11-4.

Exemple 11-4.
#include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
              void main (void);
void main ()
               {
                 int rangée;
                 int old_mode;
                 chaîne char [17];
fg_initpm ();
                 fg_getmode old_mode = ();
if (fg_testmode (3,2))
                    fg_setmode (3);
                 else if (fg_testmode (7,2))
                    fg_setmode (7);
                  autre {
                    printf ( "Ce programme nécessite \ n");
                    printf ( "un affichage de 80 colonnes. \ n");
                     sortie (1);
                     }
                 fg_cursor (0);
                 fg_setattr (9,7,0);
pour (rang = 0; rangée <25; rangée ++) {
                    sprintf (string, "Ceci est la ligne% 2d", rangée);
                    fg_locate (ligne, 0); 

Guide de l'utilisateur 264 Fastgraph


fg_text (string, 16);
                    fg_text (string, 16);
                    fg_text (string, 16);
                    fg_text (string, 16);
                    fg_text (string, 16);
                     }
                 fg_waitkey ();
fg_allocate (1);
                 fg_transfer (32,47,11,13,0,24,0,1);
                 fg_setcolor (1);
                 fg_rect (32,47,11,13);
                 fg_setattr (15,1,0);
                 fg_locate (12,33);
                 fg_text ( «Appuyez sur une touche.", 14);
                 fg_waitkey ();
fg_transfer (0,15,22,24,32,13,1,0);
                 fg_fg_waitkey ();
fg_freepage (1);
                 fg_setmode (old_mode);
                 fg_reset ();
               }


Exemple 11-5 illustre une autre utilisation de la routine de fg_transfer.  Ce

exemple est fonctionnellement identique à l'exemple 10-10, mais il utilise au lieu de fg_transfer fg_getmap et fg_drawmap. Avec la routine de fg_transfer, nous éliminons les appels à fg_getmap et fg_drawmap, les deux appels à fg_move, et le tableau de 32 octets besoin pour récupérer le bloc. Comme un bonus supplémentaire, en utilisant fg_transfer est beaucoup plus rapide que la technique de l'exemple 10-10, bien que nous ne remarquerez probablement pas ce gain avec un tel petit bloc.

Le bloc copié dans l'exemple 11-5 est une rangée de quatre personnages, de sorte que son

largeur dans l'espace de l'écran est de 32 pixels et sa hauteur est de 8 pixels. Parce que le bloc est dans le coin supérieur gauche de l'écran, les limites des blocs sont Xmin = 0, xmax = 31, ymin = 0, et ymax = 7. Nous voulons passer d'une demi-cellule de caractère de bloc (4 pixels) à droite et une rangée (8 pixels) vers le bas, de sorte que nos coordonnées de destination sont x = 4 (xmin + 4) et y = 15 (ymax + 8). Notez comment le programme se limite aux modes 19 et 20 pour assurer la copie de bloc ne soit pas affectée par les limites d'octet. En outre, nous copions le bloc d'une position à une autre sur la page visuelle, de sorte que la source et les pages de destination sont 0.

Exemple 11-5.
#include <fastgraf.h>
                 #include <stdio.h>
                 #include <stdlib.h>
                void main (void);
void main ()
                 {
                   int old_mode, new_mode;
fg_initpm (); 
                                  Chapitre 11: Bloc-transfert Routines 265


new_mode = fg_bestmode (320,200,1);
                   if (new_mode <19) {
                      printf ( "Ce programme nécessite une");
                      ( «mode graphique 256 couleurs. \ n") printf;
                       sortie (1);
                       }
fg_getmode old_mode = ();
                   fg_setmode (new_mode);
fg_setcolor (9);
                   fg_text ( "text", 4);
                   fg_waitkey ();
fg_transfer (0,31,0,7,4,15,0,0);
                   fg_waitkey ();
fg_setmode (old_mode);
                   fg_reset ();
                 }


Exemple 11-6 montre encore une autre application de fg_transfer dans un graphisme

mode vidéo. Le programme affiche un rectangle dans le quadrant supérieur gauche de l'écran, puis centre le mot «quadrant» à l'intérieur du rectangle. Après avoir attendu pendant une séquence de touches, le programme utilise fg_transfer d'abord copier le quadrant supérieur gauche au quadrant supérieur droit. Il utilise ensuite à nouveau fg_transfer pour copier la moitié supérieure de l'écran à la moitié inférieure. Le résultat de ceci est l'écran étant rempli de ce qui était initialement dans le quadrant supérieur gauche.

Exemple 11-6.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  int new_mode, old_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                      sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_setcolor (7);
                  fg_rect (0,159,0,99);
                  fg_setcolor (9);
                  fg_locate (6,6);
                  fg_text ( "quadrant", 8); 

Guide de l'utilisateur 266 Fastgraph


fg_waitkey ();
fg_transfer (0,159,0,99,160, 99,0,0);
                  fg_transfer (0,319,0,99, 0,199,0,0);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


Routines Bloc de transfert pour Tampons Virtuels

fg_restore, fg_save et routines fg_transfer de Fastgraph copie blocs

entre les pages vidéo physiques ou virtuels. D'autres routines sont fournies pour les transferts de blocs entre les tampons virtuels et des pages vidéo, ou entre les tampons virtuels. Dans notre discussion de tampons virtuels dans le chapitre 8, nous avons décrit fg_vbcut et fg_vbpaste les routines de Fastgraph. Rappelons que fg_vbcut copies d'un bloc de la page vidéo active à la mémoire tampon virtuelle active, tandis que les copies fg_vbpaste un bloc de la mémoire tampon virtuelle active à la page de la vidéo active.

 Nous allons maintenant présenter une autre routine de transfert de blocs, fg_vbcopy, pour

blocs de copie entre deux tampons virtuels, ou à une position non-chevauchement dans le même tampon virtuel. Les arguments fg_vbcopy sont exactement les mêmes que celles de fg_transfer, à l'exception des deux derniers arguments de référence du tampon de source et la destination virtuelle gère la place des numéros de page vidéo. Exemple 11-7 est analogue à l'exemple 11-6, mais il fg_vbcopy utilise pour effectuer les deux opérations de copie de blocs dans une mémoire tampon virtuelle 320x200 (ceux-ci ont été effectués avec fg_transfer dans l'exemple 06.11). Après cela, il appelle fg_vbpaste pour afficher le contenu du tampon virtuel.

 Exemple 11-7.
 #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main (void);
 #ifdef FG32
               char buffer [64000];
               #autre
               carboniser loin tampon [64000];
               #fin si
 void main ()
               {
                  poignée int;
                  int new_mode, old_mode;
 fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                     sortie (1); 
                                   Chapitre 11: Bloc-transfert Routines 267


 }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
 fg_vbinit ();
                  handle = fg_vbdefine (tampon, 320200);
                  fg_vbopen (poignée);
 fg_setcolor (7);
                  fg_rect (0,159,0,99);
                  fg_setcolor (9);
                  fg_locate (6,6);
                  fg_text ( "quadrant", 8);
 fg_vbcopy (0,159,0,99,160, 99, poignée, poignée);
                  fg_vbcopy (0,319,0,99, 0199, poignée, poignée);
                  fg_vbpaste (0,319,0,199,0,199);
                  fg_waitkey ();
 fg_vbclose ();
                  fg_setmode (old_mode);
                  fg_reset ();


Blocks avec les couleurs transparentes

 Les routines suivante de transfert de bloc, nous allons discuter sont fg_tcxfer, fg_tcmask,

et fg_tcdefine. La routine de fg_tcxfer est similaire à fg_transfer en ce qu'il copie une zone rectangulaire d'une position à une autre, mais fg_tcxfer vous permet de traiter une ou plusieurs couleurs comme transparent (le nom fg_tcxfer signifie le transfert de couleur transparente). En d'autres termes, tout pixel dont la couleur valeur est définie pour être transparent ne sont pas copiées vers la zone de destination. Les arguments de la routine de fg_tcxfer sont les mêmes que pour la routine de fg_transfer, mais fg_tcxfer n'a aucun effet en mode vidéo de texte. Parce que fg_tcxfer doit examiner la couleur des pixels individuels, il est presque aussi rapide que fg_transfer. La routine de fg_tcxfer travaille toujours avec des pages vidéo, même si un tampon virtuel est actif (routine de fg_vbtcxfer, décrite dans la section suivante, fournit des transparents les transferts de blocs de couleur pour les tampons virtuels).

 Vous pouvez utiliser fg_tcmask ou fg_tcdefine pour définir les couleurs qui sont

considéré comme transparent dans les appels ultérieurs à fg_tcxfer.L'argument de la routine fg_tcmask est un masque de bits entier (plus précisément, un masque de 16 bits) où chaque bit indique si oui ou non la couleur est transparente. Par exemple, si le bit 0 (le bit de droite) est situé dans le masque, puis la couleur 0 sera transparent; si le bit 0 est remis à zéro, la couleur 0 ne sera pas transparent. Parce que la taille de masque de bits est de 16 bits, seules les 16 premières valeurs de couleur peuvent être définis comme transparent en utilisant fg_tcmask.

Exemple 8.11 illustre l'utilisation des fg_tcxfer et fg_tcmask routines.

Ce programme est similaire à l'exemple 11-6, sauf la couleur du mot «quadrant» (couleur 9) est défini comme étant transparent, et fg_tcxfer est utilisé à la place de fg_transfer. Parce que la couleur 9 cartes à colorier 1 en mode quatre couleurs graphiques CGA (mode 4), nous devons définir les deux couleurs 1 et 9 pour être transparent (rappelez-vous, fg_tcmask considère les valeurs de couleurs réelles transparentes, et non pas des indices de couleur). Le masque de bits transmis à fg_tcmask ainsi sera 0000 0010 0000 0010 Guide de l'utilisateur 268 Fastgraph


binaire ou 0202 hex. Cela provoque le mot «quadrant» pour apparaître dans la couleur de fond (couleur 0) au lieu de la couleur 9 en haut à droite, en bas à gauche et en bas à droite quadrants.

Exemple 11-8.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  int new_mode, old_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                     sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_setcolor (7);
                  fg_rect (0,159,0,99);
                  fg_setcolor (9);
                  fg_locate (6,6);
                  fg_text ( "quadrant", 8);
                  fg_waitkey ();
fg_tcmask (0x0202);
                  fg_tcxfer (0,159,0,99,160, 99,0,0);
                  fg_tcxfer (0,319,0,99, 0,199,0,0);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


La routine fg_tcdefine attend deux arguments entiers - une définition de la

numéro de couleur (entre 0 et 255) et une autre définition de l'état de la transparence associée à cette couleur. Si l'état est égal à zéro, la couleur spécifiée sera opaque (non transparent). S'il est une autre valeur, la couleur sera transparente. Dans l'exemple précédent, nous pourrions utiliser fg_tcdefine au lieu de fg_tcmask pour rendre les couleurs 1 et 9 transparent en remplaçant l'appel à fg_tcmask ce qui suit:


fg_tcdefine (1,1);
                             fg_tcdefine (9,1); 
                                  Chapitre 11: Bloc-transfert Routines 269


Si vous ne l'appelez fg_tcmask ou fg_tcdefine, la routine de fg_tcxfer considère pas de couleurs transparentes.


Transferts de blocs transparents pour Tampons virtuels

fg_vbtcxfer routine transfère des blocs de Fastgraph avec des couleurs transparentes

de la mémoire tampon virtuelle active à la page de la vidéo active. Ses arguments identiques à ceux de fg_vbpaste, mais il ne copie pas les pixels dont les couleurs sont transparentes. Les fg_tcdefine ou fg_tcmask routines définissent quelles couleurs sont transparentes, comme lors de l'utilisation fg_tcxfer.

Exemple 11-9 donne le même résultat que l'exemple 11-8, mais il le fait

en utilisant des tampons virtuels. Plutôt que de créer un tampon virtuel en plein écran, cependant, cet exemple crée un tampon d'un quart virtuel de la taille de l'écran et transfère le contenu du tampon virtuel pour chaque quadrant de la page visuelle dans quatre opérations distinctes. Dans le quadrant supérieur gauche, nous appelons simplement fg_vbpaste pour afficher le contenu du tampon virtuel. Les trois appels fg_vbtcxfer emplissent les autres quadrants, mais avec la couleur 9 pixels étant transparent. Cette séquence d'opérations de copie de bloc de la mémoire tampon virtuelle crée le même affichage résultant comme exemple 11-8. Notez que cet exemple fg_tcdefine utilise pour faire la couleur 9 transparent; nous pourrions tout aussi bien avoir fg_tcmask utilisé.

Exemple 11-9.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
#ifdef FG32
               char buffer [16000];
                #autre
               carboniser loin tampon [16000];
                #fin si
void main ()
                {
                  poignée int;
                  int new_mode, old_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                     sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_vbinit ();
                  handle = fg_vbdefine (tampon, 160100);
                  fg_vbopen (poignée);
fg_setcolor (7); 

Guide de l'utilisateur 270 Fastgraph


fg_fillpage ();
                  fg_setcolor (9);
                  fg_locate (6,6);
                  fg_text ( "quadrant", 8);
                  fg_vbpaste (0,159,0,99,0,99);
                  fg_waitkey ();
fg_tcdefine (9,1);
                  fg_vbtcxfer (0,159,0,99,160,99);
                  fg_vbtcxfer (0,159,0,99,0,199);
                  fg_vbtcxfer (0,159,0,99,160,199);
                  fg_waitkey ();
fg_vbclose ();
                  fg_setmode (old_mode);
                  fg_reset ();
                }


Transfert de blocs vers et depuis la mémoire conventionnelle

Les deux dernières routines de transfert de bloc, nous allons discuter sont fg_getblock et

fg_putblock. Les fg_getblock transferts de routine d'une région rectangulaire de la page vidéo active ou tampon virtuel à un tableau (vous pouvez utiliser fg_imagesiz pour déterminer la taille du tableau nécessaire pour stocker le bloc). Le fg_putblock transferts de routine d'un bloc précédemment récupéré avec fg_getblock à la page active ou tampon virtuel. Bien que ces deux routines sont plus rapides que fg_getimage et fg_putimage, ils ne sont pas aussi vite que fg_restore, fg_save et fg_transfer.

Chacun de ces routines nécessite cinq arguments. La première est l'adresse

du tableau qui va recevoir ou qui contient le bloc. Les quatre autres arguments définissent la position du bloc sur la page active ou tampon virtuel, dans l'ordre minimum x, maximum x, y minimum et maximum de y. Dans les modes de texte, les coordonnées sont exprimées en quantités d'espace de caractères (lignes et colonnes). Dans les modes graphiques, ils sont exprimés en valeurs (pixels) de l'espace de l'écran, avec le x coordonnées étendu aux limites d'octet si nécessaire.

Notez que les deux fg_getblock et fg_putblock attendent l'adresse de réseau pour être

passé par référence, sauf dans la mesure BASIC. Cela signifie que les programmes Pascal en mode réel doivent utiliser la procédure GetMem pour allouer le stockage de la mémoire tampon, comme cela est le seul moyen de passer quelque chose par référence loin en mode réel Pascal. Dans les environnements 16 bits, la taille maximale d'un bloc est 64K octets, quel que soit le compilateur que vous utilisez.

Exemple 11-10 est similaire à l'exemple 11-5 et montre fg_getblock et

fg_putblock en action dans un mode graphique 320x200. Le programme affiche le mot «texte» et récupère dans un bloc de pixels 32 par 8. Après une séquence de touches, il affiche le bloc de 8 pixels ci-dessous et 8 pixels à la droite de sa position initiale. La taille de la mémoire tampon a été choisi pour être de 256 octets pour tenir compte de la plus grande taille requise pour un 32 bloc de 8 (qui se produit dans les modes graphiques de 256 couleurs). Notez également comment la source et de destination horizontales extrêmes de blocs ont été choisis pour l'alignement de la limite d'octet dans le cas où fg_bestmode sélectionné un mode graphique de 16 couleurs.

Exemple 11-10. 
                                  Chapitre 11: Bloc-transfert Routines 271


#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
#ifdef FG32
               char buffer [256];
                #autre
               CHAR loin tampon [256];
                #fin si
void main ()
                {
                  int old_mode, new_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                     sortie (1);
                      }
fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_setcolor (9);
                  fg_text ( "text", 4);
                  fg_getblock (tampon, 0,31,0,7);
                  fg_waitkey ();
fg_putblock (tampon, 8,39,8,15);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


Résumé des programmes de transfert de bloc

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

Pour toutes les routines de transfert de bloc, Fastgraph étend le pixel horizontal

les coordonnées à une limite d'octet lorsque les routines sont utilisées dans un mode vidéo graphique.

FG_COPYPAGE transfère le contenu d'une page vidéo à un autre.  le

pages peuvent être des pages vidéo physiques, virtuels ou logiques. Si les deux pages sont des pages logiques, ils doivent exister dans le même type de mémoire. La routine de fg_copypage ne fonctionne pas avec des tampons virtuels. Guide de l'utilisateur 272 Fastgraph


FG_GETBLOCK récupère le bloc (pour l'affichage plus tard avec fg_putblock) à

la position spécifiée sur la page vidéo active ou tampon virtuel. Dans les modes de texte, les extrêmes de blocs sont définis dans l'espace de caractère; dans les modes graphiques, ils sont définis dans l'espace de l'écran.

FG_GETHPAGE renvoie le numéro de page cachée, tel que défini dans le plus récent

appeler à fg_sethpage.

FG_PUTBLOCK affiche le bloc (précédemment obtenu avec fg_getblock) à

la position spécifiée sur la page vidéo active ou tampon virtuel. Dans les modes de texte, les extrêmes de blocs sont définis dans l'espace de caractère; dans les modes graphiques, ils sont définis dans l'espace de l'écran.

FG_RESTORE copies d'un bloc de la page vidéo cachée à la même position

sur la page de la vidéo active. La routine de fg_restore ne fonctionne pas avec des tampons virtuels.

FG_RESTOREW est identique à celle fg_restore, mais les extrémités du bloc sont

spécifié en tant que coordonnées de l'espace mondial. La routine de fg_restorew ne fonctionne pas avec des tampons virtuels.

FG_SAVE copies d'un bloc de la page vidéo active à la même position sur

la page vidéo cachée. La routine de fg_save ne fonctionne pas avec des tampons virtuels.

FG_SAVEW est identique à celle fg_save, mais les extrémités du bloc sont spécifiés comme

coordonne l'espace mondial. La routine fg_savew ne fonctionne pas avec des tampons virtuels.

FG_SETHPAGE définit la page vidéo cachée (utilisée par fg_restore,

fg_restorew, fg_save et fg_savew).

FG_TCDEFINE définit l'attribut transparent d'un indice de couleur pour une utilisation

avec la routine de fg_tcxfer. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_TCMASK définit lequel des 16 premières couleurs du fg_tcxfer de volonté de routine

envisager transparent. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode vidéo texte.

FG_TCXFER copies d'un bloc de toutes les positions sur une page vidéo à tout

position sur une page vidéo, à l'exclusion des pixels dont la valeur de couleur est transparente. Cette routine n'a aucun effet lorsqu'il est utilisé dans un mode texte et vidéo ne fonctionne pas avec des tampons virtuels.

FG_TRANSFER copies d'un bloc de toutes les positions sur une page vidéo à tout

position sur une page vidéo. Il est le plus grand bloc de routine de transfert de Fastgraph. La routine de fg_transfer ne fonctionne pas avec des tampons virtuels.

FG_VBCOPY copies d'une région rectangulaire d'un tampon virtuel à un autre,

ou à une position sans chevauchement à l'intérieur de la même mémoire tampon virtuelle.

FG_VBTCXFER copies d'une région rectangulaire de la mémoire tampon virtuelle active à

la page de la vidéo active, à l'exclusion des pixels transparents.



chapitre 12


Techniques d'animation 274 Guide de l'utilisateur Fastgraph


aperçu

Contrairement à d'autres micro-ordinateurs, le PC IBM et PS / 2 famille de systèmes ne sont pas

avoir un matériel spécial graphique ou firmware pour aider dans l'exécution de l'animation. Cela signifie toute animation fait sur ces systèmes doit être entièrement mis en oeuvre par le logiciel. Ce chapitre montre comment faire en utilisant la gestion des pages vidéo de Fastgraph, affichage de l'image, et de bloquer les routines de transfert. Les méthodes décrites dans ce chapitre ne sont pas destinés à être tout compris, car ce serait lui-même remplir un volume distinct au moins aussi grand que ce manuel. Cependant, les techniques d'animation présentés ici devraient fournir une base que vous pouvez facilement étendre à développer des utilisations plus sophistiquées de l'animation. Les exemples de ce chapitre sont limitées aux modes graphiques vidéo.


Animations simple

Le premier type d'animation que nous allons examiner est appelée animation simple.  Dans

animation simple, nous affichons un objet, l'effacer, puis l'afficher dans une nouvelle position. Lorsque nous effectuons cette «effacer et réafficher" séquence répétitive, l'objet se déplace. Ce procédé présente cependant deux inconvénients. Tout d'abord, à moins que l'objet est plutôt petit, il scintillement parce que l'effacement et l'affichage de l'objet ne coïncide pas avec le taux de l'affichage vidéo de rafraîchissement. Deuxièmement, et peut-être plus important encore, quoi que ce soit sous l'objet n'a pas été enregistré en tant que l'objet se déplace à travers elle. Malgré ces limites, l'animation simple est parfois utile, et il est un bon endroit pour commencer notre discussion sur les techniques d'animation.

Exemple 12-1 déplace un petit rectangle vert clair (magenta dans CGA) de

de gauche à droite sur l'écran dans un mode graphique 320x200 couleur. Le programme se déplace le rectangle, 20 pixels de large et 10 pixels de haut, en utilisant une boucle for. Cette boucle fg_clprect utilise d'abord pour afficher le rectangle, puis fg_waitfor utilise pour laisser l'objet sur l'écran momentanément, et fg_clprect utilise enfin à nouveau pour effacer le rectangle en réafficher dans la couleur de fond d'origine (fg_waitfor est décrit au chapitre 16). Nous utilisons fg_clprect plutôt que fg_rect parce que les premières et dernières quelques itérations de la boucle aboutissent à au moins une partie du rectangle étant hors de l'écran. Chaque itération de boucle successive affiche le rectangle cinq pixels à droite de sa position précédente.

Exemple 12-1.
#include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
        void main (void);
void main ()
         {
           int new_mode, old_mode;
           int x;
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
           new_mode = fg_bestmode (320,200,1); 
                                     Chapitre 12: Techniques d'animation 275


if (new_mode <0 || new_mode == 12) {
              printf ( "Ce programme nécessite une 320");
              ( "le mode x 200 graphiques couleur \ n".) printf;
              sortie (1);
               }
           fg_getmode old_mode = ();
           fg_setmode (new_mode);
/ * Déplacer l'objet à travers l'écran * /
for (x = -20; x <320; x + = 5) {
              fg_setcolor (10);
              fg_clprect (x, x + 19,95,104);
              fg_waitfor (1);
              fg_setcolor (0);
              fg_clprect (x, x + 19,95,104);
               }
/ * Rétablir le mode vidéo original et revenir à DOS * /
fg_setmode (old_mode);
           fg_reset ();
         }


Exemple 12-2 est identique à l'exemple 12-1, mais il montre ce qui arrive quand

on déplace le rectangle sur un arrière-plan existant (dans ce cas, le fond est blanc solide). Si vous exécutez ce programme, vous verrez que le rectangle laisse une traînée de couleur 0 pixels derrière elle. Bien que cela puisse être parfois utile, il démontre que l'animation simple est destructive car il ne conserve pas l'arrière-plan. Dans cet exemple, si nous avons changé le deuxième appel à fg_setcolor au sein de la boucle pour revenir à la couleur 15 au lieu de la couleur 0, l'arrière-plan serait rétabli. En général, cependant, il peut ne pas être aussi facile de remplacer l'arrière-plan, nous devons donc compter sur une autre méthode pour la préserver.

Exemple 12-2.
#include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
        void main (void);
void main ()
         {
           int new_mode, old_mode;
           int x;
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
           new_mode = fg_bestmode (320,200,1);
           if (new_mode <0 || new_mode == 12) {
              printf ( "Ce programme nécessite une 320");
              ( "le mode x 200 graphiques couleur \ n".) printf;
              sortie (1); 

Guide de l'utilisateur 276 Fastgraph


 }
           fg_getmode old_mode = ();
           fg_setmode (new_mode);
/ * Tirer un certain type de fond * /
fg_setcolor (15);
           fg_rect (0,319,0,199);
/ * Déplacer l'objet à travers l'écran * /
for (x = -20; x <320; x + = 5) {
              fg_setcolor (10);
              fg_clprect (x, x + 19,95,104);
              fg_waitfor (1);
              fg_setcolor (0);
              fg_clprect (x, x + 19,95,104);
               }
/ * Rétablir le mode vidéo original et revenir à DOS * /
fg_setmode (old_mode);
           fg_reset ();
         }


Pour résumer, nous avons vu que l'animation simple est facile à mettre en œuvre, mais

il est destructeur et provoque généralement l'objet animé de scintillement. Pour toutes ces raisons, il n'a pas été utilisé trop fréquemment.


XOR Animations

animation "Exclusive ou" animation, ou XOR pour faire court, est un intéressant

extension de l'animation simple et est très utile lors de l'animation d'un objet d'une seule couleur sur un fond d'une seule couleur. Comme animation simple, il utilise la technique "effacer et réafficher" pour déplacer un objet, mais il le fait différemment. Au lieu d'effacer l'objet en l'affichant dans la couleur de fond, l'animation XOR fait à l'aide de la même couleur en utilisant un ou exclusif, ou XOR, opération. Cette méthode repose sur une propriété spécifique de l'opérateur ou exclusif:

(Objet XOR fond) objet XOR = fond

En d'autres termes, si quelque chose XOR deux fois dans la même position, le résultat est le même que celui de l'image originale dans cette position.

Exemple 12-3 montre animation XOR. Ce programme est similaire à

exemple 12-2, mais il ne fonctionne que dans le mode graphique EGA 320x200 (mode 13). Après avoir établi le mode vidéo, il utilise la routine fg_setfunc Fastgraph pour sélectionner le mode XOR. Cela provoque aucune sortie graphique ultérieure à XORed avec le contenu de la mémoire vidéo au lieu de simplement remplacer. La routine de fg_setfunc est décrite plus loin dans le chapitre 17.

Les autres différences entre les exemples 12-3 et 12-2 sont que l'appel à

fg_setcolor a été déplacé en dehors de la boucle, et que fg_setcolor prend une

Chapitre 12: Techniques d'animation 277


valeur différente. Depuis l'arrière-plan existant est blanc brillant (couleur 15), nous ne pouvons pas utiliser la couleur 10 si l'on veut afficher un objet vert vif. La valeur désirée est celle qui quand XORed avec la couleur 15 produit de couleur 10; la meilleure manière d'obtenir cette valeur est de XOR ces deux nombres. L'appel à fg_setcolor peut être déplacé en dehors de la boucle parce que nous affichons l'objet en utilisant le même indice de couleur tout au long.

Exemple 12-3.
#include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
        void main (void);
void main ()
         {
           int old_mode;
           int x;
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
           if (fg_testmode (13,1) == 0) {
              printf ( "Ce programme nécessite EGA. \ n");
              sortie (1);
               }
           fg_getmode old_mode = ();
           fg_setmode (13);
           fg_setfunc (3);
/ * Tirer un certain type de fond * /
fg_setcolor (15);
           fg_rect (0,319,0,199);
/ * Déplacer l'objet à travers l'écran * /
fg_setcolor (10 ^ 15);
           for (x = -20; x <320; x + = 5) {
              fg_clprect (x, x + 19,95,104);
              fg_waitfor (1);
              fg_clprect (x, x + 19,95,104);
               }
/ * Rétablir le mode vidéo original et revenir à DOS * /
fg_setmode (old_mode);
           fg_reset ();
         }


Fastgraph ne supporte que l'opération XOR de pixel dans le EGA et VGA natif

modes graphiques vidéo (modes 13 à 18) et 16 couleurs modes (28 et 29) SVGA. Ainsi, vous ne pouvez pas utiliser l'animation XOR dans CGA, Tandy / PCjr, Hercules, ou 256- modes graphiques de couleurs. Guide de l'utilisateur 278 Fastgraph


Tandis que l'animation XOR est non destructive (qui est, elle restaure l'original

arrière-plan), il souffre encore du scintillement rencontré dans une animation simple. En dépit de cela, il peut être utile lors de l'animation d'un objet d'une seule couleur sur un fond d'une seule couleur.


Animation cadre statique

animation cadre statique utilise une stratégie différente de celle animation simple ou

animation XOR. Le régime général de cette méthode est de créer la séquence d'animation entière hors de l'écran, puis afficher successivement chaque élément, ou un cadre, dans cette séquence sur une position de la page vidéo visuelle. Il en résulte une animation visuellement attrayant qui est non destructive et ne comprend pas le scintillement associé à une animation simple et animation XOR. animation cadre statique nécessite la page visuelle de vidéo et une ou plusieurs pages supplémentaires (ou les tampons virtuels) à mettre en œuvre. Le nombre de pages nécessaires dépend du nombre d'images et la taille de chaque trame.

Exemple 12-4 fonctionne dans tous les modes graphiques vidéo 320x200 de couleur et

illustre une utilisation simple de l'animation d'image statique. Le programme affiche une séquence d'animation contenant 12 images; il affiche cette séquence trois fois. La séquence d'animation se compose d'un rectangle vert clair (magenta dans CGA) se déplaçant de gauche à droite à travers le centre du cadre. Chaque cadre est de 96 pixels de large et 50 pixels de haut. Les 12 cadres sont mis en place sur une page vidéo hors de l'écran, comme indiqué ici:

0 95 96 191 192 287
 0
                        cadre 1 cadre 2 cadre 3
                    49
 50
                        cadre 4 cadre 5 cadre 6
                    99
100
                        cadre 7 cadre 8 cadre 9
                   149
150
                        frame 10 frame 11 frame 12
                   199


Exemple 12-4 établit d'abord le mode vidéo et alloue la

Page vidéo supplémentaire (nécessaire si vous utilisez un mode vidéo dans lequel la page 1 est une page vidéo virtuelle). Le programme génère alors l'arrière-plan pour l'image 1; l'arrière-plan est un rectangle bleu (cyan dans CGA) avec une ellipse blanche centrée sur elle. Après l'appel à fg_ellipse, la première image est prêt.

L'étape suivante consiste à créer les 11 images restantes. Dans le cadre 2, le droit

la moitié des 20 pixels de large rectangle va entrer dans le bord gauche du cadre. Dans le cadre 3, le rectangle sera dix pixels plus à droite, ou alignés contre le bord gauche du cadre. Dans les cadres 4 à 12, le rectangle sera dix pixels plus loin à droite dans chaque trame, de sorte que par image 12, seule la moitié gauche de la

Chapitre 12: Techniques d'animation 279


rectangle apparaît sur le bord droit du cadre. La première boucle dans le programme construit des trames 2 à 12 en copiant l'arrière-plan de l'image 1, puis afficher le rectangle (qui est, l'objet animé) dans la bonne position pour cette trame.

La seconde boucle exécute la séquence d'animation. Pour afficher le 12-

séquence de trame à trois reprises, il doit effectuer 36 itérations. La boucle copie simplement chaque image de la bonne position sur la page vidéo 1 au milieu de la page vidéo visuelle. Notez comment fg_waitfor est utilisé pour faire une pause momentanée entre les images.

Exemple 12-4.
#include <fastgraf.h>
       #include <stdio.h>
       #include <stdlib.h>
      void main (void);
#define VISUAL 0
      #define HIDDEN 1
int xmin [] = {0, 96192, 0, 96192, 0, 96192, 0, 96192};
      int ymax [] = {49, 49, 49, 99, 99, 99.149.149.149.199.199.199};
void main ()
       {
         int new_mode, old_mode;
         cadre int, offset;
         int i, x, y;
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
         new_mode = fg_bestmode (320,200,2);
         if (new_mode <0 || new_mode == 12) {
            printf ( "Ce programme nécessite une 320");
            ( "le mode x 200 graphiques couleur \ n".) printf;
            sortie (1);
             }
         fg_getmode old_mode = ();
         fg_setmode (new_mode);
         fg_allocate (HIDDEN);
/ * Dessiner l'arrière-plan dans le coin supérieur gauche * /
fg_setpage (HIDDEN);
         fg_setcolor (1);
         fg_rect (0,95,0,49);
         fg_setcolor (15);
         fg_move (48,25);
         fg_ellipse (20,20);
/ * Afficher l'objet animé contre chaque fond * /
fg_setcolor (10);
         offset = -10; 

Guide de l'utilisateur 280 Fastgraph


for (i = 1; i <12; i ++) {
            x = xmin [i];
            y = ymax [i];
            fg_transfer (0,95,0,49, x, y, HIDDEN, HIDDEN);
            fg_setclip (x, x + 95,0,199);
            fg_clprect (x + offset, x + offset + 19, y-29, y-20);
            offset + = 10;
             }
/ * Glisser l'objet à travers le fond trois fois * /
for (i = 0; i <36; i ++) {
            frame = i% 12;
            x = xmin [cadre];
            y = ymax [cadre];
            fg_transfer (x, x + 95, y-49, y, 112124, HIDDEN, VISUAL);
            fg_waitfor (2);
             }
/ * Rétablir le mode vidéo original et revenir à DOS * /
fg_freepage (HIDDEN);
         fg_setmode (old_mode);
         fg_reset ();
       }


Animation Dynamic Frame

animation d'images dynamique est similaire à l'animation d'image statique, mais tout le

trames d'animation sont construites selon les besoins au cours de la séquence d'animation au lieu de l'avance. En utilisant cette méthode, vous devez d'abord stocker une copie de l'arrière-plan sur une page vidéo hors écran. Ensuite, pour construire un cadre, créer une autre copie (appelé l'espace de travail) de l'arrière-plan ailleurs sur la page hors de l'écran (ou même à une autre page hors de l'écran) et afficher l'objet sur cette copie. Enfin, transférer l'espace de travail à la page visuelle. Comme animation d'images statiques, cette méthode produit une séquence d'animation sans scintillement non destructif.

Exemple 12-5 est fonctionnellement identique à l'exemple 12-4, mais il utilise

dynamique plutôt que statique animation d'images. Comme précédemment, le programme construit l'arrière-plan dans le coin supérieur gauche de la page vidéo 1, mais il fg_transfer utilise ensuite pour le copier dans le centre de la page vidéo visuelle. La boucle for construit chaque image comme elle est nécessaire et aussi des copies au centre de la page visuelle. Encore une fois, fg_waitfor crée la pause nécessaire entre les cadres.

Exemple 12-5.
#include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
        void main (void);
#define VISUAL 0   
                                     Chapitre 12: Techniques d'animation 281


#define HIDDEN 1
void main ()
         {
           int new_mode, old_mode;
           cadre int, offset;
            int i;
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
           new_mode = fg_bestmode (320,200,2);
           if (new_mode <0 || new_mode == 12) {
              printf ( "Ce programme nécessite une 320");
              ( "le mode x 200 graphiques couleur \ n".) printf;
              sortie (1);
               }
           fg_getmode old_mode = ();
           fg_setmode (new_mode);
           fg_allocate (HIDDEN);
/ * Dessiner l'arrière-plan dans le coin supérieur gauche * /
fg_setpage (HIDDEN);
           fg_setcolor (1);
           fg_rect (0,95,0,49);
           fg_setcolor (15);
           fg_move (48,25);
           fg_ellipse (20,20);
/ * Copier dans le centre de la page visuelle * /
fg_transfer (0,95,0,49,112,124, HIDDEN, VISUAL);
/ * Glisser l'objet à travers le fond trois fois * /
fg_setcolor (10);
           for (i = 0; i <36; i ++) {
              frame = i% 12;
              offset = 10 * frame - 10;
              fg_transfer (0,95,20,29,112,105, HIDDEN, HIDDEN);
              fg_rect (112 + offset, 131 + offset, 96105);
              fg_transfer (112,207,96,105,112,105, HIDDEN, VISUAL);
              fg_waitfor (2);
               }
/ * Rétablir le mode vidéo original et revenir à DOS * /
fg_freepage (HIDDEN);
           fg_setmode (old_mode);
           fg_reset ();
         }


Deux articles dans l'exemple 12-5 méritent un examen plus approfondi. Tout d'abord, nous avons choisi

notre espace de travail à la page 1, il utilise donc les mêmes coordonnées d'espace d'écran comme le Guide de l'utilisateur 282 Fastgraph


zone d'image sur la page visuelle. Ce n'est pas nécessaire, sauf si vous utilisez fg_restore au lieu de fg_transfer. Deuxièmement, le programme peut utiliser la routine fg_rect plus rapidement à la place de fg_clprect. Elle peut le faire parce que même si l'objet va au-delà des limites de l'espace de travail, nous ne transférons l'espace de travail lui-même. Cependant, pour que cela fonctionne correctement, les limites horizontales de l'espace de travail doivent tomber sur les limites d'octet.

Notez aussi que nous ne devons pas transférer la totalité du cadre pendant la

séquence d'animation. Dans l'exemple 12-5, nous savons que les extrêmes verticales de l'image en mouvement sont y = 96 et y = 105, de sorte que nous ne transférons 10 lignes au lieu de l'image entière. On pourrait de même calculer les x extrêmes pour chaque trame et seulement transférer la partie nécessaire. Rappelons, cependant, que fg_transfer étend les coordonnées horizontales octet frontières, afin que nous puissions copier quelques pixels supplémentaires ainsi. Cela peut ou peut ne pas affecter la séquence d'animation. Encore une fois, le problème est éliminé si vous alignez votre espace de travail sur les limites d'octet.

Lorsque nous utilisons l'animation de cadre dynamique, il est facile de modifier le nombre de

trames dans la séquence d'animation. Supposons que nous voulions produire une animation plus fluide en augmentant le nombre de trames de 12 à 24. Cela signifie que l'objet se déplace par incréments de cinq pixels au lieu de dix. Les seules modifications nécessaires sont de doubler le nombre d'itérations de la boucle, modifier les calculs pour le numéro de l'image et les valeurs de décalage comme indiqué ici, et de réduire la pause de fg_waitfor 2-1.


frame = i% 24;
                         offset = 5 * frame - 10;


Comparez cela à tous les changements qui seraient nécessaires si nous utilisions l'animation du cadre statique.


page Flipping

Page flipping est une variation de l'animation de cadre dans lequel vous construire

les images des pages vidéo hors écran et ensuite faire répétitivement ces pages la page visuelle. Nous pouvons diviser davantage la page technique de retournement dans les variantes statiques et dynamiques, comme nous l'avons fait avec l'animation du cadre.

En page statique retournement, nous construisons la séquence d'animation entière dans

avancer, avec une image par page vidéo. Une fois cela fait, nous pouvons afficher chaque image en utilisant fg_setvpage pour passer instantanément d'une page vidéo à un autre. Bien que ce produit une animation fluide, sans scintillement, nous ne pouvons pas réaliser la séquence très loin avant de manquer de pages vidéo (et donc des images d'animation).

En page dynamique de retournement, on construit chaque trame d'animation quand il est

nécessaire.Comme dans la page statique retournement, nous construisons chaque image sur une page vidéo séparée. Toutefois, à titre d'exemple 12-6 montre, nous avons seulement besoin de trois pages vidéo pour produire la séquence d'animation, quel que soit le nombre d'images dans la séquence. Deux des trois pages vidéo alterneront comme la page visuelle, tandis que la page vidéo restante conserve une copie de l'arrière-plan.

Exemple 12-6, qui exécute une séquence d'animation similaire aux exemples

12-4 et 12-5, illustre l'animation de cadre dynamique dans les 320x200 graphiques EGA

Chapitre 12: Techniques d'animation 283


mode vidéo (mode 13). Le programme commence par l'affichage de l'arrière-plan sur la vidéo la page 2. pages vidéo 0 et 1 alterneront comme la page visuelle; la page qui est pas la page visuelle est appelée la page cachée. Nous commençons par la page 0 comme la page visuelle, et donc la page 1 de la page cachée. Pour construire chaque image, le programme utilise fg_transfer pour copier l'arrière-plan de la page 2 à la page cachée, puis fg_clprect utilise pour afficher l'objet animé à la bonne position sur la page cachée. Après cela, il affiche l'image suivante en utilisant fg_setvpage pour rendre la page cachée de la page visuelle. Avant de commencer la prochaine itération, le programme permet de basculer le numéro de page cachée dans la préparation pour la trame suivante.

Exemple 12-6.
#include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
        void main (void);
void main ()
         {
           int old_mode;
           int caché;
           int x;
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
           if (testmode (fg_13,3) == 0) {
              printf ( "Ce programme nécessite EGA. \ n");
              sortie (1);
               }
           fg_getmode old_mode = ();
           fg_setmode (13);
/ * Dessiner l'arrière-plan à la page deux * /
fg_setpage (2);
           fg_setcolor (1);
           fg_rect (0,319,0,199);
           fg_setcolor (15);
           fg_move (160,100);
           fg_ellipse (20,20);
/ * Glisser l'objet sur l'écran * /
= Cachés 1;
           setcolor (10);
           for (x = -10; x <320; x + = 4) {
              fg_setpage (caché);
              fg_transfer (0,319,0,199,0,199,2, caché);
              fg_clprect (x, x + 19,96,105);
              fg_setvpage (caché);
              caché = 1 - caché;
              fg_waitfor (1);
              }   

Guide de l'utilisateur 284 Fastgraph


/ * Rétablir le mode vidéo original et revenir à DOS * /
fg_setmode (old_mode);
           fg_reset ();
         }


Un problème avec une ou l'autre technique page flipping se pose si nous utilisons virtuelle

pages vidéo. Page flipping repose sur le fait que le changement de numéro de page visuelle se produit instantanément, ce qui est exactement ce qui se passe lorsque nous utilisons les pages vidéo physiques. Cependant, ce n'est pas le cas avec des pages virtuelles ou logiques, car Fastgraph doit copier le contenu des pages entières dans la mémoire vidéo. Bien que cela se produit très rapidement, il est pas instantanée, et ses effets sont immédiatement visibles sur l'animation.


Une animation Exemple: Le Fastgraph Fish Tank

Si vous avez installé les exemples de programmes lorsque vous avez installé Fastgraph, la

Exemples sous-répertoire comprendra un programme entièrement commenté appelé le réservoir de poissons qui illustre l'animation de cadre dynamique. Le réservoir de poissons est un excellent exemple de multi-objet animation non-destructive dans laquelle plusieurs types de poissons tropicaux nagent en arrière contre un récif corallien de fond. Comme une image vaut 1.024 mots, nous vous suggérons d'étudier le code source de réservoir de poissons pour certaines techniques utiles dans l'élaboration d'un programme d'animation complet. Le code source pour le programme de réservoir de poissons est en FISHTANK.C, FISHTANK.BAS, FISHTANK.FOR ou FISHTANK.PAS, selon ce que le soutien langue que vous avez installé avec Fastgraph.


Résumé des Techniques d'animation

Ce chapitre a présenté cinq techniques d'animation: animation simple,

animation XOR, animation d'images statiques, animation d'images dynamiques, et page flipping. Le tableau suivant résume leur comportement.

technique destructrice? sans scintillement?

simple, oui non
             XOR no no
             cadre statique non oui
             cadre dynamique non oui
             Page flipping non oui

animation simple et animation XOR sont des techniques élémentaires qui sont rarement utilisés une fois que vous maîtrisez l'animation de trame et la page flipping.

Comme indiqué au début de ce chapitre, les exemples simples présentés

ici servir de base pour la compréhension de la mécanique des techniques d'animation dont nous avons discuté. Dans les programmes du "monde réel", vous aurez généralement à afficher une image en utilisant la famille des routines à la place en utilisant des images rudimentaires fg_drwimage ou fg_drawmap tels que les rectangles dans nos exemples. Une règle utile est d'utiliser des fichiers pixel run PCX, GIF, ou pour les deux milieux et des objets en mouvement, puis utilisez fg_getimage ou fg_getmap pour récupérer les objets en mouvement comme des images bitmap pour l'affichage plus tard. Bien sûr, il est souhaitable de faire ce travail "dans les coulisses" sur les pages vidéo autres que la page visuelle. Ce

Chapitre 12: Techniques d'animation 285


est précisément la technique utilisée dans l'aquarium Fastgraph. Guide de l'utilisateur 286 Fastgraph



Chapitre 13


Effets spéciaux 288 Guide de l'utilisateur Fastgraph


aperçu

Ce chapitre traitera des routines Fastgraph qui aident à produire

effets visuels spéciaux. Ceux-ci incluent la possibilité de dissoudre le contenu de l'écran par petits incréments, faites défiler les zones de l'écran, changer l'origine physique de l'écran, et mettre en place un environnement d'écran divisé. Les exemples de programmes d'accompagnement illustrent comment utiliser ces routines pour produire des effets intéressants.


Dissoudre écran

dissolution de l'écran est le processus de remplacement du contenu de l'écran entier

en petits incréments aléatoires au lieu de tout à la fois. Fastgraph comprend deux routines, fg_fadeout et fg_fadein, à cette fin. La routine fg_fadeout remplace incrémentielle contenu de la page visuelle avec des pixels de la couleur actuelle, alors que fg_fadein remplace incrémentielle le contenu des pages visuelles avec le contenu des pages cachées (qui est, la page définie dans l'appel le plus récent à fg_sethpage). Les deux routines acceptent un argument entier qui définit le délai entre chaque remplacement progressif. Une valeur de zéro signifie que pour effectuer le remplacement le plus rapidement possible, alors que 1 est légèrement plus lent, 2 est plus lente encore, et ainsi de suite. Les fg_fadeout et fg_fadein routines ont aucun effet en mode vidéo texte et travaillent toujours avec des pages vidéo, même si un tampon virtuel est actif.

Exemple 13-1 montre comment utiliser fg_fadeout. Le programme, qui se déroule en tout

mode vidéo graphique, remplit d'abord l'écran avec un rectangle de couleur 2. Après avoir attendu pendant une séquence de touches, le programme remplace incrémentielle le contenu de l'écran avec des pixels de couleur 15 (l'indice de couleur courant lorsque fg_fadeout est appelé). Après une autre touche, le programme sort gracieusement.

Exemple 13-1.
#include <fastgraf.h>
                void main (void);
void main ()
                 {
                   int old_mode;
fg_initpm ();
                   fg_getmode old_mode = ();
                   fg_setmode (fg_automode ());
fg_setcolor (2);
                   fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                   fg_waitkey ();
fg_setcolor (15);
                   fg_fadeout (0);
                   fg_waitkey ();
fg_setmode (old_mode);
                   fg_reset ();
                }   
                                          Chapitre 13: Effets spéciaux 289


Exemple 13-2 montre comment utiliser fg_fadein dans tous les graphiques couleur 320x200

mode vidéo. Le programme remplit d'abord l'écran avec un rectangle de couleur 2, puis remplit Page vidéo 1 avec un rectangle de couleur 1. Après avoir attendu pendant une séquence de touches, le programme transfère incrémentielle le contenu de la page 1 à la page visuelle. Après l'appel à fg_fadein, à la fois la page 0 (la page visuelle) et la page 1 (page cachée) contiennent des rectangles de couleur 1 qui remplissent la page vidéo dans son intégralité. Enfin, le programme attend une autre touche avant de revenir à DOS.

Exemple 13-2.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  int new_mode, old_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,2);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                     sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
                  fg_allocate (1);
                  fg_sethpage (1);
fg_setcolor (2);
                  fg_rect (0,319,0,199);
                  fg_setpage (1);
                  fg_setcolor (1);
                  fg_rect (0,319,0,199);
                  fg_waitkey ();
fg_fadein (0);
                  fg_waitkey ();
fg_freepage (1);
                  fg_setmode (old_mode);
                  fg_reset ();
                }


Vous pouvez également produire des effets visuels attrayants en remplaçant le

contenu de l'écran d'une manière non aléatoire en utilisant les fg_restore ou fg_transfer routines. Par exemple, vous pouvez copier le contenu des pages cachées à la page visuelle à travers une série de zones rectangulaires concentriques, chacune légèrement plus grande que la précédente, jusqu'à ce que l'ensemble de l'écran est copié. Un autre effet intéressant est de commencer autour du périmètre de l'écran et procéder vers le Guide de l'écran 290 Fastgraph utilisateur


centre, produisant ainsi un effet de "serpent". Expérimenter avec de telles techniques peut révéler d'autres effets qui conviennent à votre application.


Défilement

Un autre effet utile défile, et Fastgraph fournit une routine qui

effectue le défilement vertical dans une région donnée de la page vidéo active. Les rouleaux de routine de fg_scroll une région définie dans l'espace de l'écran ou de l'espace de caractère. Il peut faire défiler vers le haut ou vers le bas et offre deux types de défilement: circulaire et à la fin-off. Dans le défilement circulaire, lignes qui défilent hors un bord de la zone définie apparaissent à son bord opposé. En bout de défilement, ces lignes vent simplement au-dessus ou au-dessous de la zone de défilement. Les schémas suivants illustrent les deux types de défilement.

fin-off défilement défilement circulaire
avant après avant après
CB
                 AA
AA
                 BB


Dans ces diagrammes, la zone délimitée par les lignes doubles est le défilement

région, tel que spécifié dans l'appel à fg_scroll. En outre, le sens de défilement est supposé être vers le bas (qui est, vers le bas de l'écran), et le nombre de lignes pour faire défiler est la hauteur de la zone désignée B. Le nombre de lignes pour faire défiler est souvent appelé l'incrément de défilement .

Pour l'exemple de fin de défilement, le défilement des transferts d'opération

région A la baisse de sorte qu'une partie de celui-ci est copié dans la zone B. La zone C (qui est la même taille que la zone B) en haut de la zone de défilement est rempli avec des pixels de l'indice de couleur courante (tels que définis dans l'appel le plus récent à fg_setcolor), et le contenu original de la zone B sont perdus. L'exemple de défilement circulaire copie également la région A vers le bas dans la zone B. originale Contrairement fin de défilement, cependant, le défilement circulaire préserve la zone B en le copiant sur le bord opposé de la zone de défilement.

La routine de fg_scroll prend six arguments. Les quatre premiers définissent la

défilement région dans le minimum de commande coordonnée x, maximum coordonnée x, y minimale coordonnée et maximale coordonnée y. Dans les modes graphiques vidéo, les coordonnées x sont étendues aux limites d'octets si nécessaire. Le cinquième argument est l'incrément de défilement. Il spécifie le nombre de lignes à faire défiler. Si elle est positive, le sens de défilement est vers le bas de l'écran; si elle est négative, la direction de défilement est vers le haut de l'écran. Le sixième et dernier argument spécifie le type de défilement. Si cette valeur est zéro, le défilement sera circulaire; si elle est une autre valeur, le défilement sera fin-off. Si le type de défilement est circulaire, Fastgraph utilisera la page cachée (tel que défini dans l'appel le plus récent à fg_sethpage) comme un espace de travail (plus précisément, la zone délimitée par la région extrêmes de défilement sur la page cachée sera utilisée). La routine de fg_scroll est désactivé quand un tampon virtuel est actif.

Chapitre 13: Effets spéciaux 291


Nous allons maintenant présenter trois exemples de programmes qui utilisent la routine fg_scroll.

Exemple 13-3 fonctionne dans un mode vidéo 320x200 graphique. Le programme affiche deux lignes de texte ( «une ligne» et «aligner deux») dans le coin supérieur gauche de l'écran sur un fond blanc. Il utilise ensuite fg_scroll pour déplacer la deuxième ligne vers le bas quatre rangées de pixels en utilisant un rouleau fin-off. Après avoir attendu pendant une séquence de touches, le programme fg_scroll utilise à nouveau pour déplacer le texte à sa position d'origine. Remarque surtout comment fg_setcolor est utilisé avant le premier appel à fg_scroll pour remplacer le "off" défiler les lignes avec des pixels de couleur 15, préservant ainsi le fond blanc.

Exemple 13-3.
#include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  int new_mode, old_mode;
fg_initpm ();
                  new_mode = fg_bestmode (320,200,1);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                     sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
fg_setcolor (15);
                  fg_rect (0,319,0,199);
                  fg_setcolor (10);
                  fg_text ( "une ligne", 8);
                  fg_locate (1,0);
                  fg_text ( "aligner deux", 8);
                  fg_waitkey ();
fg_setcolor (15);
                  fg_scroll (0,63,8,15,4,1);
                  fg_waitkey ();
                  fg_scroll (0,63,12,19, -4,1);
                  fg_waitkey ();
fg_setmode (old_mode);
                  fg_reset ();
                }


Exemple 13-4 est similaire à l'exemple 13-3, mais il court dans la colonne 80

mode texte de couleur (mode 3). En mode texte, nous ne pouvons pas faire défiler une demi-rangée de caractères comme dans l'exemple 13-3, de sorte que les rouleaux de programme d'une ligne minimale à la place.

Exemple 13-4. 

Guide de l'utilisateur 292 Fastgraph


#include <fastgraf.h>
                        void main (void);
void main ()
                         {
                           int old_mode;
fg_initpm ();
                           fg_getmode old_mode = ();
                           fg_setmode (3);
                           fg_cursor (0);
fg_setcolor (7);
                           fg_rect (0,79,0,24);
                           fg_setattr (10,7,0);
                           fg_text ( "une ligne", 8);
                           fg_locate (1,0);
                           fg_text ( "aligner deux", 8);
                           fg_waitkey ();
fg_setcolor (7);
                           fg_scroll (0,7,1,1,1,1);
                           fg_waitkey ();
                           fg_scroll (0,7,2,2, -1,1);
                           fg_waitkey ();
fg_setmode (old_mode);
                           fg_reset ();
                         }


Exemple 13-5, l'exemple de défilement finale, démontre une circulaire

faire défiler.Le programme fonctionne dans tous les modes graphiques vidéo 320x200 en couleurs; notez l'utilisation de la page vidéo 1 pour l'espace de travail requis lors de fg_scroll effectue un défilement circulaire. Le programme remplit d'abord l'écran avec un rectangle bleu clair (cyan dans CGA), affiche un rectangle blanc plus petit dans le centre de l'écran, puis utilise fg_move, fg_draw et fg_paint pour afficher une étoile verte lumière (magenta CGA) dans le rectangle blanc. Le programme exécute une boucle while pour faire défiler l'étoile vers le haut par incréments de quatre pixels. Parce que le défilement est circulaire, les lignes de l'étoile qui "Scroll off" le bord supérieur du rectangle blanc (dont la hauteur est la même que la zone de défilement) reparaître à son bord inférieur. L'utilisation de fg_waitfor dans la boucle ralentit simplement vers le bas du rouleau. Le défilement se poursuit jusqu'à ce qu'une touche est enfoncée.

Exemple 13-5.
#include <conio.h>
               #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
               void main (void);
void main ()
                {
                  int new_mode, old_mode; 
                                          Chapitre 13: Effets spéciaux 293


fg_initpm ();
                  new_mode = fg_bestmode (320,200,2);
                  if (new_mode <0 || new_mode == 12) {
                     printf ( "Ce programme nécessite une 320");
                     ( "le mode x 200 graphiques couleur \ n".) printf;
                     sortie (1);
                      }
                  fg_getmode old_mode = ();
                  fg_setmode (new_mode);
                  fg_allocate (1);
                  fg_sethpage (1);
fg_setcolor (9);
                  fg_rect (0,319,0,199);
                  fg_setcolor (15);
                  fg_rect (132,188,50,150);
fg_setcolor (10);
                  fg_move (160,67);
                  fg_draw (175,107);
                  fg_draw (140,82);
                  fg_draw (180,82);
                  fg_draw (145,107);
                  fg_draw (160,67);
                  fg_paint (160,77);
                  fg_paint (150,87);
                  fg_paint (160,87);
                  fg_paint (170,87);
                  fg_paint (155,97);
                  fg_paint (165,97);
tandis que (kbhit () == 0) {
                     fg_waitfor (1);
                     fg_scroll (136,184,50,150, -4,0);
                      }
                  fg_waitkey ();
fg_freepage (1);
                  fg_setmode (old_mode);
                  fg_reset ();
                }


Modification de l'origine de l'écran

Fastgraph comprend deux routines pour changer l'origine de l'écran.  Par

changer l'origine de l'écran, nous avons simplement entendons définir le (x, y) de coordonnées du coin supérieur gauche de la zone d'affichage. Les préformes de routine fg_pan cette fonction dans l'espace de l'écran, tandis que la routine fg_panw fait dans l'espace mondial. Ni les changements de routine les graphiques position du curseur. Parce que la fonction de fg_pan et fg_panw est de changer l'origine de l'écran, ces routines ne sont pas applicables aux tampons virtuels. Guide de l'utilisateur 294 Fastgraph


Chacun de ces sous-programmes comporte deux arguments qui spécifient x et y

les coordonnées de l'origine de l'écran. Pour fg_pan, les arguments sont des quantités entières. Pour fg_panw, ils flottent des quantités ponctuelles.

Dans le EGA, VGA, MCGA, modes XVGA et SVGA graphiques (modes 13 à 29),

vous pouvez définir l'origine de l'écran à tout (x, y) de coordonnées de position (qui est, à tout pixel). Dans d'autres modes les graphiques, certaines restrictions existent, imposées par le matériel vidéo spécifique. Ces contraintes limitent les positions de coordonnées qui peuvent être utilisés comme l'origine de l'écran. Fastgraph compense ces restrictions en réduisant spécifiées x et les coordonnées y des valeurs qui sont acceptables pour le mode vidéo en cours, comme indiqué dans le tableau suivant.

x sera réduite y sera réduite
        mode vidéo à un multiple de: à un multiple de:
4 à 5 août 2
             6 16 2
             9 4 4
            11 8 4
            12 4 2 ou 3

Dans les modes 4 et 5, par exemple, les coordonnées x seront réduits à un multiple de 8 pixels, et la coordonnée Y sera réduite à un multiple de 2 pixels. Dans le mode basse résolution Hercules (mode 12), la coordonnée y réduction dépend de si oui ou non la ligne de pixel spécifiée est scan doublé.

Exemple 13-6 montre un effet utile qui peut être réalisé avec ou fg_pan

fg_panw. Ce programme fg_automode utilise pour sélectionner un mode vidéo, puis dessine un rectangle blanc non rempli. Les faces supérieure et inférieure du rectangle sont intentionnellement dessinés juste plus petit que la taille physique de l'écran. Après avoir attendu pendant une séquence de touches, le programme utilise une boucle pour rendre le trémousser rectangle de haut en bas. Le déplace rectangle parce fg_pan est appelé dans la boucle pour changer l'origine de l'écran entre le coin supérieur gauche du rectangle et l'origine d'origine. Notez également l'utilisation de fg_waitfor pour provoquer de légers retards après chaque appel à fg_pan. Si on n'a pas utilisé fg_waitfor, le changement de l'origine se produirait si rapidement que nous ne remarquerait pas l'effet. Enfin, le programme restaure le mode vidéo original et attributs de l'écran avant de revenir à DOS.

Exemple 13-6.
#include <fastgraf.h>
                 #include <stdio.h>
                 #include <stdlib.h>
                void main (void);
#define DELAY 2
                JUMP #define 4
void main ()
                 {
                    int i;
                   int old_mode;
fg_initpm (); 
                                          Chapitre 13: Effets spéciaux 295


fg_getmode old_mode = ();
                   fg_setmode (fg_automode ());
fg_setcolor (15);
                   fg_move (0, JUMP);
                   fg_draw (fg_getmaxx (), JUMP);
                   fg_draw (fg_getmaxx (), fg_getmaxy () - JUMP);
                   fg_draw (0, fg_getmaxy () - JUMP);
                   fg_draw (0, JUMP);
                   fg_waitkey ();
for (i = 0; i <6; i ++) {
                      fg_pan (0, JUMP);
                      fg_waitfor (DELAY);
                      fg_pan (0,0);
                      fg_waitfor (DELAY);
                       }
fg_setmode (old_mode);
                   fg_reset ();
                 }


La vraie puissance de fg_pan devient clair quand il est utilisé avec fg_resize à

effectuer un panoramique lisse. Rappel du chapitre 8 que fg_resize modifie la page vidéo dimensions en modes EGA et VGA graphiques natifs (modes 13 à 18), les modes étendus graphiques VGA (20 à 23), et les modes les SVGA graphiques (24 à 29). Nous allons maintenant présenter un exemple qui montre comment utiliser ces deux routines pour effectuer un panoramique en mode basse résolution EGA graphiques (mode 13). La méthode qu'il utilise également fonctionnerait dans un mode qui prend en charge la page de redimensionnement vidéo.

Exemple 13-7 commence par établir le mode vidéo, puis immédiatement

appels fg_resize pour augmenter la taille de la page vidéo de 640x400 pixels. Ainsi, la page vidéo est maintenant quatre fois sa taille originale. Suite à cela, le programme remplit la page (la page entière, et pas seulement ce qui est affiché) avec un rectangle vert clair avec une bordure blanche autour de lui. Il affiche ensuite le message "Appuyez sur les touches fléchées pour vous déplacer" dans le centre de la page 640x400.

La partie principale du programme est une boucle qui accepte les frappes et les appels

fg_pan pour effectuer le panoramique d'un pixel à la fois. Lorsque vous appuyez sur une des quatre touches fléchées, le programme ajuste les coordonnées x et y pour l'origine de l'écran comme indiqué. Par exemple, en appuyant sur la flèche haut fait défiler l'écran vers le haut un pixel. Lorsque nous arrivons au bord de la page vidéo, le programme empêche la poursuite de défilement dans cette direction. Ce processus se poursuit jusqu'à ce que vous appuyez sur la touche Echap, au moment où le programme restaure les attributs d'origine en mode vidéo et écran avant de quitter.

Exemple 13-7.
#include <fastgraf.h>
                void main (void);
void main ()
                 {
                   unsigned clé de char, aux;
                   int old_mode; 

Guide de l'utilisateur 296 Fastgraph


int x, y;
fg_initpm ();
                   fg_getmode old_mode = ();
                   fg_setmode (13);
                   fg_resize (640,400);
fg_setcolor (2);
                   fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
                   fg_setcolor (15);
                   fg_box (0, fg_getmaxx (), 0, fg_getmaxy ());
                   fg_justify (0,0);
                   fg_move (320,200);
                   fg_print ( "Appuyez sur les touches fléchées pour vous déplacer.", 24);
x = 0;
                   y = 0;
faire {
                      fg_getkey (touche &, & aux);
                      if (aux == 72 && y <200)
                         y ++;
                      else if (aux == 75 && x <320)
                          x ++;
                      else if (aux == 77 && x> 0)
                         X--;
                      else if (aux == 80 && y> 0)
                          Y-;
                      fg_pan (x, y);
                   } While (key = 27!);
fg_setmode (old_mode);
                   fg_reset ();
                 }


Panning Avec Tampons Virtuels

La routine de fg_pan ne convient pas pour le panoramique d'une grande image à travers un

petite fenêtre, car elle affecte l'ensemble de l'écran. Cependant, vous pouvez obtenir ce type de panoramique en stockant la grande image sur une page vidéo hors de l'écran ou dans un tampon virtuel, puis copier les parties appropriées à la fenêtre fixe sur la page visuelle. Exemple 13-8 illustre cette technique en utilisant un tampon virtuel.

Exemple 13-8.
#include <fastgraf.h>
                void main (void);
#ifdef FG32
                char buffer [64000];
                 #autre
                carboniser énorme tampon [64000];
                #fin si   
                                          Chapitre 13: Effets spéciaux 297


void main ()
                 {
                   unsigned clé de char, aux;
                   poignée int;
                   int old_mode;
                   int x, y;
fg_initpm ();
                   fg_getmode old_mode = ();
                   fg_setmode (19);
fg_vbinit ();
                   handle = fg_vbdefine (tampon, 320200);
                   fg_vbopen (poignée);
                   fg_loadpcx ( "CORAL.PCX", 0);
                   fg_vbclose ();
fg_setcolor (2);
                   fg_fillpage ();
                   fg_setcolor (15);
                   fg_box (111,208,69,130);
                   fg_locate (3,8);
                   fg_text ( "Appuyez sur les touches fléchées pour vous déplacer.", 24);
x = 112;
                   y = 129;
                   fg_vbpaste (x, x + 95, y 59, y, 112,129);
faire {
                      fg_getkey (touche &, & aux);
                      if (aux == 72 && y <199)
                         y ++;
                      else if (aux == 75 && x <223)
                          x ++;
                      else if (aux == 77 && x> 0)
                         X--;
                      else if (aux == 80 && y> 59)
                          Y-;
                      fg_vbpaste (x, x + 95, y 59, y, 112,129);
                   } While (key = 27!);
fg_setmode (old_mode);
                   fg_reset ();
                 }


Exemple 13-8 charge notre image familière de CORAL.PCX dans un 320x200 virtuel

tampon. Il définit ensuite une zone de 96x60 au milieu de la page visuelle qui servira d'une fenêtre dans l'image CORAL.PCX plus large (cette région est délimitée horizontalement par x = 112 et x = 207 et verticalement par y = 70 et y = 129). Le premier appel à fg_vbpaste copies de la partie centrale 96x60 du buffer virtuel à la fenêtre de la page visuelle. La boucle de panning est similaire à celle de l'exemple 13-7, sauf que fg_vbpaste utilise pour mettre à jour le contenu de la fenêtre. En appuyant sur les incréments de touches fléchées ou décrémente les coordonnées définissant la région de source dans le Guide de l'utilisateur 298 Fastgraph


la mémoire virtuelle. En outre, notons la façon dont nous avons ajusté l'if pour empêcher fg_vbpaste d'accéder à des pixels en dehors de la mémoire virtuelle.


Écran divisé

Fastgraph fournit un support écran partagé pour EGA, VGA, MCGA et XVGA

modes graphiques (modes 13 à 23) pour les applications en cours d'exécution sur les systèmes VGA ou SVGA. Quand un écran partagé est activé, la partie supérieure de l'écran (lignes 0 à n-1, où n est la rangée de pixels à laquelle l'écran partagé prend effet) contiendra un sous-ensemble de la page vidéo visuelle. La partie inférieure (à partir de la ligne n) contiendra la première fg_getmaxy () - n + 1 lignes de la page vidéo 0. Par exemple, supposons que nous utilisons un mode graphique de 200 lignes et nous permettre à un écran partagé à la ligne 180. Si la page 1 est la page vidéo visuelle, les 180 premières lignes de l'écran seront affichées à partir des lignes 0 à 179 de la page 1, et les 20 dernières lignes seront affichées à partir des lignes 0 à 19 de la page 0. Un environnement de l'écran partagé est utile pour maintenir une image statique, comme une boîte de tableau de bord ou de l'état, au bas de l'écran pendant le défilement de la partie supérieure.

Exemple 13-9 montre une opération typique de l'écran partagé en 320x200

XVGA mode graphique (mode 20). Dans cet exemple, nous supposerons que nous voulons avoir une boîte d'état occupant les 20 dernières lignes (lignes 180 à 199) de l'écran, tandis que les 180 rangées supérieures (0 à 179) seront défiler verticalement. Le programme commence par le réglage du mode vidéo, puis en appelant fg_measure pour calculer une valeur de retard dépendant processor- pour ralentir le défilement (cette technique est expliquée plus en détail dans le chapitre 16).

Dans le mode 20, la mémoire vidéo est structuré en quatre 320x200 pages physiques.

Page 1 est pas visible lorsque nous tirons la boîte bleue avec la bordure blanche, donc nous ne voyons pas jusqu'à ce que l'appel fg_setvpage faire page 1, page visuelle. Bien sûr, cela rend aussi la page 0 invisible, donc nous ne voyons pas la boîte creuse rouge de 20 pixels de haut quand nous dessinons à la page 0.

Une fois que nous avons établi ce que nous avons besoin dans les pages 0 et 1, nous activons le

écran partagé en appelant fg_split. Le seul paramètre passé à fg_split est la ligne de l'écran à laquelle l'écran partagé prend effet, ou en d'autres termes, le nombre de lignes dans la partie supérieure de l'écran. Dans l'exemple 13-9, nous fg_split (180) appelle, de sorte que les 180 premières lignes de la page 1 apparaissent en haut de l'écran, et les 20 premières lignes de la page 0 va apparaître au bas.

Maintenant, nous sommes prêts à faire défiler la partie supérieure de l'écran (qui est maintenant la page

1).fg_pan routine de Fastgraph convient à cet effet. Nous réalisons le défilement vers le haut par incrémentation de la fg_pan coordonnée y dans une boucle. Nous atteignons le défilement vers le bas par décrémenter la coordonnée y. Nous devons appeler fg_stall (ou utiliser une autre méthode similaire) pour forcer un bref délai entre les itérations. Si nous ne faisons pas cela, la pleine défilement 20 rangée apparaît presque instantanément, perdant ainsi l'effet de défilement. Notez que nous ne pouvions pas utiliser fg_pan pour faire défiler la partie supérieure de l'écran de cette manière sans mettre en place un environnement d'écran divisé. En effet, par défaut, fg_pan applique à l'ensemble de l'écran. Utilisation de l'écran partagé nous fournit deux pages vidéo indépendantes, et quand la page 1 est la page de vidéo active, fg_pan ne touche pas la page 0.

Exemple 13-9.
#include <fastgraf.h>
  void main (void); 
                                          Chapitre 13: Effets spéciaux 299


void main ()
   {
     int retard, y;
/ * Initialisation de l'environnement vidéo * /
fg_initpm ();
     fg_setmode (20);
/ * Définir un retard de panoramique processeur dépendant * /
delay = fg_measure () / 16;
/ * Dessiner une boîte bleue avec une bordure blanche à la page 1 * /
fg_setpage (1);
     fg_setcolor (9);
     fg_fillpage ();
     fg_setcolor (15);
     fg_box (0,319,0,199);
     fg_move (160,100);
     fg_justify (0,0);
     fg_print ( "Ceci est la page 1", 14);
/ * Affiche ce que nous venons dessiné à la page 1 * /
fg_setvpage (1);
     fg_waitkey ();
/ * Dessiner une boîte creuse rouge en haut de la page 0 (maintenant invisible) * /
fg_setpage (0);
     fg_setcolor (12);
     fg_box (0,319,0,19);
     fg_setcolor (15);
     fg_move (160,10);
     fg_print ( "Split Screen", 12);
/ * Activer l'environnement d'écran divisé, ce qui rend le premier * /
     / * 20 lignes de la page 0 apparaissent en bas de l'écran, * /
     / * Et faire les 180 premières lignes de la page 1 apparaît en haut * /
fg_split (180);
     fg_waitkey ();
/ * Recadrer vers le haut par incréments d'une ligne, l'affichage du reste de * /
     /* Page 1 */
fg_setpage (1);
     pour (y = 0; y <= 20; y ++)
      {
        fg_pan (0, y);
        fg_stall (retard);
      }
     fg_waitkey (); 

Guide de l'utilisateur 300 Fastgraph


 / * Panoramique vers le bas par incréments d'une ligne à la position initiale * /
 pour (y = 20; y> = 0; Y-)
      {
         fg_pan (0, y);
         fg_stall (retard);
      }
      fg_waitkey ();
 / * Restauration 80x25 mode texte et la sortie * /
 fg_setmode (3);
      fg_reset ();
   }


 Pour passer d'un environnement d'écran divisé retour à une «page unique»

environnement, appelez fg_split avec un paramètre de ligne égale à la résolution verticale de l'écran pour le mode vidéo actuel.


Résumé des effets spéciaux Routines

 Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

 FG_FADEIN remplace incrémentielle la page contenu visuel avec le caché

contenu de la page. Cette routine n'a pas d'effet dans les modes vidéo texte et ne sont pas applicables aux tampons virtuels.

 FG_FADEOUT remplace incrémentielle contenu de la page visuelle avec des pixels de

la couleur actuelle. Cette routine n'a pas d'effet dans les modes vidéo texte et ne sont pas applicables aux tampons virtuels.

 FG_PAN change l'origine de l'écran (le coin supérieur gauche de l'écran) pour

coordonne l'espace de l'écran spécifié. Cette routine n'a pas d'effet dans les modes vidéo texte et ne sont pas applicables aux tampons virtuels.

 FG_PANW est la version de la routine de fg_pan espace mondial.
 FG_RESIZE modifie les dimensions d'une page vidéo EGA et VGA graphiques

modes. Cette routine est désactivé quand un tampon virtuel est actif.

 FG_SCROLL fait défiler verticalement une région de la page vidéo active.  le

le défilement peut être fait soit vers le haut ou vers le bas, en utilisant soit une fin-off ou de la méthode circulaire. défilement circulaire utilise une partie de la page cachée comme un espace de travail temporaire. Cette routine ne fonctionne pas quand un tampon virtuel est actif.

 FG_SPLIT active ou désactive un environnement d'écran partagé en EGA, VGA,

MCGA et XVGA modes graphiques.



Chapitre 14


Guide de support de périphériques d'entrée 302 Fastgraph utilisateur


aperçu

 La sélection des périphériques d'entrée d'application est une partie importante de

la conception d'un programme pour le PC IBM et PS / 2 famille de systèmes. Le clavier et la souris sont les plus populaires, et en fait de plus en plus d'applications, en particulier ceux qui utilisent une interface graphique, réellement besoin d'une souris pour utiliser le produit. Un autre dispositif d'entrée, principalement utilisé dans les logiciels de divertissement, est le joystick. Bien que pas aussi populaire que la souris, joysticks peuvent néanmoins simplifier l'utilisation de certaines applications. Fastgraph fournit un support pour ces trois types de périphériques d'entrée, et ce chapitre discutera en détail.


Keyboard support

 Le support du clavier de Fastgraph comprend des routines pour lire les frappes, chèque

l'état de certaines touches, et réglez l'état de ces touches. En outre, Fastgraph fournit un gestionnaire de clavier de bas niveau qui remplace le gestionnaire de clavier du BIOS pour augmenter la réactivité du clavier. Ces routines sont indépendantes des autres parties du Fastgraph et ne nécessitent donc pas que vous appelez fg_setmode. Toutes les routines liées au clavier fonctionnent en mode texte et des graphiques vidéo.

 Le PC IBM et claviers PS / 2 produire deux types de codes de caractères -

codes standards et codes étendus (codes étendus sont parfois appelés codes auxiliaires). Les codes standard correspondent aux 128 caractères dans le jeu de caractères ASCII. En général, la pression des touches sur la partie principale du clavier ou du pavé numérique avec NumLock allumé, va générer un code standard. Les 128 codes étendus sont spécifiques au PC IBM et claviers PS / 2. Quelques frappes communes qui produisent des codes étendus sont des touches du pavé numérique avec NumLock éteint, les touches de fonction, ou en appuyant sur Alt avec une autre touche. Les tableaux suivants présentent les codes de clavier standard et étendu.

 Tableau des codes de clavier standard
 code clé code clé code clé code clé
 (None) 0 espace 32 @ 64 `96
          Ctrl + A 1!  33 A 65 a 97
          Ctrl + B 2 "34 B 66 b 98
          Ctrl + C 3 # 35 C 67 c 99
          Ctrl + D 4 $ 36 D 68 d 100
          Ctrl + E 5% 37 E 69 e 101
          Ctrl + F 6 et 38 F 70 f 102
          Ctrl + G 7 '39 G 71 g 103
          Ctrl + H 8 (40 H 72 h 104
          Ctrl + I 9) 41 I 73 i 105
          Ctrl + J 10 * 42 J 74 j 106
          Ctrl + K 11 + 43 K 75 k 107
          Ctrl + L 12, 44 L 76 l 108
          Ctrl + M 13-45 M 77 m 109
          Ctrl + N 14.  46 N 78 n 110
          Ctrl + O 15/47 O 79 o 111
          Ctrl + P 16 0 48 P 80 p 112
                                      Chapitre 14: Entrée Device Support 303


 Ctrl + Q 17 1 49 Q 81 q 113
          Ctrl + R 18 2 50 R 82 r 114
          19 3 51 S 83 de Ctrl + s 115
          Ctrl + T 20 4 52 T 84 t 116
          Ctrl + U 21 5 53 U 85 u 117
          Ctrl + V 22 6 54 V 86 v 118
          Ctrl + W 23 7 55 W 87 w 119
          Ctrl + X 24 8 56 X 88 x 120
          Ctrl + Y 25 9 57 Y 89 y 121
          Ctrl + Z 26: 58 Z 90 z 122
          Ctrl + [27;  59 [91 {123
          Ctrl + \ 28 <60 \ 92 |  124
          Ctrl +] 29 = 61] 93} 125
          Ctrl + ^ 30> 62 ^ 94 ~ 126
          Ctrl + - 31?  63 _ 95 Ctrl + BS 127


 Tableau des codes de clavier étendu
 clé de code
 3 Ctrl + @
             15 Maj + Tab (onglet arrière)
             16-25 Alt + Q pour Alt + P (rangée supérieure de lettres)
             30-38 Alt + A pour Alt + L (rangée du milieu de lettres)
             44-50 Alt + Z à Alt + M (rangée du bas de lettres)
             59-68 F1 à F10
             71 Accueil
             72 flèche vers le haut
             73 PgUp
             75 flèche gauche
             77 flèche droite
             79 Fin
             80 flèche vers le bas
             81 PgDn
             82 Ins
             83 Del
             84-93 Maj + F1 à Maj + F10
             94-103 Ctrl + F1 pour Ctrl + F10
             104-113 Alt + F1 à Alt + F10
             114 Ctrl + PrtSc
             115 Ctrl + flèche gauche
             116 Ctrl + flèche droite
             117 Ctrl + Fin
             118 Ctrl + PgDn
             119 Ctrl + Accueil
             120-131 Alt + 1 à Alt + = (rangée supérieure de touches)
             132 Ctrl + PgUp


En outre, quatre touches génèrent les mêmes codes standard que les autres combinaisons de touches de commande. Ces clés sont:

 clé même code
 Backspace Ctrl + H 8

Guide de l'utilisateur 304 Fastgraph


 Tab Ctrl + I 9
                        Entrez Ctrl + M 13
                        Évadez Ctrl + [27
 Les touches CapsLock, NumLock et ScrollLock ne génèrent pas une norme ou

Code étendu lorsqu'il est pressé. Au lieu de cela, ils basculer entre off et les Etats.


lecture Keystrokes

 Lorsque vous appuyez sur une combinaison de touches ou la touche, le code standard ou étendu

représentant cette séquence de touches est stockée dans la mémoire tampon de clavier du BIOS ROM. Ce tampon peut contenir jusqu'à 16 frappes et fournit ainsi une capacité de type avance. Fastgraph comprend trois routines pour lire une information de frappe de la mémoire tampon de clavier. La routine de fg_getkey lit l'élément suivant dans la mémoire tampon de clavier si l'on est disponible (qui est, si une touche a été pressée). Si la mémoire tampon du clavier est vide (ce qui signifie aucune touche n'a été pressée), fg_getkey attend une touche, puis fournit des informations à ce sujet. Une autre routine, fg_intkey, lit la frappe suivante de la mémoire tampon du clavier si l'on est disponible. Si la mémoire tampon du clavier est vide, fg_intkey retourne et rapports immédiatement cette condition. La routine de fg_intkey est utile lorsqu'un programme doit continuer d'exécuter une tâche jusqu'à ce qu'une touche est enfoncée. Nous avons déjà vu la troisième routine, fg_waitkey, qui vide le tampon du clavier, puis attend une autre touche. Contrairement à fg_getkey et fg_intkey, fg_waitkey ne renvoie aucune information de frappe. Il est très utile dans «appuyer sur une touche pour continuer" situations.

 Les deux fg_getkey et fg_intkey nécessitent deux arguments d'un octet adoptées par

référence. Si la frappe est représentée par une norme de code de clavier, fg_getkey et fg_intkey retourner son code dans le premier argument et définir le second argument à zéro. De même, si la frappe génère un code étendu, les routines renvoient son code dans le second argument et mettre le premier argument à zéro. Si fg_intkey détecte une mémoire tampon du clavier vide, il définit les deux arguments à zéro.

 Exemple 14-1 est un programme simple qui utilise fg_getkey.  Il sollicite

frappes et puis affiche les deux valeurs renvoyées par fg_getkey dont l'un sera toujours zéro. La variable clé reçoit le code standard de la clé, tandis aux reçoit son code étendu. A noter que fg_initpm et fg_getkey sont les seules routines Fastgraph du programme; cela peut être fait parce que les routines de support du clavier sont logiquement indépendants du reste de Fastgraph. Le programme retourne au DOS lorsque vous appuyez sur la touche Echap.

 Exemple 14-1.
 #include <fastgraf.h>
               #include <stdio.h>
               void main (void);
 #define ESC 27
 void main ()
               {
                  unsigned clé de char, aux;
 fg_initpm (); 
                                      Chapitre 14: Entrée Device Support 305


 faire {
                     fg_getkey (touche &, & aux);
                     printf ( "key =% 3d aux =% 3d \ n", clé, aux);
                     }
                  while (key = ESC!);
               }


 Exemple 14-2 lit les frappes à l'aide de fg_intkey à intervalles d'une demi-seconde

(18.2 fg_waitfor unités égales d'une seconde). Comme dans l'exemple précédent, le programme affiche les codes standard et étendu pour chaque frappe. Cependant, l'exemple 14-2 continuellement exécuter la boucle while même si aucune des séquences de touches sont disponibles, auquel cas les valeurs clés et aux deux seront zéro. Le programme retourne au DOS lorsque vous appuyez sur la touche Echap.

 Exemple 14-2.
 #include <fastgraf.h>
               #include <stdio.h>
               void main (void);
 #define ESC 27
 void main ()
               {
                  unsigned clé de char, aux;
 fg_initpm ();
                  faire {
                     fg_waitfor (9);
                     fg_intkey (touche &, & aux);
                    printf ( "key =% 3d aux =% 3d \ n", clé, aux);
                     }
                 while (key = ESC!);
               }


Lorsque vous utilisez fg_intkey dans une boucle "serré" qui ne fait guère d'autre, vous

devrait forcer un petit retard dans la boucle en appelant fg_waitfor comme dans l'exemple 14-2. Typiquement, un retard d'une ou deux impulsions d'horloge est suffisant. Sans ce délai, le BIOS peut ne pas être capable de gérer toutes les activités de clavier, et donc des frappes peut ne pas être disponible pour votre programme.


Test et réglage États clés

Comme mentionné précédemment, les CapsLock, NumLock, et les clés ScrollLock ne le font pas

générer un code standard ou étendu lorsqu'il est pressé, mais au lieu de basculer entre off et les Etats. Fastgraph comprend des routines pour vérifier l'état de ces touches, ainsi que la mise en l'état des touches CapsLock et NumLock.

Les routines Fastgraph fg_capslock, fg_numlock et fg_scrlock

respectivement lire l'état des touches ScrollLock CapsLock, NumLock, et. Chaque routine n'a pas d'arguments et renvoie l'état clé comme valeur de la fonction. Une valeur de retour de 0 signifie que la clé associée est à l'état bloqué, tandis que le Guide de 1 306 Fastgraph utilisateur


indique que la clé est dans l'état. Si le clavier ne dispose pas d'une clé ScrollLock, fg_scrlock considère la clé off et renvoie une valeur de zéro.

Exemple 14-3 est un programme simple qui utilise fg_capslock, fg_numlock, et

fg_scrlock d'imprimer des messages décrivant l'état actuel de ces trois touches.

Exemple 14-3.
#include <fastgraf.h>
                    #include <stdio.h>
                   void main (void);
void main ()
                    {
                      fg_initpm ();
                      if (fg_capslock ())
                         printf ( "CapsLock est sur \ n.");
                       autre
                         printf ( "CapsLock est désactivé. \ n");
if (fg_numlock ())
                         printf ( "Verr Num est sur \ n.");
                       autre
                         printf ( "Verr Num est désactivé. \ n");
if (fg_scrlock ())
                         printf ( "ScrollLock est sur \ n.");
                       autre
                         printf ( "ScrollLock est désactivé. \ n");
                    }


Vous pouvez également définir l'état des CapsLock et NumLock clés au sein d'un

programme.Fastgraph comprend deux routines, fg_setcaps et fg_setnum, à cette fin. Chaque routine exige un argument entier qui spécifie le nouvel état clé. Si la valeur de l'argument est 0, la clé sera désactivée; si la valeur est 1, la touche est activée. Exemple 14-4 utilise fg_setcaps et fg_setnum pour désactiver CapsLock et Verr Num.

Exemple 14-4.
#include <fastgraf.h>
                           void main (void);
void main ()
                            {
                              fg_initpm ();
                              fg_setcaps (0);
                              fg_setnum (0);
                            }


Sur la plupart des claviers, en changeant les Etats clés avec fg_setcaps ou fg_setnum aussi

va changer la lumière de l'état du clavier pour refléter le nouvel état clé. Cependant, certains claviers plus âgés, en particulier lorsqu'il est utilisé sur PC, PC / XT, ou Tandy 1000

Chapitre 14: Entrée Device Support 307


systèmes, ne mettent pas à jour la lumière de l'Etat. Cela rend la lumière de l'Etat incompatible avec le véritable état clé.


Low-Level Keyboard Handler

Fastgraph comprend un gestionnaire de clavier de bas niveau qui remplace le BIOS

gestionnaire de clavier. Les interceptions de gestionnaire de remplacement frappes avant le BIOS et élimine ainsi le signal sonore gênant qui sonne lors du remplissage de la mémoire tampon du clavier du BIOS. Le gestionnaire de clavier de Fastgraph est particulièrement bien adapté pour le développement de jeux, car elle augmente la réactivité du clavier dans les jeux d'action à grande vitesse. Toutefois, lorsque le gestionnaire de clavier de bas niveau est activé, il est impossible d'utiliser fg_getkey, fg_intkey, fg_waitkey, ou des fonctions de tiers qui utilisent BIOS ou services DOS pour l'activité du clavier. Pour cette raison, un programme qui permet au gestionnaire de clavier de bas niveau doit le désactiver avant de quitter pour DOS.

Le gestionnaire de clavier de bas niveau peut être activé et désactivé à tout moment.

La routine de fg_kbinit est prévu à cet effet. Pour permettre à faible gestionnaire de clavier de niveau Fastgraph, passez la valeur 1 à fg_kbinit. Pour désactiver le gestionnaire de Fastgraph et réactiver le gestionnaire de clavier du BIOS, passer la valeur zéro. Aucun dommage est causé si vous essayez d'activer le gestionnaire de clavier Fastgraph quand il est déjà actif, ou si vous essayez de le désactiver lorsque le gestionnaire du BIOS est actif.

Lorsque le gestionnaire de clavier de bas niveau est activé, vous pouvez utiliser fg_kbtest à

vérifier si les touches sont actuellement enfoncée ou relâchée. Ce sous-programme fournit le seul mécanisme pour accéder au clavier lorsque le gestionnaire de niveau bas est activé. Il précise les clés à travers des codes de balayage. Si la touche correspondante est pressée, fg_kbtest renvoie 1. Si elle est libérée, la routine renvoie zéro. La routine de fg_kbtest peut tester si une touche est enfoncée si vous passez la valeur 0 à la place d'un code d'analyse spécifique. Le tableau suivant répertorie les codes de balayage correspondant aux touches d'un clavier de PC standard.

Table de codes de balayage
scan scan scan scan
         code clé code clé code clé code clé
Esc 1 I 23 X 45 F9 67
         1 2 O 24 C 46 F10 68
         2 3 P 25 V 47 NumLock 69
         3 4 [26 B 48 ScrLock 70
         4 5] 27 N 49 71 Accueil
         5 6 Entrez 28 M 50 Up flèche 72
         6 7 Ctrl 29, 51 PgUp 73
         7 8 A 30. 52 KP- 74
         8 9 S 31/53 L flèche 75
         9 10 D 32 R shift 54 ​​KP5 76
         0 11 F 33 R 55 KP * flèche 77
         - 12 G 34 Alt 56 KP + 78
         = H 13 35 Espace 57 79 Fin
         BS 14 J 36 CapsLock 58 Dn flèche 80
         Tab 15 K 37 F1 59 PgDn 81
         Q 16 L 38 F2 60 Ins 82
         W 17; 39 F3 61 Del 83
         E 18 '40 F4 62 (non utilisé) 84   

Guide de l'utilisateur 308 Fastgraph


R 19 `41 F5 63 (non utilisé) 85
         T 20 L décalage 42 F6 64 (non utilisé) 86
         Y 21 \ 43 F7 65 F11 87
         U 22 Z 44 F8 66 F12 88


Il y a des codes en fait plus d'analyse définis pour les claviers de PC que ceux énumérés

dans ce tableau. Ces codes de balayage sont générés quand une touche est pressée comme une combinaison d'une ou plusieurs touches, par exemple lorsque les touches Maj et slash sont pressées ensemble pour produire un point d'interrogation (?) Caractère. faible gestionnaire de clavier au niveau de Fastgraph est conçu pour signaler la compression ou la libération de touches elles-mêmes, par opposition à la communication des caractères réels ainsi produits. Il est donc impossible pour le gestionnaire de clavier pour signaler le code de balayage pour un caractère multi-clé. Si nécessaire, ces caractères peuvent être identifiés par les codes de balayage généré pour chaque clé dans la séquence. Par exemple, un point d'interrogation devrait être déclarée comme une barre oblique (code de balayage 53) généré en appuyant sur le décalage à gauche (42) ou décalage à droite (54) touches.

Exemple 14-5 illustre l'utilisation du clavier de bas niveau de Fastgraph

gestionnaire. Il fg_kbinit utilise d'abord pour permettre le gestionnaire de clavier Fastgraph et affiche un message indiquant cela. Puis, à environ une seconde d'intervalle, le programme appelle fg_kbtest pour vérifier lequel des quatre touches fléchées sont pressées et affiche un message approprié. En appuyant sur Echap restaure le gestionnaire de clavier du BIOS et quitte à DOS.

Exemple 14-5.
#include <fastgraf.h>
               #include <stdio.h>
              void main (void);
#define ESC 1
              #define GAUCHE 75
              #define DROIT 77
              #define UP 72
              #define BAS 80
void main ()
               {
                 fg_initpm ();
                 fg_kbinit (1);
                 printf ( "Keyboard gestionnaire activé. \ n");
faire {
                    printf ( "touches enfoncées:");
                    if (fg_kbtest (GAUCHE)) printf ( "gauche");
                    if (fg_kbtest (DROITE)) printf ( «droit»);
                    if (fg_kbtest (UP)) printf ( "Up");
                    if (fg_kbtest (DOWN)) printf ( "Down");
                     printf ( "\ n");
                    fg_waitfor (18);
                 } While (fg_kbtest (ESC) == 0);
fg_kbinit (0);
                 printf ( "Keyboard gestionnaire désactivé. \ n");
              }   
                                     Chapitre 14: Entrée Device Support 309


Fastgraph comprend deux autres routines pour le gestionnaire de clavier de bas niveau.

La fonction fg_kblast renvoie le code de balayage pour le plus récent keypress traitées par le gestionnaire de clavier de bas niveau. S'il n'y a pas eu de touches depuis l'appel fg_kbinit, la valeur de retour sera zéro. La routine de fg_kbreset réinitialise l'état du gestionnaire de clavier de bas niveau de Fastgraph à ce qu'elle était après avoir été initialisé avec fg_kbinit (1). Ceci a pour effet de "rinçage" le gestionnaire de clavier. Aucune de ces deux fonctions a des arguments.


Mouse support

La souris est un périphérique d'entrée et de pointage très populaire, en particulier dans

graphiquement des programmes orientés. Fastgraph contient plusieurs routines pour soutenir les souris. Ces routines effectuent des tâches telles que l'initialisation de la souris, le contrôle et la définition du curseur de la souris, et les rapports d'informations sur la position de la souris et de l'état du bouton.

Le logiciel sous-jacent qui contrôle la souris est appelée la souris

chauffeur.Les routines de support de la souris de Fastgraph fournissent une interface de haut niveau pour ce pilote. La souris Microsoft et son pilote de souris d'accompagnement sont devenus un standard de l'industrie, et d'autres fabricants de souris ont également fait leurs pilotes de souris compatible Microsoft. Pour cette raison, les routines de support de la souris Fastgraph supposent que vous utilisez un Microsoft ou le pilote de la souris compatible.

Malheureusement, tous les pilotes non de la souris sont créés égaux. Autrement dit, certains

les pilotes ne sont pas compatibles Microsoft, même si elles peuvent être annoncés en tant que telle. Dans certains cas, ces incompatibilités sont plutôt trivial, mais d'autres sont importants. Par exemple, les premières versions de certains pilotes tiers de souris avaient des problèmes réels dans les modes graphiques EGA. Le pilote de la souris Microsoft, le pilote souris Logitech (version 3.2 ou supérieure), et le pilote de la souris DFI (version 3.00 ou plus) sont connus pour bien travailler avec les routines de support de la souris de Fastgraph. Toute autre pilote de souris compatible Microsoft devrait également fonctionner correctement.


Initialisation de la souris

Il y a deux étapes nécessaires pour utiliser les routines de support de la souris de Fastgraph

au sein d'un programme d'application. D'abord, vous devez installer le pilote de la souris. Cela se fait avant de lancer l'application, généralement en entrant la commande MOUSE à l'invite de commande DOS. Deuxièmement, vous devez utiliser la fonction fg_mouseini de Fastgraph pour initialiser la souris dans le programme.

La fonction fg_mouseini n'a pas d'arguments et retourne un "succès ou

échec indicateur "comme valeur de fonction. Si la valeur de retour est -1, cela signifie fg_mouseini n'a pas pu initialiser la souris (soit parce que le pilote de la souris est pas installé, ou le pilote est installé, mais la souris est physiquement déconnecté). La valeur de retour sera également -1 si fg_mouseini est appelée quand un tampon virtuel est actif. Si fg_mouseini retourne une valeur entière positive, l'initialisation de la souris a réussi. la valeur elle-même indique le nombre de boutons (soit 2 ou 3) sur la souris. Si vous ne pas appeler fg_mouseini, ou si le Guide de l'utilisateur 310 Fastgraph


fg_mouseini ne peut pas initialiser la souris, aucun des autres routines de support de la souris de Fastgraph aura des effect.3

Exemple 14-6 illustre comment initialiser la souris. A la différence du clavier

routines de soutien, les routines de support de la souris de Fastgraph exigent que fg_setmode être appelé en premier. Dans cet exemple, nous passons simplement fg_setmode la valeur -1 pour initialiser Fastgraph pour tout ce mode vidéo est en vigueur lorsque nous courons le programme. Le programme appelle ensuite fg_mouseini et imprime un message indiquant si oui ou non l'initialisation a réussi. Si cela était le message comprend le nombre de boutons de la souris.

Exemple 14-6.
#include <fastgraf.h>
              #include <stdio.h>
             void main (void);
void main ()
              {
                statut int;
fg_initpm ();
                fg_setmode (-1);
                status = fg_mouseini ();
si (état <0)
                   printf ( "Souris pas disponible \ n".);
                 autre
                   printf ( "% d bouton de la souris trouvée. \ n", état);
              }


Vous devez être conscient que certains pilotes de souris n'initialisent pas entièrement

la souris lorsqu'un programme change les modes vidéo. Ce problème se produit plus fréquemment lorsque vous restaurez le mode vidéo d'origine à la fin d'un programme qui a appelé fg_mouseini. Lors du changement de mode vidéo, vous devez d'abord faire le curseur de la souris invisible (ceci est décrit dans la section suivante), changer le mode vidéo, puis appelez fg_mouseini nouveau pour initialiser la souris pour le nouveau mode vidéo.


XVGA et SVGA Souris Considérations

les pilotes de souris ne peuvent pas afficher directement le curseur de la souris dans XVGA et SVGA

modes graphiques (modes 20 à 29). Par conséquent, Fastgraph doit afficher le curseur de la souris à travers un gestionnaire d'interruption qui est activé chaque fois que la souris se déplace. Le gestionnaire est installé automatiquement lorsque vous appelez fg_mouseini dans les modes 20 à 29.


____________________

(3) Si vous utilisez une autre bibliothèque de souris ou de communiquer directement avec la souris

pilote, vous devez toujours appeler fg_mouseini si votre programme fonctionne dans les modes 13 à 18. Dans le cas contraire, Fastgraph ne saura pas que votre programme utilise une souris et peut afficher des graphiques de manière incorrecte.

Chapitre 14: Entrée Device Support 311


Si vous ne désactivez pas ce gestionnaire avant votre programme se termine, il sera

rester "accroché" au pilote de la souris. Ce sera très probablement accrocher votre système la prochaine fois que vous essayez de faire quoi que ce soit de conséquence. La routine fg_mousefin supprime le gestionnaire d'interruption de la souris de Fastgraph du pilote de la souris. Dans les modes XVGA et SVGA graphiques, vous devriez appeler fg_mousefin juste avant de restaurer le mode vidéo d'origine, comme indiqué ici:


fg_mousefin ();
                           fg_setmode (old_mode);
                           fg_reset ();


Encore une fois, fg_mousefin appel est nécessaire que dans les modes graphiques XVGA et SVGA. L'appeler dans d'autres modes vidéo est pas applicable, si elle ne pose aucun problème.

Dans le VGA standard / MCGA mode 256 couleurs (mode 19), les pixels blancs dans le

curseur souris sont affichées dans la couleur 15. Cela est incompatible avec d'autres modes graphiques, où les pixels blancs du curseur de la souris sont affichées dans la valeur de couleur numéro le plus élevé disponible dans ce mode. Fastgraph corrige cette incohérence dans XVGA et modes SVGA 256 couleurs graphiques en affichant blanc curseur de la souris pixels de couleur 255. Comme la couleur 15, la couleur 255 est blanc par défaut. Cela vous permet de redéfinir la couleur 15 dans vos applications 256 couleurs sans interférer avec les couleurs du curseur de la souris.


Contrôle du curseur de la souris

Le curseur de la souris indique que la position courante de la souris.  Par défaut,

le curseur est une petite flèche blanche dans les modes graphiques et un rectangle d'un caractère en mode texte. Après avoir utilisé fg_mouseini pour initialiser la souris, le curseur de la souris est invisible. Pour le rendre visible, vous devez utiliser fg_mousevis. Cette routine a un seul argument entier qui définit la visibilité du curseur de la souris. Si elle est de 0, le curseur de la souris sera invisible; si elle est 1, le curseur de la souris devient visible. Si le curseur de la souris est déjà dans l'État requis, fg_mousevis ne fait rien.

Si le curseur se trouve dans une zone de l'écran étant mis à jour, ou si

se déplace dans ce domaine au cours du processus de mise à jour, vous devez faire le curseur de la souris invisible ou le congeler à sa position actuelle. Vous devez aussi le faire lors de l'exécution de sortie vidéo dans les modes EGA et VGA graphiques natifs (modes 13 à 18). Au lieu de vérifier ces conditions, il est souvent plus pratique et efficace pour rendre le curseur de la souris invisible pendant toutes les mises à jour de l'écran, puis le rendre visible à nouveau lorsque la mise à jour est terminée. Une alternative à rendre le curseur de la souris invisible gèle à sa position actuelle en utilisant fg_mousepos et fg_mouselim (ces routines seront décrites sous peu) au cours des mises à jour de l'écran, puis restaurer les limites de la souris par défaut. Notez, cependant, que cette méthode ne fonctionne que si le curseur de la souris est en dehors de la zone mise à jour. Vous devez également faire le curseur de la souris invisible lors du changement de numéro de page visuel avec fg_setvpage.

Après l'initialisation de la souris, le curseur est positionné dans le centre de

l'écran.Déplacer la souris bien sûr change la position du curseur, mais vous pouvez également placer le pointeur de la souris avec le fg_mousemov routine Fastgraph. Cette routine a deux arguments qui spécifient le nouveau Guide 312 Fastgraph utilisateur horizontal et vertical


la position du curseur. La position est exprimée en unités d'espace d'écran pour les modes graphiques, alors qu'il est exprimé dans les cellules de caractères pour les modes de texte. La routine fg_mousemov déplace le curseur si oui ou non il est visible.

Parfois, il est utile de limiter le curseur de la souris sur une zone déterminée de

l'écran.La fg_mouselim routine Fastgraph empêche le curseur de la souris de se déplacer en dehors de la zone rectangulaire spécifiée. Il nécessite quatre arguments qui spécifient l'horizontale minimale coordonnée, horizontale maximale de coordonnées, coordonnée minimale verticale et maximale coordonnée verticale de cette zone. Encore une fois, les coordonnées sont exprimées en unités d'espace d'écran pour les modes graphiques et des cellules de caractères pour les modes de texte.

L'une des fonctions les plus importantes du pilote de la souris est de traduire

les mouvements de la souris horizontale et verticale dans une position sur l'écran. La souris signale ces mouvements vers le pilote de souris en unités appelées mickeys (un mickey est d'environ 1/200 de pouce, bien que pour certains pilotes de souris, il est 1/400 de pouce). Par défaut, le déplacement de la souris 8 mickeys dans le sens horizontal déplace le curseur de la souris un pixel horizontal. De même, en déplaçant la souris 16 mickeys se déplace verticalement le curseur d'un pixel vertical. Fastgraph fournit une fg_mousespd nommée routine qui peut modifier ces valeurs, ce qui permet effectivement de contrôler la vitesse à laquelle le curseur de la souris se déplace par rapport au mouvement de la souris elle-même. La routine de fg_mousespd nécessite deux arguments qui définissent le nombre de mickeys requis pour huit pixels de déplacement du curseur de la souris. Le premier argument spécifie ce pour la direction horizontale, et le second pour la direction verticale.

Exemple 14-7, qui fonctionne dans un mode graphique, démontre fg_mousevis,

fg_mousemov, fg_mouselim et fg_mousespd. Le programme établit d'abord le mode vidéo, initialise la souris, et remplit l'écran avec un rectangle blanc. Ensuite, le programme appelle fg_mousevis pour rendre le curseur de la souris visible et appelle ensuite fg_mouselim pour restreindre le curseur de la souris sur une zone d'un quart de la taille de l'écran, centré au milieu de l'écran. À ce stade, vous devez déplacer le curseur de la souris sur l'écran pour voir l'effet de fg_mouselim et notez la vitesse à laquelle le curseur se déplace par rapport à la souris elle-même. Le programme se poursuit lorsque vous appuyez sur une touche.

Le programme utilise ensuite fg_mousemov pour déplacer le curseur de la souris à chaque coin

de la région établie par fg_mouselim. L'appel à fg_waitfor garde le curseur dans chaque coin pendant deux secondes, à moins que vous déplacez la souris. Notez comment le programme tente de déplacer le curseur de la souris à chaque coin de l'écran, mais puisque cela serait déplacer le curseur en dehors de la zone définie de mouvement, fg_mousemov positionne juste le curseur à l'endroit le plus proche possible dans cette région. Le dernier appel à fg_mousemov déplace le curseur vers le milieu de l'écran. Après avoir fait cela, le programme appelle fg_mousespd pour changer la vitesse du curseur de la souris. Les valeurs passées à fg_mousespd (16 et 32) sont deux fois les valeurs par défaut et permettent donc vous déplacez la souris deux fois plus loin avant de déplacer le curseur de la souris à la même distance. Lorsque vous exécutez le programme, comparer la sensibilité de la souris à la vitesse d'origine. Après une séquence de touches, le programme revient à DOS.

Exemple 14-7.
#include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
             void main (void); 
                                     Chapitre 14: Entrée Device Support 313


void main ()
              {
                int maxx, maxy;
                int old_mode;
fg_initpm ();
                fg_getmode old_mode = ();
                fg_setmode (fg_automode ());
if (fg_mouseini () <0) {
                   fg_setmode (old_mode);
                   fg_reset ();
                   sortie (1);
                    }
maxx = fg_getmaxx ();
                maxy = fg_getmaxy ();
                fg_setcolor (15);
                fg_rect (0, maxx, 0, maxy);
fg_mousevis (1);
                fg_mouselim (maxx / 4,3 * maxx / 4, maxy / 4,3 * maxy / 4);
                fg_waitkey ();
fg_mousemov (0,0);
                fg_waitfor (36);
                fg_mousemov (maxx, 0);
                fg_waitfor (36);
                fg_mousemov (maxx, maxy);
                fg_waitfor (36);
                fg_mousemov (0, maxy);
                fg_waitfor (36);
                fg_mousemov (maxx / 2, maxy / 2);
                fg_mousespd (16,32);
                fg_waitkey ();
fg_setmode (old_mode);
                fg_reset ();
              }


Indication de l'état de la souris

Il est évidemment important de pouvoir suivre la position de la souris et

état de la touche. Les Fastgraph routines fg_mousepos et fg_mousebut vous permettre de le faire.

Les informations fg_mousepos des retours de routine à propos de la souris actuelle

la position du curseur et de l'état du bouton. Il nécessite trois arguments entiers, tous passés par référence. Les deux premiers arguments reçoivent respectivement les coordonnées horizontales et verticales du curseur de la souris. Ces valeurs sont exprimées en unités d'espace d'écran pour les modes graphiques et des cellules de caractères pour les modes de texte. Le troisième argument reçoit un masque à trois bits contenant l'état du bouton comme indiqué ici: Guide de l'utilisateur 314 Fastgraph


bit
               sens du nombre
0 1 si le bouton gauche enfoncé, 0 sinon
                  1 1 si le bouton droit enfoncé, 0 sinon
                  2 1 si le bouton du milieu enfoncé, 0 sinon

Par exemple, si les deux boutons gauche et droit sont pressés, l'état du bouton sera réglé à 3. Si la souris n'a que deux boutons, le bit 2 sera toujours zéro.

Une autre routine fg_mousebut est disponible pour renvoyer le nombre de

appuyez sur le bouton ou de libérer les chiffres qui se sont produits depuis la dernière vérification, ou depuis l'appel fg_mouseini. Chaque bouton de la souris maintient ses propres compteurs séparés, revient donc fg_mousebut cette information pour une touche spécifique. En outre, fg_mousebut renvoie la position horizontale et verticale du curseur de la souris au moment où le bouton spécifié dernière pression ou libéré.

La routine fg_mousebut prend quatre arguments entiers, dont la dernière

trois sont passés par référence. La valeur absolue de premier argument spécifie le bouton d'intérêt (1 signifie le bouton gauche, 2 est le bouton droit, et 3 est le bouton du milieu), alors que sa valeur réelle détermine si nous vérifions des presses ou des rejets. Si la valeur est positive, appuyez sur le bouton chiffres seront communiqués. Si elle est négative, la libération chiffres seront communiqués. Les deuxième, troisième et quatrième arguments reçoivent respectivement la presse ou la libération compte, la position du curseur de la souris horizontale au moment de la dernière pression ou la libération, et la position verticale à la même époque. Si la presse ou la libération comptage est égal à zéro, la position du curseur de la souris est retourné comme (0,0). Les positions de coordonnées sont exprimées en unités d'espace d'écran pour les modes graphiques et des cellules de caractères pour les modes de texte.

Exemple 14-8 fonctionne dans un mode graphique vidéo, et illustre l'utilisation de

fg_mousepos et fg_mousebut. Le programme établit d'abord le mode vidéo et initialise la souris (le programme sort si l'initialisation échoue) puis. Il prochaine remplit tout l'écran avec un rectangle blanc puis appelle fg_mousevis pour rendre le curseur de la souris visible.

La partie principale de l'exemple 14-8 est une boucle while qui interroge la souris au

intervalles de trois secondes (l'appel fg_waitfor (54) retarde le programme pendant trois secondes). Dans la boucle, le programme fg_mousebut utilise d'abord pour obtenir le nombre de fois sur le bouton gauche de la souris a été pressé dans les trois dernières secondes. Par la suite, la routine fg_mousepos obtient la position courante de la souris. Le programme affiche ensuite ces informations dans le coin supérieur gauche de l'écran; noter comment fg_mousevis est utilisé pour faire le curseur invisible pendant les opérations graphiques. Le programme se poursuit jusqu'à ce que vous appuyez sur le bouton droit de la souris, vérifié par l'appel à fg_mousebut à la fin de la boucle.

Exemple 14-8.
#include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
        void main (void);
void main ()   
                                     Chapitre 14: Entrée Device Support 315


 {
           int old_mode;
           boutons int, count;
           int x, y;
           chaîne char [25];
fg_initpm ();
           fg_getmode old_mode = ();
           fg_setmode (fg_automode ());
if (fg_mouseini () <0) {
              fg_setmode (old_mode);
              fg_reset ();
              sortie (1);
               }
fg_setcolor (15);
           fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
           fg_mousevis (1);
faire {
              fg_waitfor (54);
              fg_mousebut (1, & compter, et x, et y);
              fg_mousepos (& x, et y, et boutons);
              sprintf (string, "X =% 3d Y =% count 3d =% 4d", x, y, compter);
              fg_mousevis (0);
              fg_setcolor (15);
              fg_rect (0, fg_xconvert (25), 0, fg_yconvert (1));
              fg_setcolor (0);
              fg_locate (0,0);
              fg_text (string, 24);
              fg_mousevis (1);
              fg_mousebut (2, et compter, et x, et y);
               }
           tandis que (compter == 0);
fg_setmode (old_mode);
           fg_reset ();
         }


Définir le curseur de la souris

Par défaut, le curseur de la souris est une petite flèche blanche dans les modes graphiques et

un rectangle d'un caractère en mode texte. Dans les modes graphiques, vous pouvez modifier le curseur de la souris sur une image 16 par 16 pixels avec la fg_mouseptr routine Fastgraph (en modes graphiques quatre couleurs les CGA, la taille du curseur est de 8 par 16 pixels). Vous ne pouvez pas changer la forme du curseur de la souris en mode texte, mais vous pouvez utiliser le fg_mousecur routine Fastgraph pour définir la façon dont il interagit avec des personnages existants sur l'écran. Guide de l'utilisateur 316 Fastgraph


Modes de texte

Pour changer le curseur de la souris en mode texte, vous devez d'abord définir deux 16-

des quantités de bits appelé le masque de l'écran et le masque de curseur. La figure suivante définit le format de chaque masque.

les bits signifie
valeur de caractère 0-7 ASCII
                  8 à 11 couleur de premier plan
                  12 à 14 couleur de fond
                  15 blink

Notez comment cette structure est parallèle à la nature et des octets d'attributs associé à chaque cellule de caractère. Le masque d'écran par défaut est 77FF hex, et le masque de curseur par défaut est 7700 hex.

Lorsque vous placez la souris sur une cellule de caractère spécifique, la souris

pilote utilise les masques d'écran et curseur pour déterminer l'apparence du curseur de la souris. Tout d'abord, le pilote de souris logiquement ANDS le masque de l'écran avec le contenu existant de cette cellule de caractère. Il a ensuite XORs résultant avec le masque de curseur pour afficher le curseur de la souris.

Par exemple, examiner comment le curseur de la souris est produit dans la colonne 80

mode texte de couleur (mode 3). Supposons qu'une cellule de caractère spécifique contient le caractère ASCII 0 (48 décimal, 30 hex) et un octet d'attribut qui spécifie un blanc (couleur 15) de premier plan sur un fond bleu (couleur 1) et ne clignote pas (bit clin 0). La structure binaire du caractère et son attribut sont:

attribuer le caractère
0 001 1111 00110000


Maintenant, nous allons voir ce qui se passe lorsque nous appliquons l'écran et de curseur masques pour le caractère et son attribut.


attribut / caractère 0001 1111 0011 0000 (1F30 hex)
          écran de masque 0111 0111 1111 1111 (77FF hex) par défaut
                                 -------------------
          résultat de ET 0001 0111 0011 0000 (1730 hex)
          curseur de masque 0111 0111 0000 0000 (7700 hex) par défaut
                                 -------------------
          résultat de XOR 0110 0000 0011 0000 (6030 hex)


Le caractère résultant (30 hex) est le caractère original, mais le nouvel attribut (60 hex) représente un premier plan noir avec un fond brun et ne clignote pas. Tant que le curseur de la souris reste positionné sur cette cellule de caractère, il apparaît noir sur le brun.

Lorsque nous utilisons l'écran et de curseur par défaut des masques, le curseur de la souris

toujours afficher le caractère original et il ne clignote pas. La couleur de premier plan du curseur sera 15-F, où F est la couleur de premier plan du caractère affiché. De même, la couleur d'arrière-plan curseur sera 7-B, où B est la

Chapitre 14: Entrée Device Support 317


La couleur de fond de caractère affiché. Les masques par défaut seront presque toujours produire un curseur de la souris satisfaisante.

Il est cependant possible de modifier l'aspect du curseur de la souris

modes de texte en utilisant vos propres masques d'écran et de curseur. La fg_mousecur routine Fastgraph fait justement cela. Il attend deux arguments, le premier étant le masque de curseur et le second masque de l'écran. Exemple 14-9 illustre l'utilisation de fg_mousecur. Le programme affiche un texte et utilise le curseur de la souris par défaut. Après avoir attendu pendant une séquence de touches, le programme appelle fg_mousecur pour définir un nouveau curseur de la souris. Le nouveau curseur est similaire au curseur par défaut, mais il affiche les couleurs de premier plan dans l'intensité opposé, comme le curseur par défaut. Le programme attend ensuite une autre touche avant de revenir à DOS.

Exemple 14-9.
#include <fastgraf.h>
                 #include <stdio.h>
                 #include <stdlib.h>
                void main (void);
void main ()
                 {
                   int old_mode;
                   int rangée;
fg_initpm ();
                   fg_getmode old_mode = ();
                   fg_setmode (3);
if (fg_mouseini () <0) {
                      fg_setmode (old_mode);
                      fg_reset ();
                      sortie (1);
                       }
fg_setattr (7,0,0);
                   fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
fg_setattr (12,7,0);
                   pour (rang = 0; rangée <25; rangée ++) {
                      fg_locate (ligne, 34);
                      fg_text ( "exemple 14-9", 12);
                       }
fg_mousevis (1);
                   fg_waitkey ();
                   fg_mousecur (0x7FFF, 0x7F00);
                   fg_waitkey ();
fg_setmode (old_mode);
                   fg_reset ();
                }   

Guide de l'utilisateur 318 Fastgraph


Modes graphiques

Définir le curseur de la souris dans graphiques modes vidéo nécessite également création

un masque d'écran et le curseur masque, mais comme on pouvait s'y attendre, la structure de ces masques est très différent de modes de texte. En fait, il ressemble étroitement au format bitmap en mode indépendant utilisé par fg_drawmap. Bien que leur structure est différente, la façon dont le pilote de souris applique les masques sont les mêmes que dans les modes de texte. Autrement dit, le pilote affiche le curseur de la souris d'abord logiquement la mémoire ANDing vidéo avec le masque de l'écran, puis XORing qui résultent avec le masque de curseur.

Commençons par regarder les masques pour le curseur de la souris par défaut dans

les modes graphiques. La taille de chaque masque (et donc le curseur de la souris) est de 16 pixels de large et 16 pixels de haut. Comme mentionné précédemment, le curseur par défaut est une petite flèche blanche avec un contour noir autour d'elle. Voici ses masques d'écran et de curseur exprimés en valeurs binaires.

curseur à l'écran curseur
             masque apparence de masque
1001111111111111 0000000000000000 **
       1000111111111111 0010000000000000 * x *
       1000011111111111 0011000000000000 * xx *
       1000001111111111 0011100000000000 * xxx *
       1000000111111111 0011110000000000 * xxxx *
       1000000011111111 0011111000000000 * xxxxx *
       1000000001111111 0011111100000000 * xxxxxx *
       1000000000111111 0011111110000000 * xxxxxxx *
       1000000000011111 0011111111000000 * xxxxxxxx *
       1000000000001111 0011111000000000 * xxxxx *****
       1000000011111111 0011011000000000 * xx xx * *
       1000100001111111 0010001100000000 * x * xx *
       1001100001111111 0000001100000000 ** * * xx
       1111110000111111 0000000110000000 * xx *
       1111110000111111 0000000110000000 * xx *
       1111111000111111 0000000000000000 ***
Le pilote de souris premier ANDS le masque de l'écran avec la mémoire vidéo à la

position du curseur souris. Cela signifie que le masque d'écran 1 bits laissent mémoire vidéo intacte, tandis que les bits 0 changent les pixels correspondant au noir. Ensuite, le pilote de souris le résultat XOR avec le masque de curseur. Cette fois le curseur masque bits 0 quittent la mémoire vidéo inchangée, tandis que les 1 bits changent les pixels correspondants au blanc. Cela produit un curseur de la souris comme indiqué ci-dessus à droite, où un point () représente un pixel inchangé, un astérisque (*) un pixel noir et un pixel blanc xa. Le tableau suivant résume l'apparence du curseur pour toutes les combinaisons possibles de bits de masque.

bit de masque écran masque bit de curseur résultant curseur pixel
0 0 noir
                  0 1 blanc
                  1 0 inchangé
                  1 1 inversé
La couleur d'un pixel «inversé» est nk, où n est la couleur maximale

numéro dans le mode vidéo en cours, et k est la couleur du pixel

Chapitre 14: Entrée Device Support 319

remplacé.En outre, "noir" et pixels "blancs" ne sont pas nécessairement ces couleurs dans les modes 16 couleurs et 256 couleurs. Plus exactement, "noir" pixels sont affichés dans la couleur attribuée à la palette 0 et pixels "blancs" sont les affichés dans la couleur attribuée à la palette 15 (255 en XVGA et SVGA 256 couleurs modes). Si vous utilisez les modes de couleur CGA, "noir" pixels sont affichés dans la couleur de fond, et "blancs" pixels apparaissent en couleur 3 (dont la couleur réelle est déterminée par la palette CGA sélectionnée).

Avec une compréhension de la façon dont le curseur de la souris par défaut fonctionne dans

modes graphiques, nous sommes maintenant prêts à définir notre propre curseur de la souris. On voit ici le masque de l'écran, le masque de curseur, et l'aspect résultant pour un curseur en forme de plus-solide. Les équivalents hexadécimaux des valeurs de masque binaires sont également donnés.

----- Masque écran ---- ----- masque de curseur ----
                                                               le curseur
      hex binaire apparence hexadécimal binaire
1110000000111111 0000000000000000 E03F 0000 ... ******* ......
 1110000000111111 0000111110000000 E03F 0F80 ... * xxxxx * ......
 1110000000111111 0000111110000000 E03F 0F80 ... * xxxxx * ......
 0000000000000111 0000111110000000 0007 0F80 **** **** xxxxx ...
 0000000000000111 0111111111110000 0007 7FF0 * xxxxxxxxxxx * ...
 0000000000000111 0111111111110000 0007 7FF0 * xxxxxxxxxxx * ...
 0000000000000111 0111111111110000 0007 7FF0 * xxxxxxxxxxx * ...
 0000000000000111 0111111111110000 0007 7FF0 * xxxxxxxxxxx * ...
 0000000000000111 0111111111110000 0007 7FF0 * xxxxxxxxxxx * ...
 0000000000000111 0000111110000000 0007 0F80 **** **** xxxxx ...
 1110000000111111 0000111110000000 E03F 0F80 ... * xxxxx * ......
 1110000000111111 0000111110000000 E03F 0F80 ... * xxxxx * ......
 1110000000111111 0000000000000000 E03F 0000 ... ******* ......
 1111111111111111 0000000000000000 FFFF 0000 ................
 1111111111111111 0000000000000000 FFFF 0000 ................
 1111111111111111 0000000000000000 FFFF 0000 ................

Si nous voulions faire le curseur de la souris creuse plutôt que solide, les masques et l'apparence du curseur résultant serait ressembler à ceci.

----- Masque écran ---- ----- masque de curseur ----
                                                               le curseur
      hex binaire apparence hexadécimal binaire
1110000000111111 0000000000000000 E03F 0000 ... ******* ......
 1110111110111111 0000000000000000 EFBF 0000 ... * ..... * ......
 1110111110111111 0000000000000000 EFBF 0000 ... * ..... * ......
 0000111110000111 0000000000000000 0F87 0000 **** ..... **** ...
 0111111111110111 0000000000000000 7FF7 0000 * ........... * ...
 0111111111110111 0000000000000000 7FF7 0000 * ........... * ...
 0111111111110111 0000001000000000 7FF7 0200 * ..... x ..... * ...
 0111111111110111 0000000000000000 7FF7 0000 * ........... * ...
 0111111111110111 0000000000000000 7FF7 0000 * ........... * ...
 0000111110000111 0000000000000000 0F87 0000 **** ..... **** ...
 1110111110111111 0000000000000000 EFBF 0000 ... * ..... * ......
 1110111110111111 0000000000000000 EFBF 0000 ... * ..... * ......
 1110000000111111 0000000000000000 E03F 0000 ... ******* ......
 1111111111111111 0000000000000000 FFFF 0000 ................
 1111111111111111 0000000000000000 FFFF 0000 ................
 1111111111111111 0000000000000000 FFFF 0000 ................   

Guide de l'utilisateur 320 Fastgraph


A noter que le bit central défini dans le masque de curseur provoque le pixel correspondant dans la mémoire vidéo qui doit être inversée.

Il y a un élément plus nécessaire pour définir un curseur de la souris en mode graphique

complètement.Ce point est le point chaud, ou la position réelle de l'écran utilisé ou rapporté par le pilote de la souris. Pour les curseurs en forme de plus-juste construit, il serait logique de définir le point chaud dans le centre de la plus. Le point chaud est spécifié par rapport au coin supérieur gauche du curseur, de sorte que sa position dans le curseur serait (6,6) - qui est, six pixels à droite et six pixels en dessous du coin supérieur gauche. Vous pouvez spécifier les décalages de points chauds en utilisant des valeurs ou des valeurs négatives au-dessus de 15 pour le positionner en dehors de la matrice du curseur de la souris si vous le souhaitez.

La fg_mouseptr routine Fastgraph définit un curseur de la souris dans les graphiques

modes. Le premier de ses trois arguments est un 32 élément 16 bits entier tableau, passé par référence. 16 premiers éléments du tableau contiennent le masque d'écran, et ses deuxièmes 16 éléments contiennent le masque de curseur. Les deux arguments restants précisent respectivement les décalages horizontaux et verticaux pour le point chaud. La routine de fg_mouseptr n'a aucun effet en mode texte vidéo. Dans les programmes C ou C ++, nous vous recommandons d'utiliser le type de données à court pour le tableau de masque parce court signifie un entier de 16 bits pour les environnements 16 bits et 32 ​​bits. De même, les programmeurs FORTRAN devraient définir la matrice de masque comme un ENTIER * 2 article.

Exemple 14-10 est similaire à l'exemple 14-9. Il montre comment définir un

curseur de la souris en mode graphique en utilisant fg_mouseptr. Les valeurs stockées dans les tableaux pleins et creux définissent l'écran et de curseur masques pour les curseurs de souris en forme de plus-pleins et creux discuté plus tôt. Après avoir fait le curseur de la souris visible, le programme utilise le curseur de la souris par défaut jusqu'à ce qu'une touche est enfoncée. À la suite de cela, il se transforme en curseur solide. Après une autre touche, le programme se transforme en curseur creux. Lorsque vous exécutez exemple 14-10, comparer les différences entre les trois curseurs de souris.

Exemple 14-10.
#include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
              void main (void);
court solide [] = {0xE03F, 0xE03F, 0xE03F, 0x0007,
                                0x0007,0x0007,0x0007,0x0007,
                                0x0007,0x0007,0xE03F, 0xE03F,
                                0xE03F, 0xFFFF, 0xFFFF, 0xFFFF,
                                0x0000,0x0F80,0x0F80,0x0F80,
                                0x7FF0,0x7FF0,0x7FF0,0x7FF0,
                                0x7FF0,0x0F80,0x0F80,0x0F80,
                                0x0000,0x0000,0x0000,0x0000};
court creux [] = {0xE03F, 0xEFBF, 0xEFBF, 0x0F87,
                                0x7FF7,0x7FF7,0x7FF7,0x7FF7,
                                0x7FF7,0x0F87,0xEFBF, 0xEFBF,
                                0xE03F, 0xFFFF, 0xFFFF, 0xFFFF,
                                0x0000,0x0000,0x0000,0x0000,   
                                     Chapitre 14: Entrée Device Support 321


0x0000,0x0000,0x0200,0x0000,
                                0x0000,0x0000,0x0000,0x0000,
                                0x0000,0x0000,0x0000,0x0000};
void main ()
               {
                 int old_mode;
                 int colonne, ligne, LAST_ROW;
fg_initpm ();
                 fg_getmode old_mode = ();
                 fg_setmode (fg_automode ());
if (fg_mouseini () <0)
                  {
                    fg_setmode (old_mode);
                    fg_reset ();
                    sortie (1);
                  }
fg_setcolor (15);
                 fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
fg_setcolor (12);
                 colonne = fg_xalpha (fg_getmaxx () / 2) - 6;
                 LAST_ROW = fg_yalpha (fg_getmaxy ()) + 1;
pour (rang = 0; ligne <LAST_ROW; rangée ++)
                  {
                    fg_locate (ligne, colonne);
                    fg_text ( "exemple 14-10", 13);
                  }
fg_mousevis (1);
                 fg_waitkey ();
                 fg_mouseptr (solide, 6,6);
                 fg_waitkey ();
                 fg_mouseptr (creux, 6,6);
                 fg_waitkey ();
fg_setmode (old_mode);
                 fg_reset ();
               }


Considérations CGA

Le pilote de souris traite l'écran et curseur masques différemment dans le

CGA modes graphiques en quatre couleurs (modes 4 et 5) que dans les autres modes graphiques. Dans les modes CGA, chaque paire de bits de masque correspondant à un pixel. Cela signifie que les masques ressemblent plus étroitement à la forme spécifique du mode utilisé par fg_drwimage au lieu du format de mode indépendant de fg_drawmap.

Fastgraph utilise un curseur différent de la souris par défaut pour les modes 4 et 5. Son

écran et curseur masques, ainsi que l'apparence du curseur résultant, sont présentés dans le schéma suivant. Guide de l'utilisateur 322 Fastgraph


curseur à l'écran curseur
               masque apparence de masque
0000111111111111 0000000000000000 **
         0000001111111111 0011000000000000 ***
         0000000011111111 0011110000000000 ****
         0000000000111111 0011111100000000 *****
         0000000000001111 0011111111000000 ******
         0000000000000011 0011111111110000 *******
         0000000000000011 0011111100000000 *******
         0000000000111111 0011111110000000 *****
         0000000000001111 0011000011000000 ******
         0000110000001111 0000000011000000 ** ***
         1111111100000011 0000000000110000 ***
         1111111100000011 0010000000110000 ***
         1111111111000011 0000000000000000 **
         1111111111111111 0000000000000000
         1111111111111111 0000000000000000
         1111111111111111 0000000000000000

Comme vous pouvez le voir, le curseur de la souris résultante est huit pixels de large au lieu de 16.

Un autre point important concernant les curseurs de souris dans les modes 4 et 5 est le

risque de saignement du pixel, ou la modification des couleurs à l'intérieur du curseur de la souris lorsqu'elle se déplace horizontalement. Le saignement se produit si vous utilisez les paires de bits 01 ou 10 dans les deux masque pour représenter un pixel. Dans les masques par défaut pour les modes 4 et 5, notez que seules les valeurs binaires 00 et 11 apparaissent sous forme de paires de bits. Gardez cela à l'esprit si vous créez vos propres masques dans ces modes vidéo.

XVGA et SVGA Considérations

Dans les modes graphiques XVGA et modes 256 couleurs SVGA graphiques (20 à 27), il est

possible de créer un curseur de souris multicolores. Pour ce faire, utilisez fg_mouse256 au lieu de fg_mouseptr pour définir la forme et l'apparence du curseur de la souris. La routine fg_mouse256 utilise les mêmes arguments que fg_mouseptr, mais les masques sont passés dans un tableau de 512 octets constitué d'un masque d'écran de 256 octets suivi d'un masque de curseur 256 octets. Comme dans le cas fg_mouseptr, chaque masque est structurée comme une grille de 16x16 pixels, mais chaque pixel est représenté par une valeur d'octet plutôt que d'un seul bit.

Le pilote de la souris affiche le curseur de la souris par opération logique vidéo

mémoire avec le masque de l'écran, puis XORing qui résultent avec le masque de curseur. Cela signifie normalement les valeurs de masque d'écran sont soit 0 ou 255, tandis que les valeurs de masque de curseur se situent entre 0 et 255. Par exemple, examiner de nouveau la graphique par défaut mode curseur de la souris (la flèche). Si nous voulions afficher le curseur en jaune (couleur 14) à la place de son blanc par défaut, vous développez le masque d'écran de 16 à 256 octets, en remplaçant les bits à zéro dans le masque "standard" avec zéro octets et en remplaçant les bits un avec la valeur 255. Vous de même élargir le masque du curseur, en remplaçant les bits zéro avec zéro octets et les bits à la valeur 14.

Chapitre 14: Entrée Device Support 323


Joystick support

Le troisième type de dispositif d'entrée pris en charge par Fastgraph est le joystick.

Bien que les joysticks sont pas aussi populaires que les souris, ils sont souvent préférables lorsque les réactions d'un utilisateur sont critiques, comme dans un jeu de style arcade. Fastgraph comprend des routines pour l'initialisation d'un joystick, la lecture la position ou le bouton du statut d'un joystick, et en faisant un joystick se comportent de manière analogue au clavier. Ces routines sont indépendantes du reste de Fastgraph et ne nécessitent donc pas que vous premier appel fg_setmode.

Manettes de jeu sont connectés à un système par l'intermédiaire d'un port de jeu. Le PCjr et

Tandy 1000 systèmes sont équipés de deux ports de jeu, et donc soutenir deux joysticks. Sur les autres systèmes de la famille IBM, vous pouvez installer une carte de jeu avec un ou deux ports de jeu. Si la carte ne comporte qu'un seul port de jeu, vous pouvez utiliser un câble séparateur à débourser deux joysticks dans le port.


Initialisation Joysticks

Avant de pouvoir utiliser l'une des routines de support de manette de Fastgraph avec un

joystick spécifique, vous devez initialiser ce joystick. La routine de fg_initjoy exécute cette tâche. Cette routine nécessite un seul argument entier qui spécifie le joystick pour initialiser, soit 1 ou 2. En cas de succès, fg_initjoy retourne 0 comme valeur de la fonction. Si la machine n'a pas de port de jeu, ou si le joystick demandé ne soit pas connecté au port de jeu, fg_initjoy renvoie -1. Lorsque vous utilisez fg_initjoy, le joystick en cours d'initialisation doit être centrée (qui est, le bâton lui-même doit pas être incliné dans les deux sens).

Exemple 14-11 utilise la routine de fg_initjoy pour essayer d'initialiser à la fois

joysticks. Pour chaque manette, le programme imprime un message indiquant si oui ou non l'initialisation a réussi.

Exemple 14-11.
#include <fastgraf.h>
                #include <stdio.h>
               void main (void);
void main ()
                {
                  fg_initpm ();
                  if (fg_initjoy (1) <0)
                     printf ( "Joystick 1 pas disponible \ n de.");
                   autre
                     printf ( "Joystick 1 trouvé \ n de.");
if (fg_initjoy (2) <0)
                     printf ( "Joystick 2 pas disponible \ n de.");
                   autre
                     printf ( "Joystick 2 trouvé \ n de.");
               }   

Guide de l'utilisateur 324 Fastgraph


Rapports Joystick Status

Chaque joystick peut signaler trois éléments: sa position horizontale, son

position verticale, et l'état du bouton. Fastgraph comprend des routines pour obtenir chacune de ces quantités.

Les fg_getxjoy et fg_getyjoy routines renvoient respectivement à l'horizontale

et la position verticale du levier de commande indiqué. Les deux routines nécessitent un seul argument entier, dont la valeur est 1 ou 2, pour identifier le joystick. La position demandée est renvoyée comme valeur de la fonction. Les coordonnées horizontales augmentent à mesure que la manette est déplacé vers la droite, tandis que les coordonnées verticales augmentent à mesure que la manette se déplace vers le bas. Si fg_initjoy n'a pas été initialisé le joystick spécifié, ou si votre programme n'a pas encore appelé fg_initjoy, tant fg_getxjoy et fg_getyjoy retournera -1.

Caractéristiques Joystick varient plus que ceux de tout autre dispositif d'entrée.

Les valeurs renvoyées par fg_getxjoy et fg_getyjoy dépendent de la vitesse du processeur du système et la marque du joystick utilisé. Il suffit souvent de connaître la position par rapport à sa position précédente du joystick, auquel cas la réelle valeurs de coordonnées ne comptent pas. Toutefois, si vous devez compter sur spécifique des valeurs de coordonnées, votre programme doit effectuer un certain type de calibrage manuel du joystick, puis escalader les coordonnées déclarées par fg_getxjoy et fg_getyjoy au besoin.

L'autre élément d'information joysticks fournissent est l'état du bouton.

La plupart des joysticks ont deux boutons, appelés les boutons du haut et du bas. D'autres ont trois boutons, mais l'un d'eux duplique la fonctionnalité d'un autre (par exemple, un joystick peut avoir un bouton en bas sur le côté gauche et une autre sur le côté droit). La fg_button routine Fastgraph renvoie le joystick statut de bouton comme sa valeur de fonction. Comme fg_getxjoy et fg_getyjoy, fg_button nécessite un seul argument qui spécifie le numéro de joystick. La signification de la valeur de retour est montré ici:

sens de la valeur
0 ne touche enfoncée
                            1 bouton supérieur enfoncé
                            2 bouton du bas pressé
                            3 boutons haut et bas pressé
Vous ne devez appeler fg_initjoy avant d'utiliser fg_button.  Si la

joystick spécifié est absent, fg_button retourne une valeur de 0.

Exemple 14-12 utilise fg_getxjoy, fg_getyjoy et fg_button pour interroger à la fois

joysticks à intervalles d'une demi-seconde. Il affiche ensuite le numéro de joystick (1 ou 2), la position horizontale, la position verticale, et l'état de bouton pour chaque manette. Comme le programme fonctionne, vous pouvez déplacer les joysticks et regarder la façon dont les mouvements affectent l'affichage des valeurs de coordonnées. Le programme continue ainsi jusqu'à ce que vous appuyez sur Ctrl / C ou Ctrl / Pause pour l'arrêter.

Exemple 14-12.
#include <fastgraf.h>
                 #include <stdio.h>
                void main (void); 
                                     Chapitre 14: Entrée Device Support 325


void main ()
                 {
                   int b, x, y;
fg_initpm ();
                   fg_initjoy (1);
                   fg_initjoy (2);
while (1) {
                      x = fg_getxjoy (1);
                      y = fg_getyjoy (1);
                      b = fg_button (1);
                      printf ( "1:% 3d% 3d% 1d \ n", x, y, b);
                      x = fg_getxjoy (2);
                      y = fg_getyjoy (2);
                      b = fg_button (2);
                      printf ( "2:% 3d% 3d% 1d \ n \ n", x, y, b);
                      fg_waitfor (9);
                       }
                 }


Il y a deux façons de surveiller efficacement l'état de bouton du joystick.  Un

est d'appeler fg_button à de nombreux endroits dans votre programme, puis prendre les mesures nécessaires en fonction de l'état du bouton. Cependant, la méthode préférée est d'étendre le BIOS d'interruption du temps de la journée pour vérifier l'état du bouton à chaque coup d'horloge (il y a 18,2 horloge par seconde), définir un indicateur si un bouton est enfoncé, puis vérifier le drapeau comme nécessaire dans votre programme. Informations sur la modification du BIOS interruption de temps de jour figure à l'Annexe C.


Keyboard Emulation

Bien que nous puissions utiliser fg_getxjoy et fg_getyjoy pour surveiller par rapport

les mouvements de la manette, il est généralement plus facile de le faire avec une autre routine Fastgraph, fg_intjoy. Cette routine est similaire à fg_intkey en ce qu'il renvoie deux valeurs équivalentes aux codes de clavier standard ou étendues pour des frappes analogues.

La routine de fg_intjoy a besoin de trois arguments. Le premier argument spécifie

le numéro de joystick, 1 ou 2. Les deuxième et troisième arguments, les deux quantités d'octets ONe passés par référence, reçoivent les codes de clavier standard et étendu analogues au mouvement de la manette et l'état de bouton. Le second argument reçoit une valeur de 13 (le code de clavier standard pour la touche Entrée) si un bouton de la manette est enfoncée; il reçoit une valeur de 0 sinon. Le troisième argument reçoit une valeur correspondant au code de clavier étendu pour l'une des touches directionnelles du clavier numérique, tel que résumé dans le tableau suivant.

position de joystick clé étendue code clé correspondant
et quitté la maison 71
                 up up flèche 72
            haut et à droite PgUp 73
                gauche flèche gauche 75   

Guide de l'utilisateur 326 Fastgraph


centrée (aucune action) 0
                droite droite du 77
            vers le bas et 79 Fin gauche
                flèche vers le bas vers le bas 80
           vers le bas et à droite PgDn 81

La routine fg_intjoy établira deux arguments clés de code à zéro si le joystick spécifié n'a pas encore été initialisé.

Exemple 14-13 est similaire à l'exemple 14-11, mais il utilise fg_intjoy en place

de fg_getxjoy et fg_getyjoy signaler la position relative du joystick. Ce programme ne signale pas l'état du bouton du joystick comme exemple 14-11 fait, mais vous pouvez facilement ajouter cette fonctionnalité à elle.

Exemple 14-13.
#include <fastgraf.h>
                   #include <stdio.h>
                  void main (void);
void main ()
                   {
                     clé char, aux;
fg_initpm ();
                     fg_initjoy (1);
                     fg_initjoy (2);
while (1) {
                        fg_intjoy (1, touche &, & aux);
                        printf ( "1:% 2d% 2d \ n", clé, aux);
                        fg_intjoy (2, touche &, & aux);
                        printf ( "2:% 2d% 2d \ n \ n", clé, aux);
                        fg_waitfor (9);
                         }
                   }


Considérations Joystick spéciales

Si vous développez un programme qui prend en charge un seul joystick, vous devez utiliser

joystick 1. Les raisons sont de deux ordres. Tout d'abord, il fera de votre programme compatible avec la plupart des autres produits qui prennent en charge les joysticks. Deuxièmement, de nombreux Tandy 1000 machines de série ne peuvent pas déterminer si joystick 2 est présent lorsque ni joystick est connecté. Cela signifie que si vous utilisez joystick 2 à la place de la manette 1 dans un programme de joystick unique, vous ne serez pas en mesure de dire si un joystick est disponible lors de l'exécution sur un Tandy 1000.


Résumé des Routines d'entrée

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

Chapitre 14: Entrée Device Support 327


FG_BUTTON renvoie des informations sur l'état de l'une manette de

boutons.

FG_CAPSLOCK détermine l'état de la touche CapsLock.
FG_GETKEY attend une touche (ou lit l'entrée suivante à partir du BIOS

mémoire tampon du clavier). Il renvoie le code de clavier standard ou étendu de la frappe.

FG_GETXJOY et FG_GETYJOY reviennent à l'horizontale et verticale de coordonnées

position du joystick spécifié. Les coordonnées réelles dépendent de la vitesse du processeur et la marque de joystick utilisé.

FG_INITJOY initialise joystick 1 ou 2 et doit être appelé avant d'utiliser

fg_getxjoy, fg_getyjoy ou fg_intjoy. Elle renvoie un code d'état indiquant si oui ou non l'initialisation a réussi.

FG_INTJOY renvoie les codes de clavier standard et étendue analogue à

la position et le bouton état actuel du joystick spécifié.

FG_INTKEY lit la prochaine entrée de la mémoire tampon et retourne clavier BIOS

code de clavier standard ou étendu de la frappe. Il est semblable à fg_getkey, mais il ne pas attendre une touche si la mémoire tampon du clavier est vide.

FG_KBINIT active ou désactive le gestionnaire de clavier de bas niveau de Fastgraph.  Si

le gestionnaire de clavier est déjà dans l'État requis, rien ne se passe.

FG_KBLAST renvoie le code de balayage pour le plus récent traité par keypress

Le gestionnaire de clavier de bas niveau de Fastgraph.

FG_KBRESET réinitialise l'état du gestionnaire de clavier de bas niveau de Fastgraph à

ce qu'il était après avoir été activé avec fg_kbinit.

FG_KBTEST détermine si la clé ayant le code de balayage spécifiée est maintenant

enfoncée ou relâchée. Le gestionnaire de clavier de bas niveau doit être activé pour que cette routine fonctionne correctement.

FG_MOUSE256 définit la forme et l'apparence d'une souris multicolore

curseur en mode SVGA graphiques XVGA et 256 couleurs.

FG_MOUSEBUT renvoie des informations sur le bouton de la souris ou de la libération de presse

compte, ainsi que la position du curseur de la souris au moment de la dernière pression sur un bouton ou de la libération.

FG_MOUSECUR définit l'apparence du curseur de la souris dans le texte vidéo

modes.

FG_MOUSEFIN dégrafe XVGA ou SVGA le gestionnaire de la souris de Fastgraph de la souris

chauffeur.Cette routine doit être utilisé juste avant de revenir au mode texte dans les programmes qui ont appelé fg_mouseini dans les modes graphiques XVGA ou SVGA. Il n'a pas d'effet dans d'autres modes vidéo.

FG_MOUSEINI initialise la souris et doit être appelée avant tout de

d'autres routines de support de la souris de Fastgraph. Elle retourne un état d'erreur si le Guide de l'utilisateur 328 Fastgraph


pilote de souris n'a pas été chargé, si la souris est pas connecté, ou si un tampon virtuel est actif.

FG_MOUSELIM définit la zone rectangulaire dans laquelle le curseur de la souris peut

Déplacer.

FG_MOUSEMOV déplace le curseur de la souris sur la cellule de caractère spécifié (en

modes de texte) ou la position de l'espace de l'écran (en mode graphique).

FG_MOUSEPOS renvoie la position actuelle de la souris et l'état de bouton.
FG_MOUSEPTR définit la forme et l'apparence du curseur de la souris dans

graphiques modes vidéo.

FG_MOUSESPD définit le nombre d'unités mickey par huit pixels du curseur

mouvement. Ce contrôle efficacement la vitesse à laquelle le curseur se déplace par rapport au déplacement de la souris elle-même.

FG_MOUSEVIS rend le curseur de la souris visible ou invisible.
FG_NUMLOCK détermine l'état de la touche Verr Num.
FG_SCRLOCK détermine l'état de la clé ScrollLock (qui ne sont pas

présent sur certains claviers).

FG_SETCAPS contrôle l'état de la clé de CapsLock.
FG_SETNUM contrôle l'état de la touche Verr Num.
FG_WAITKEY vide la mémoire tampon du clavier du BIOS (qui est, supprime toute type-

avance caractères) et attend une autre touche.



chapitre 15


Effets sonores 330 Guide de l'utilisateur Fastgraph


aperçu

Dans le domaine de l'IBM PC et PS / 2 famille de systèmes, un son est défini

par sa fréquence, la durée et le volume. La fréquence d'un son est mesurée en unités appelées Hertz. Alors que le PC et PS / 2 peuvent produire des sons allant de 18 à plus d'un million Hertz, l'humain moyen peut entendre des sons entre 20 et 20.000 Hertz. La longueur d'un son, appelé sa durée, est exprimée en tops d'horloge; il y a soit 18,2 de 72,8 horloge par seconde, selon la méthode utilisée pour produire le son. Enfin, le volume détermine l'intensité sonore du son. Comme nous le verrons dans ce chapitre, nous pouvons contrôler le volume d'un son uniquement sur le PCjr et Tandy 1000 systèmes.

Fastgraph propose plusieurs méthodes différentes pour produire des effets sonores.

Ceux-ci incluent des tonalités simples, une série de tonalités exprimée numériquement, ou une série de tonalités exprimées sous forme de notes musicales. Les effets sonores peuvent être discrètes, continue ou effectuée en même temps que d'autres activités. Les routines liées au son sont indépendants des autres parties du Fastgraph et ne nécessitent pas de routines d'initialisation être appelés.


Sources sonores

Tous les membres du PC et PS / 2 familles peuvent produire des sons à l'aide du

8253-5 puce minuterie programmable et le haut-parleur interne. Cette méthode est limitée à produire des sons uniques de fréquences et durées données, même si nous pouvons combiner ces sons pour créer des effets audio intéressants ou jouer de la musique. Lorsque nous utilisons cette technique, nous avons aucun contrôle sur le volume sonore. En fait, les volumes sonores varient souvent légèrement sur des systèmes différents parce que les propriétés physiques du haut-parleur et son logement ne sont pas toujours les mêmes.

Les PCjr et Tandy 1000 systèmes ont une puce supplémentaire, plus puissant

pour produire des sons. Ceci est la puce sonore Texas Instruments SN76496A, appelé la puce sonore TI pour faire court. La puce sonore TI dispose de trois canaux vocaux indépendants pour produire des sons purs, et un quatrième canal pour générer du bruit périodique ou blanc. Chaque canal vocal a un contrôle de volume séparé qui nous permet de contrôler le volume du son qu'il émet.


synchrone son

Un effet sonore est dit synchrone si elle est produite alors qu'aucun autre

l'activité est en cours. En d'autres termes, un programme émet un son synchrone en démarrant le son, l'attente pendant une durée déterminée, puis arrêter le son. Le programme doit attendre le son pour terminer avant de faire quoi que ce soit d'autre. Tant que la durée est relativement courte, du fait que le son est synchrone a peu ou pas d'effet sur la vitesse d'exécution du programme. Fastgraph comprend des routines pour la production de son synchrone en utilisant soit le 8253-5 minuterie programmable ou la puce sonore TI.

La routine fg_sound utilise la minuterie programmable pour produire un son d'une

compte tenu de la fréquence et la durée. La fréquence, définie par le premier argument, est exprimée en Hertz et doit être un entier compris entre 18 et 32.767. Le deuxième argument définit la durée et est exprimée en ticks d'horloge; Là

Chapitre 15: Effets sonores 331


sont 18,2 horloge par seconde. Si la durée est nulle ou négative, le son continuera jusqu'à ce qu'il soit arrêté avec fg_quiet.

Exemple 15-1 utilise fg_sound pour créer différents effets sonores, une pause pour

une seconde entre chaque. Il se produit d'abord trois sons distincts de 20, 100 et 1000 Hertz. Chacun de ces sons dure environ 1/6 d'une seconde (trois coups d'horloge). Le programme fait alors un bruit gazouillant en alternant rapidement des sons de fréquences similaires. Enfin, le programme crée un ton glissement de fréquences croissantes entre 100 et 500 Hertz. Chaque tonalité dans cette séquence dure deux tops d'horloge, donc il faut environ 4,5 secondes pour jouer toute la séquence. Dans tous les cas, l'exemple 15-1 affiche un message identifiant juste avant chaque son.

Exemple 15-1.
#include <fastgraf.h>
             #include <stdio.h>
            void main (void);
void main ()
             {
               int freq;
fg_initpm ();
               printf ( "20 Hz ton ... \ n");
               fg_sound (20.3);
               fg_waitfor (18);
printf ( "100 Hz ton ... \ n");
               fg_sound (100,3);
               fg_waitfor (18);
printf ( "1000 Hz ton ... \ n");
               fg_sound (1000,3);
               fg_waitfor (18);
printf ( "ramage ... \ n");
               fg_sound (400,1);
               fg_sound (410,1);
               fg_sound (400,1);
               fg_sound (410,1);
               fg_waitfor (18);
printf ( "tonalité de glissement 100-500 Hz ... \ n");
               pour (freq = 100; freq <= 500; freq + = 10)
                  fg_sound (fréq, 2);
             }


La routine de fg_voice est analogue à fg_sound, mais il utilise le son TI

puce plutôt que la minuterie programmable pour créer des sons. Pour cette raison, fg_voice ne peut être utilisé sur le PCjr ou 1000 Tandy systèmes. La puce sonore TI nous permet de contrôler le volume d'un son, et il offre également quatre canaux vocaux distincts. Ainsi, fg_voice nécessite deux arguments supplémentaires en dehors de la fréquence et de durée afin de définir le canal vocal et le volume sonore. Guide de l'utilisateur 332 Fastgraph


Le premier argument de fg_voice définit le canal vocal, comme indiqué ici:
sens de la valeur
1 voix canal # 1
                            2 voix canal # 2
                            3 voix canal # 3
                            4 voix canal n ° 4, le bruit périodique
                            5 voix canal # 4, bruit blanc

Si l'on utilise des canaux vocaux 1, 2 ou 3, le second argument définit la fréquence acoustique en Hertz, entre 18 et 32.767. Si nous utilisons un canal vocal 4, cependant, le second argument est plutôt une valeur qui représente une fréquence spécifique, comme indiqué dans ce tableau:

La valeur de la fréquence
0 512 Hertz
                                   1 1024 Hertz
                                   2 2048 Hertz

Le troisième argument définit le volume sonore. Il doit être compris entre 0 et 15, où 0 est silencieux et 15 est le plus fort. Le quatrième argument définit la durée de son horloge ticks. Comme fg_sound, il y a 18,2 horloge par seconde, et si la durée est nulle ou négative, le son continuera jusqu'à l'arrêt avec fg_quiet.

Exemple 15-2 utilise fg_voice pour créer différents effets sonores en utilisant la TI

puce sonore. Comme dans l'exemple 15-1, on fait une pause d'une seconde entre chaque. Les appels de programme premier fg_testmode pour être sûr qu'il est en cours d'exécution sur un PCjr ou Tandy 1000 système (mode vidéo 9 est disponible uniquement sur ces systèmes). Si oui, le programme utilise la voix canal # 4 pour produire un bruit périodique 2048 Hertz, suivie par un bruit blanc de la même fréquence. Les deux sons sont émis au niveau de volume maximum (15) et durent environ 1/6 d'une seconde chacune (trois coups d'horloge). Après ces bruits, par exemple 15-2 produit un son 500 Hertz du volume croissant. Dans tous les cas, le programme affiche un message identifiant juste avant chaque son.

Exemple 15-2.
#include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
            void main (void);
void main ()
             {
               le volume int;
fg_initpm ();
               if (fg_testmode (9,0) == 0) {
                  printf ( "Ce programme nécessite une PCjr ou");
                  printf ( "un système Tandy 1000 \ n.");
                   sortie (1);
                  }   
                                            Chapitre 15: Effets sonores 333


printf ( "2048 Hz bruit périodique ... \ n");
               fg_voice (4,2,15,3);
               fg_waitfor (18);
printf ( "2048 Hz bruit blanc ... \ n");
               fg_voice (5,2,15,3);
               fg_waitfor (18);
printf ( "500 Hz ton de volume croissant ... \ n");
               pour (volume = 1; volume <= 15, le volume ++) {
                  fg_voice (1500, volume, 0);
                  fg_waitfor (4);
                   }
fg_quiet ();
             }


Notez comment exemple 15-2 utilise une durée de zéro (son continu) et

fg_waitfor pour spécifier la durée pour chaque niveau de volume de la séquence de tonalités 500 Hertz. Cela provoque la transition entre les changements de volume au mieux se fondre les uns avec les autres. La routine de fg_quiet, qui arrête son continu a commencé avec fg_sound ou fg_voice, termine le son après le niveau de volume final.

Les deux fg_sound et fg_voice produisent un son unique. Nous avons vu comment

combiner des sons pour produire des effets sonores, mais les sons individuels sont encore définis numériquement - qui est, par une certaine fréquence et la durée. Il est souvent plus facile de créer des sons à partir des notes de musique, et pour cette raison Fastgraph comprend une fg_music routine qui produit ces sons. La routine fg_music utilise la minuterie programmable pour produire un son synchrone; il ne supporte pas la puce sonore TI.

La routine fg_music a un seul argument appelé la chaîne de musique,

passé par référence comme un tableau d'octets ou de chaîne de caractères. La chaîne de musique est tout simplement une séquence de longueur variable des commandes de musique, suivi d'un signe dollar ($) terminateur. commandes de musique sont résumées dans le tableau suivant.

commande sens

A travers G Jouez la note spécifiée dans l'octave actuelle.

   Peut être annexée à un caractère de note (A à G) pour faire cette note 
pointu.

. Peut être annexée à un caractère de note (A à G) ou une forte (#) pour

étendre cette note la moitié de sa longueur normale. Plusieurs points peuvent être

        utilisé, et chacun à nouveau d'étendre la note de la moitié autant que le
        l'extension précédente.

Ln Régler la longueur des notes et des pauses suivantes. La valeur de n est un

entier compris entre 1 et 64, où 1 indique une note entière, deux demi
        Attention, 4 un quart de note, et ainsi de suite. Si aucune commande de L est présent, L4
         est assumé.

Sur Définir l'octave pour les notes suivantes. La valeur de n peut être un

entier compris entre 0 et 6 pour définir une octave spécifique. Il peut également être un

Guide de l'utilisateur 334 Fastgraph


plus (+) ou moins (-) caractère pour augmenter ou diminuer la
        actuel numéro d'octave. Octave 4 contient du milieu C, et si aucune O
        commande est présente, O4 est supposé.

P Pause (repos) pendant la durée spécifiée par le plus récent L

commander.

Sn Réglez la quantité de silence entre les notes. La valeur de n est un

entier compris entre 0 et 2. Si n est 0, chaque note joue pour le plein
        délai fixé par la commande L (musique legato). Si n est égal à 1, chaque note
        joue pour 7/8 le délai fixé par la commande L (musique normale). Si n
        est 2, chaque note joue pour 3/4 le délai fixé par la commande L (musique
        staccato). Si aucune commande S est présent, S1 est supposé.

Tn Réglez le tempo de la musique (le nombre de notes trimestre par minute).

La valeur de n est un entier compris entre 32 et 255. Si aucune commande de T est
        présente, T120 est supposé.

La routine fg_music ignore tous les autres caractères de la chaîne musicale. Il ignore également des valeurs de commande en dehors de la plage autorisée, comme T20 ou O8.

Exemple 15-3 illustre certaines utilisations de fg_music. Le programme joue le

premières mesures de «Mary Had a Little Lamb", suivi de l'échelle musicale (y compris les objets tranchants) dans deux octaves, et enfin l'introduction de la Cinquième Symphonie de Beethoven. Il y a une pause d'une seconde entre chaque morceau de musique, et le programme affiche les titres avant de jouer la musique. Les caractères vides apparaissent dans les chaînes de musique pour aider à les rendre plus lisibles.

Exemple 15-3.


#include <fastgraf.h>
   #include <stdio.h>
  void main (void);
void main ()
   {
  {Fg_initpm ();
     printf ( "Mary Had a Little Lamb ... \ n");
     fg_music ( "T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC $");
     fg_waitfor (18);
printf ( "l'échelle dans deux octaves ... \ n");
     fg_music ( "L16 CC # DD # EFF # GG # AA # B O + CC # DD # EFF # GG # AA # B $");
     fg_waitfor (18);
printf ( "Cinquième Symphonie de Beethoven ... \ n");
     fg_music ( "T180 O2 L2 P L8 P GGG L2 D # L24 P L8 P L2 FFF D $");
  }   
                                            Chapitre 15: Effets sonores 335


Asynchronous sonore

Les sons émis simultanément avec d'autres activités dans un programme sont dites

asynchrone. Les routines de Fastgraph qui produisent un son asynchrone commencent juste le son et le contrôle au programme appelant retournent immédiatement. Les sons cesseront automatiquement lorsque la fin de la séquence est atteinte, et vous pouvez également suspendre ou arrêter la demande avant cette date. Aucun des routines sonores asynchrones de Fastgraph aucun effet s'il y a déjà un son asynchrone en cours. En outre, les routines sonores asynchrones désactiver temporairement les routines sonores synchrones (fg_sound, fg_voice et fg_music) tandis que le son asynchrone est en cours.

Pour élargir la gamme d'effets sonores et de jouer de la musique à tempo rapide,

Fastgraph quadruple temporairement le taux d'interruption de tic d'horloge de 18,2 à 72,8 tiques par seconde, tout en produisant un son asynchrone. Parce que de nombreux contrôleurs de disques comptent sur le 18.2 tick par seconde fréquence d'horloge pour synchroniser les accès disque, vos programmes ne doivent pas effectuer toutes les opérations de disque lorsque le son asynchrone est en cours.

La routine de fg_sounds est la version asynchrone de fg_sound.  Il utilise

la minuterie programmable pour lire une séquence de tonalités simultanées à d'autres opérations. Cette routine attend comme premier argument un entier de tableau de longueur variable, passée par référence, contenant des paires de valeurs de fréquence et de durée. Comme fg_sound, chaque fréquence est exprimée en Hertz et doit être comprise entre 18 et 32.767. Les durées sont également mesurées en tops d'horloge, mais parce que le taux d'interruption est quadruplé, il y a 72,8 au lieu de 18,2 tiques par seconde.

Le format de la fréquence et de la durée tableau passé à fg_sounds est

montré ici:


[0] fréquence du son 1
[1] durée de son 1
[2] fréquence du son 2
[3] durée de son 2
 .
                                          .
                                          .
[2n-2] fréquence du son n
[2n-1] durée de son n
[2n] terminaison (0)


A noter que le caractère nul (soit un octet nul) se termine à la matrice. Le deuxième argument passé à fg_sounds est une valeur entière indiquant le nombre de fois pour faire défiler la fréquence et la durée tableau. Si cette valeur est négative, les sons vont continuer jusqu'à l'arrêt avec fg_hush ou fg_hushnext. Guide de l'utilisateur 336 Fastgraph


Exemple 15-4 utilise fg_sounds pour jouer la tonalité 100 à 500 Hertz coulissant

la séquence de l'exemple 15-1. Pour prouver les sons sont faits en même temps que d'autres opérations, les messages sont affichés pendant la séquence de lecture. Ceci est contrôlé par la fg_playing routine Fastgraph, qui retourne une valeur de 1 si les sons asynchrones sont en cours, et 0 sinon. Notez comment la durée doit être spécifiée comme 8 ticks horloge (au lieu de 2 comme dans l'exemple 15-1) pour compenser le taux d'interruption horloge tique quadruplée.

Exemple 15-4.
#include <fastgraf.h>
                #include <stdio.h>
               void main (void);
void main ()
                {
                   int i;
                  int freq;
                  int sound_array [83];
i = 0;
                  pour (freq = 100; freq <= 500; freq + = 10) {
                     sound_array [i ++] = freq;
                     sound_array [i ++] = 8;
                      }
                  sound_array [i] = 0;
fg_initpm ();
                  fg_sounds (sound_array, 1);
tandis que (fg_playing ())
                     printf ( "jouer encore ... \ n");
                }


Tout comme fg_sounds est analogue à fg_sound, il y a une routine Fastgraph

fg_voices qui est semblable à fg_voice. Autrement dit, fg_voices utilise la puce sonore TI pour jouer une séquence asynchrone de tonalités. Ses arguments sont les mêmes que ceux de fg_sounds, mais la structure de la matrice solide est différent. Sa structure est:


[0] canal # 1 du son
[1] fréquence du son 1
[2] volume du son 1
[3] durée de son 1
 .
                                          .
                                          .
[4n-4] canal # de son n   
                                            Chapitre 15: Effets sonores 337


[4n-3] fréquence du son n
[4n-2] volume du son n
[4n-1] durée de son n
[4n] terminaison (0)


Les numéros de canaux, les fréquences, les volumes et les durées doivent être dans les mêmes plages comme indiqué dans la description de fg_voice, sauf les durées sont quadruplés en raison du taux d'interruption horloge tique accélérée. Encore une fois, notez que le caractère nul (qui est, un octet nul) met fin à la matrice.

Exemple 15-5 utilise fg_voices pour jouer la séquence de 500 Hertz de ton de

augmentation du volume introduit dans l'exemple 15-2. Comme dans l'exemple 15-4, le programme affiche des messages pendant la séquence de sons est en cours de lecture pour démontrer les sons sont en cours en même temps que d'autres opérations. Notez comment la durée est maintenant 16 coups d'horloge (au lieu de 4 comme dans l'exemple 15-2) en raison du taux d'interruption horloge tique quadruplée.

Exemple 15-5.
#include <fastgraf.h>
           #include <stdio.h>
          void main (void);
void main ()
           {
             int voice_array [61];
              int i;
             le volume int;
fg_initpm ();
             if (fg_testmode (9,0) == 0) {
                printf ( "Ce programme nécessite une PCjr ou");
                printf ( "un système Tandy 1000 \ n.");
                 sortie (1);
                 }
i = 0;
             pour (volume = 1; volume <= 15, le volume ++) {
                voice_array [i ++] = 1; / * L'utilisation du canal 1 * /
                voice_array [i ++] = 500; / * 500 Hz de fréquence * /
                voice_array [i ++] = volume; / * Volume variable * /
                voice_array [i ++] = 16; / * Durée * /
                 }
             voice_array [i] = 0;
fg_voices (voice_array, 1);
tandis que (fg_playing ())
                printf ( "jouer encore ... \ n");
          }   

Guide de l'utilisateur 338 Fastgraph


Il existe également une version asynchrone de fg_music.  On l'appelle

fg_musicb, et il utilise la même chaîne format de musique comme fg_music fait. Cependant, fg_musicb a un second argument qui spécifie le nombre de fois pour faire défiler la chaîne de musique. Si cette valeur est négative, la musique jouera répétitivement jusqu'à ce que vous arrêtiez avec fg_hush ou fg_hushnext.

Exemple 15-6 joue les mêmes trois morceaux de musique que l'exemple 15-3, mais il

le fait en même temps que d'autres opérations. Alors que la musique joue, le programme affiche en permanence le titre de chaque morceau. Notez la façon dont nous pouvons tirer profit de la répétition dans la chaîne de musique pour la séquence "jusqu'à l'échelle" en jouant la séquence deux fois.

Exemple 15-6.
#include <fastgraf.h>
  #include <stdio.h>
 void main (void);
void main ()
  {
    fg_initpm ();
    fg_musicb ( "T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC $", 1);
    tandis que (fg_playing ())
       printf ( "Mary Had a Little Lamb ... \ n");
    fg_waitfor (18);
fg_musicb ( "L16 CC # DD # EFF # GG # AA # B O + $", 2);
    tandis que (fg_playing ())
       printf ( "l'échelle dans deux octaves ... \ n");
    fg_waitfor (18);
fg_musicb ( "T180 O2 L2 P L8 P GGG L2 D # L24 P L8 P L2 D FFF $", 1);
    tandis que (fg_playing ())
       printf ( "Cinquième Symphonie de Beethoven ... \ n");
  }


L'exemple suivant montre les effets des routines Fastgraph

fg_hush et fg_hushnext, qui arrêtent les sons ont commencé avec fg_sounds, fg_voices ou fg_musicb. La routine fg_hush arrête immédiatement son asynchrone, tandis que fg_hushnext le fait quand le cycle actuel se termine. Ni routine a des arguments, et ni la routine n'a aucun effet si aucun son asynchrone est en cours. En outre, notez que fg_hushnext n'a aucun effet à moins que le son asynchrone est continue.

Exemple 15-7 fonctionne dans un mode vidéo texte ou des graphiques.  Il affiche

rectangles jusqu'à 16 couleurs tout en jouant de la musique asynchrone continue. Le programme vérifie périodiquement les frappes avec fg_intkey, et il continue de jouer la musique alors qu'il n'y a pas d'activité de clavier. Si vous appuyez sur la touche Echap, le programme fg_hush utilise pour arrêter la musique immédiatement; ce qui provoque une sortie de la boucle while. Si vous appuyez sur une autre touche, le programme fg_hushnext utilise pour arrêter la musique dès que la répétition en cours se termine. Une fois que cela se produit, le programme sort de la boucle de temps parce que fg_playing retournera une valeur de zéro.

Chapitre 15: Effets sonores 339


Exemple 15-7.
#include <fastgraf.h>
    void main (void);
#define ESC 27
void main ()
     {
       Couleur int;
       int old_mode;
       unsigned clé de char, aux;
fg_initpm ();
       fg_getmode old_mode = ();
       fg_setmode (fg_automode ());
       color = 0;
fg_musicb ( "O4 L16 CC # DD # EFF # GG # AA # B O + CC # DD # EFF # GG # AA # B $", - 1);
tandis que (fg_playing ())
        {
          color = (couleur + 1) et 15;
          fg_setcolor (couleur);
          fg_rect (0, fg_getmaxx (), 0, fg_getmaxy ());
fg_waitfor (4);
          fg_intkey (touche &, & aux);
          si (== touche ESC)
             fg_hush ();
          else if (+ aux clés! = 0)
             fg_hushnext ();
        }
fg_setmode (old_mode);
       fg_reset ();
     }


Exemple 15-7 montre également un effet secondaire important de la fg_musicb lorsque

jouer de la musique en continu. Toute longueur, octave, le silence, ou des valeurs de tempo changé au sein de la chaîne ne sont pas réinitialisés à leurs valeurs initiales au début de chaque répétition. Si nous n'avons pas inclus la commande O4 au début de la chaîne, la commande ultérieurement O + causerait la musique à jouer dans octaves 4 et 5 au cours de la première répétition, 5 et 6 au cours de la seconde répétition, et l'octave 6 pour toutes les répétitions ultérieures (parce que vous ne pouvez pas augmenter le nombre d'octave au-dessus 6).

Les deux dernières routines relatives à son asynchrone sont fg_resume et

fg_suspend. La fg_suspend routine musique suspend précédemment commencé par fg_musicb, tandis que fg_resume redémarre la musique à partir du point où il a été suspendu. Exemple 15-8 joue les premières mesures de "Mary Had a Little Lamb". Si vous appuyez sur une touche alors que le morceau est joué, il arrête. Puis, après une autre touche, la musique reprend et se poursuit jusqu'à fini. Guide de 340 Fastgraph utilisateur

Exemple 15-8.
#include <fastgraf.h>
  #include <stdio.h>
 void main (void);
void main ()
  {
    fg_initpm ();
    fg_musicb ( "T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC $", 1);
    fg_waitkey ();
fg_suspend ();
    printf ( "Musique suspendu Appuyez sur une touche pour reprendre \ n..");
    fg_waitkey ();
fg_resume ();
    printf ( "Music reprend \ n.");
    tandis que (fg_playing ());
    printf ( "Musique terminée. \ n");
  }


La routine de fg_suspend n'a aucun effet s'il n'y a pas de musique asynchrone en cours. De même, fg_resume n'a pas d'effet s'il n'y a pas de musique suspendue. Si vous appelez fg_suspend puis besoin d'annuler la musique ou de sortie DOS au lieu de redémarrer la musique, appelez fg_hush au lieu de fg_resume.


Résumé des Routines sonores

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

FG_HUSH arrête immédiatement son asynchrone a commencé avec fg_sounds,

fg_voices ou fg_musicb.

FG_HUSHNEXT est similaire à fg_hush, mais il ne se limite pas asynchrone

sonner jusqu'à ce que la répétition en cours se termine.

FG_MUSIC utilise la minuterie programmable pour jouer une séquence de tonalités musicales.

FG_MUSICB est la version asynchrone de fg_music. Il utilise le

minuterie programmable pour lire une séquence de tonalités musicales, simultanément avec d'autres activités.

FG_PLAYING détermine si oui ou non il y a un son asynchrone

la progression.

FG_QUIET arrête son synchrone continu a commencé avec fg_sound ou

fg_voice.

FG_RESUME redémarre la musique asynchrone précédemment suspendu par fg_suspend. 
                                            Chapitre 15: Effets sonores 341


FG_SOUND produit un son d'une fréquence spécifiée et la durée en utilisant la

minuterie programmable.

FG_SOUNDS est la version asynchrone de fg_sound. Il peut jouer une série

des tons de fréquences et des durées déterminées, simultanées avec d'autres activités.

FG_SUSPEND suspend la musique asynchrone précédemment lancée par fg_musicb.
FG_VOICE produit un son d'une fréquence, la durée et le volume spécifié

en utilisant l'un des quatre canaux vocaux de la puce sonore TI.

FG_VOICES est la version asynchrone de fg_voice. Il peut jouer une série

des tons de fréquences spécifiées, les durées et les volumes, simultanées avec d'autres activités. Guide de l'utilisateur 342 Fastgraph



Chapitre 16


Guide de synchronisation du programme 344 Fastgraph utilisateur


aperçu

Il est parfois nécessaire de retarder l'exécution d'un programme pour une brève

période, ou de déterminer combien de temps il faut pour exécuter des sections spécifiques d'un programme. Fastgraph comprend des routines pour accomplir ces tâches. Certains de ces routines sont dit être en temps réel, ce qui signifie qu'ils sont indépendants de la vitesse du processeur d'un système, alors que la vitesse des autres est spécifique au processeur. Ce chapitre décrit les deux classes de routines de cadencement, qui sont tous indépendamment des autres parties de Fastgraph.


Real-Time Routines

En temps réel des opérations de centre autour de l'heure du jour l'horloge du BIOS, qui est

rien de plus qu'un compteur qui incrémente automatiquement le système 18.2 fois par seconde. Ce nombre est souvent appelé le taux d'interruption horloge tique car une routine d'interruption effectue l'incrémentation. En outre, chaque incrément est généralement appelé un coup d'horloge.

La routine Fastgraph fg_waitfor retarde l'exécution d'un programme par le

nombre de tops d'horloge spécifié comme argument. Parce que fg_waitfor utilise des tops d'horloge, la longueur réelle du retard est le même, quelle que soit la vitesse du processeur du système. Même lorsque les routines sonores asynchrones de Fastgraph quadrupler le taux d'interruption horloge tique, Fastgraph compense cette intérieurement de façon fg_waitfor fonctionne toujours comme si le taux réel était encore 18,2 fois par seconde.

Exemple 16-1 affiche un message toutes les cinq secondes qui stipule combien de temps

le programme a été en cours d'exécution. La routine de fg_waitfor produit le délai de cinq secondes en arrêtant 91 (18,2 fois 5) coups d'horloge avant que le programme affiche chaque message. Le programme retourne au DOS lorsque vous appuyez sur une touche.

Exemple 16-1.
#include <fastgraf.h>
             #include <stdio.h>
            void main (void);
void main ()
             {
               secondes unsigned int;
               unsigned clé de char, aux;
fg_initpm ();
               secondes = 0;
                faire {
                  fg_waitfor (91);
                  secondes + = 5;
                  printf ( "% u secondes se sont écoulées. \ n", secondes);
                  fg_intkey (touche &, & aux);
                }
               tandis que (touche + aux == 0);
            }   
                                           Chapitre 16: Timing du programme 345


Une autre application commune de fg_waitfor est de ralentir une boucle qui utilise

fg_intkey pour vérifier les frappes. Dans les boucles qui ne font guère d'autre, nous pouvons appeler fg_intkey trop rapidement sans ce retard, et il est alors possible que le BIOS peut ne pas être en mesure de stocker les caractères dans sa mémoire tampon de clavier assez vite. Un petit retard, même un coup d'horloge, permet souvent de telles boucles "serrés".

La routine fg_getclock fournit un moyen efficace pour mesurer le temps,

en particulier les différences dans le temps. Cette routine n'a pas d'arguments et retourne un entier non signé 32 bits (comme sa valeur de fonction) représentant le nombre d'impulsions d'horloge depuis minuit. Exemple 16-2 montre fg_getclock. En réponse à une combinaison de touches (sauf Escape, qui retourne le contrôle au DOS), le programme affiche le nombre d'impulsions d'horloge à partir de minuit, et le nombre de tiques depuis le début du programme.

Exemple 16-2.
#include <fastgraf.h>
     #include <stdio.h>
    void main (void);
#define ESC 27
void main ()
     {
       démarrage long non signé, les tiques;
       unsigned clé de char, aux;
fg_initpm ();
       start = fg_getclock ();
        faire {
          ticks = fg_getclock ();
          printf ( "% ld ticks depuis minuit. \ n", tiques);
          printf ( "% lu ticks depuis le début du programme \ n \ n.", ticks-start);
          fg_getkey (touche &, & aux);
        }
       while (key = ESC!);
     }


Routines dépendant de la vitesse du système

La routine de fg_waitfor décrit dans la section précédente est indépendante

de la vitesse du processeur du système. Cela signifie que la longueur effective de son retard est la même sur tout système. Une autre routine fg_stall est semblable à fg_waitfor, mais son retard est proportionnel à la vitesse du processeur. Comme fg_waitfor, fg_stall a un seul argument entier qui spécifie la longueur du délai. Cependant, au lieu d'être exprimée en coups d'horloge, fg_stall mesure le retard en unités de retard. Les gâteries de routine fg_stall la longueur comme une quantité non signée, de sorte que dans les modes 16 bits le nombre maximum d'unités de retard, nous pouvons spécifier est 65.535. Le tableau suivant indique le nombre approximatif d'unités de retard par horloge tique sur trois systèmes typiques. Guide de l'utilisateur 346 Fastgraph


unités de retard du système
                     type par impulsion d'horloge
Tandy 1000 HX 280
                 25 MHz 80386 3400
                 40 MHz 80386 7100
Fastgraph comprend une routine qui détermine le nombre d'unités de retard

par horloge cocher pour le processeur utilisé. Ceci est la routine de fg_measure, qui n'a pas d'arguments et renvoie le nombre d'unités de retard par impulsion d'horloge comme valeur de fonction. Une fois que nous déterminons cette valeur, nous pouvons utiliser fg_stall pour retarder l'exécution d'un programme en temps réel. Ceci permet d'obtenir un délai beaucoup plus raffiné que l'unité horloge tique utilisée par fg_waitfor.

Exemple 16-3 est fonctionnellement identique à l'exemple 16-1, mais il utilise

fg_stall au lieu de fg_waitfor pour retarder l'exécution du programme. Les appels de programme fg_measure premier pour déterminer le nombre d'unités de retard équivalant à un coup d'horloge. Il passe ensuite cette valeur à fg_stall, appelée 91 fois à l'intérieur de la boucle pour créer le délai de cinq secondes (parce que 91 coups d'horloge est égale à cinq secondes). Le programme retourne au DOS lorsque vous appuyez sur une touche.

Exemple 16-3.
#include <fastgraf.h>
             #include <stdio.h>
            void main (void);
void main ()
             {
                int i;
               int units_per_tick;
               secondes unsigned int;
               unsigned clé de char, aux;
fg_initpm ();
               secondes = 0;
               printf ( "Benchmarking de la vitesse du système ... \ n");
               fg_measure units_per_tick = ();
               printf ( "Benchmark terminée \ n \ n.");
faire {
                  for (i = 0; i <91; i ++)
                     fg_stall (units_per_tick);
                  secondes + = 5;
                  printf ( "% u secondes se sont écoulées. \ n", secondes);
                  fg_intkey (touche &, & aux);
                }
               tandis que (touche + aux == 0);
             }


Un dernier point: fg_measure prend quelques secondes pour le système de référence

accélérer avec précision. Pour cette raison, vous ne devriez appeler fg_measure fois (généralement au début du programme) et utiliser sa valeur de retour au lieu d'appeler fg_measure tout au long du programme.

Chapitre 16: Timing du programme 347


Résumé des Routines Timing

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

FG_GETCLOCK renvoie le nombre de tops d'horloge depuis minuit comme

valeur de la fonction. Cette quantité est un entier non signé sur 32 bits.

FG_MEASURE renvoie le nombre approximatif d'unités de retard par impulsion d'horloge

comme valeur de fonction. Cette quantité est proportionnelle à la vitesse du processeur du système.

FG_STALL retarde l'exécution d'un programme pour un nombre donné de processor-

unités de retard spécifiques.

FG_WAITFOR retarde l'exécution d'un programme pour un nombre donné d'horloge

tiques. Il y a 18,2 horloge par seconde, quelle que soit la vitesse du processeur du système. Guide de l'utilisateur 348 Fastgraph



chapitre 17


Divers Routines 350 Guide de l'utilisateur Fastgraph


aperçu

Il y a encore quelques routines Fastgraph qui vraiment ne rentrent pas dans

aucune des catégories examinées jusqu'à présent. Pour cette raison, nous allons les décrire séparément dans ce chapitre.


Détermination de la mémoire disponible

La routine fg_memavail renvoie la quantité de mémoire conventionnelle libre

(En octets) disponible pour DOS. Il renvoie la quantité de mémoire que sa valeur de fonction, qui est un entier non signé 32 bits, et il n'a pas d'arguments.

Exemple 17-1 utilise fg_memavail pour montrer les effets de la création et

libérer des pages virtuelles. Lorsqu'il est exécuté dans un mode vidéo dans lequel les pages vidéo 1 et 2 sont des pages physiques, la quantité de mémoire libre reste le même parce que ces pages utilisent de la mémoire qui réside sur la carte vidéo. Cependant, dans les modes où les pages 1 et 2 sont des pages virtuelles, la quantité de mémoire libre diminue après chaque appel à fg_allocate et retourne à sa valeur d'origine après les appels à fg_freepage. Notez comment les demandes de programme et valide le mode vidéo.

Exemple 17-1.
#include <fastgraf.h>
      #include <stdio.h>
      #include <stdlib.h>
     void main (void);
void main ()
      {
        original long, mem0, mem1, mem2;
        int mode, old_mode;
printf ( "mode vidéo qui?");
        scanf ( "% d", et le mode);
fg_initpm ();
        if (fg_testmode (mode 0) == 0) {
           printf ( "Votre système ne prend pas en charge ce mode vidéo. \ n");
            sortie (1);
            }
        if (fg_testmode (mode 3) == 0) {
           printf ( "Votre système ne dispose pas de suffisamment de mémoire. \ n");
            sortie (1);
            }
originale = fg_memavail ();
        fg_getmode old_mode = ();
        fg_setmode (mode);
        mem0 = fg_memavail ();
        fg_allocate (1);
        mem1 = fg_memavail ();
        fg_allocate (2);
        mem2 = fg_memavail (); 
                                   Chapitre 17: Divers Routines 351


fg_freepage (1);
        fg_freepage (2);
        fg_setmode (old_mode);
        fg_reset ();
printf ( "origine =% ld \ n", original);
        printf ( "après setmode =% ld \ n", mem0);
        printf ( "après la 1ère page =% ld \ n", mem1);
        printf ( "après la 2ème page =% ld \ n", mem2);
        printf ( "à la fin =% ld \ n", memavail ());
      }


Choisir la fonction Mise à jour vidéo Mémoire

Dans le chapitre 12, nous avons vu comment utiliser la routine fg_setfunc pour effectuer XOR

animation en mode EGA et VGA graphiques natifs (modes 13 à 18). Dans ces modes vidéo, fg_setfunc commande l'opération logique appliquée lorsque le contenu de la modification de la mémoire vidéo. L'opération spécifique est définie par son argument, comme indiqué ici:

valeur logique
                               opération d'argument
0 remplacement
                                  1 et
                                  2 ou
                                  3 ou exclusif

Si un programme ne remet pas fg_setfunc, le mode de remplacement est toujours utilisé. Autrement dit, l'information écrite à la mémoire vidéo remplace tout ce qui était là avant. La routine de fg_setfunc applique uniquement à la mémoire vidéo, même si un tampon virtuel est actif, et n'a de sens que dans les modes graphiques EGA, VGA, SVGA et 16 couleurs.

Exemple 17-2 montre la routine de fg_setfunc. Le programme est similaire

à l'exemple 6-11, qui affiche 200 rectangles aléatoires sur l'écran. Cependant, l'exemple 17-2 montre les rectangles en mode XOR, ce qui rend les intersections du rectangle apparaissent dans des couleurs différentes.

Exemple 17-2.
#include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
           void main (void);
#define RECTANGLES 200
           #define SWAP (a, b, temp) {temp = a;  a = b; b = température;  }
void main ()
            {
               int i;
              int minx, maxx, Miny, maxy; 

Guide de l'utilisateur 352 Fastgraph


int old_mode;
              int température;
              xres int, yres;
fg_initpm ();
              if (fg_egacheck () == 0) {
                 printf ( "Ce programme nécessite EGA ou VGA. \ n");
                  sortie (1);
                  }
fg_getmode old_mode = ();
              fg_setmode (fg_automode ());
              fg_setfunc (3);
xres = fg_getmaxx () + 1;
              yres = fg_getmaxy () + 1;
for (i = 0; i <RECTANGLES; i ++) {
                 minx = rand ()% xres;
                 maxx = rand ()% xres;
                 Miny = rand ()% yres;
                 maxy = rand ()% yres;
                 if (minx> maxx)
                    SWAP (minx, maxx, temp);
                 if (Miny> maxy)
                    SWAP (Miny, Maxy, temp);
                 fg_setcolor (rand ()% 16);
                 fg_rect (minx, maxx, Miny, maxy);
                  }
fg_setmode (old_mode);
              fg_reset ();
            }


Contrôle vertical Retrace Synchronisation

Le retour vertical est la brève période où le faisceau d'électrons du moniteur

voyages à partir du bas de l'écran vers le coin supérieur gauche pour commencer un nouveau cycle de rafraîchissement d'affichage. En fonction du moniteur, le retour de balayage vertical se produit typiquement entre 50 et 60 fois par seconde.

Certaines opérations graphiques doivent être effectuées lors d'un retour vertical

intervalle pour éviter le scintillement de l'écran potentiel ou de la neige. Ceux-ci incluent un changement de page, le panoramique, et la lecture ou l'écriture d'un bloc de vidéo registres du CAD ou palettes. Par défaut, les routines de Fastgraph qui effectuent ces opérations fournissent automatiquement la synchronisation de retour vertical nécessaire. Dans la plupart des applications, ces contrôles de retour de balayage vertical sont tout à fait suffisant. Il y a des moments, cependant, lorsque vous pouvez désactiver la vérification verticale de retour de Fastgraph et effectuer la synchronisation de retour vertical au niveau de l'application.

Tel est l'objet de la routine de fg_waitvr de Fastgraph. Pour désactiver tous les

synchronisation de retour vertical interne au sein de Fastgraph, appelez fg_waitvr avec un argument zéro. Si vous voulez réactiver, passer une valeur non nulle

Chapitre 17: Divers Routines 353


fg_waitvr (notez que cela est l'état par défaut). Les routines Fastgraph pertinentes du retour vertical sont fg_getdacs, fg_palettes, fg_pan, fg_setdacs et fg_setvpage; et dans les modes 256 couleurs, fg_getrgb, fg_palette et fg_setrgb. Le retour vertical est également applicable aux routines de Fastgraph pour l'affichage ou la création de PCX, GIF, ou des fichiers en flic modes graphiques 16 couleurs et 256 couleurs lorsque les valeurs de la palette ou du CAD sont manipulés.

A titre d'exemple des raisons pour lesquelles vous pourriez vouloir faire désactiver Fastgraph de vertical

commandes revenir, envisager un changement de page. Après fg_setvpage définit l'adresse de début d'affichage pour la nouvelle page visuelle, il attend un intervalle de retour vertical de sorte que la nouvelle adresse de départ peut prendre effet. Si fg_setvpage ne le faisait pas, graphiques affichés avant le prochain retour vertical seraient parfois apparaître sur l'écran avant de l'ancienne page visuelle est complètement enlevé. Supposons, cependant, que, immédiatement après la page bascule vous avez fait des calculs ou d'autres travaux qui ne touchent l'affichage vidéo. Si vous désactivez la synchronisation de retour vertical de Fastgraph, vous pourriez obtenir un taux de trame plus rapide parce que vous pouvez effectuer les calculs post-Page-bascules alors que le système est normalement en attente pour le retour vertical. Selon l'ampleur de ces calculs, vous pouvez constater qu'il est même pas nécessaire d'attendre le retour vertical suivant une page flip.


Commutation Banque SVGA externe

L'une des caractéristiques les plus importantes qui se produit au cours de la SVGA de Fastgraph

l'initialisation du noyau est la configuration des fonctions bancaires de commutation spécifiques chipset. Lorsqu'un commutateur bancaire est nécessaire, la routine actuelle Fastgraph effectue le commutateur de banque par des points d'entrée pré-définis dans le noyau SVGA. Cela supprime les détails de bas niveau de savoir quand et comment la banque commutateur à partir du code de haut niveau d'une application.

Si vous avez une application qui effectue une partie ou la totalité de ses graphiques SVGA

à l'extérieur de Fastgraph, vous pouvez toujours utiliser une vaste autodetection SVGA chipset Fastgraph et les fonctions bancaires de commutation. Après l'initialisation avec succès le noyau SVGA avec fg_svgainit et l'établissement d'un mode vidéo graphique SVGA, les numéros de banque lecture et d'écriture seront mis à zéro. Lorsque vous avez besoin de changer de banque SVGA, appelez les fg_setbanks de routine; ses deux arguments spécifient la nouvelle lecture et d'écriture des numéros de banque. Notez que fg_setbanks ne vous dit pas quand effectuer un commutateur de banque, il gère simplement les détails de la façon de le faire. Une routine complémentaire, fg_getbanks, retourne lecture actuelle du noyau SVGA et écrire les numéros de banque.


Sauvegarde et restauration de l'État Vidéo

Si vous appelez routines Fastgraph à partir d'une routine de service d'interruption (ISR) dans

un mode VGA, XVGA ou SVGA graphiques, l'ISR est responsable de la sauvegarde et la restauration de l'état de VGA. Ceci est nécessaire car une interruption peut se produire lors de l'exécution d'autres opérations graphiques, et les routines Fastgraph appelées à partir de l'ISR sera presque certainement changer l'état VGA. Lorsque le contrôle revient au point d'interruption, le VGA sera probablement dans un état différent de celui attendu.

La routine fg_vgastate enregistre et restaure les registres VGA qui

Fastgraph prévoit être dans des états spécifiques. Ces registres sont: Guide de l'utilisateur 354 Fastgraph


* Indice Contrôleur graphique
   * Contrôleur graphique enregistre 0-8
   * Sequence index Controller
   * Sequence Controller registre 2

Pour enregistrer l'état de ces registres, appelez fg_vgastate (0). Pour les rendre à leurs valeurs précédemment enregistrées, appelez fg_vgastate (1). Si vous demandez une fg_vgastate opération de sauvegarde avant d'effectuer une opération de restauration, rien ne se passe. La routine de fg_vgastate n'a de sens que dans les modes vidéo numérotés 13 et ci-dessus lors de l'exécution sur un VGA ou SVGA système.

Si vous avez besoin pour sauvegarder et restaurer l'état du VGA en mode graphique SVGA,

vous devez utiliser fg_vgastate pour préserver les registres VGA ainsi fg_getbanks et fg_setbanks (décrit dans la section précédente) pour préserver les numéros de banque de SVGA.


Résumé des Routines Divers

Cette section résume les descriptions fonctionnelles du Fastgraph

routines présentées dans ce chapitre. Des informations plus détaillées sur ces routines, y compris leurs arguments et les valeurs de retour, peut être trouvée dans le manuel de référence Fastgraph.

FG_GETBANKS renvoie le SVGA courant lire et écrire les numéros de banque.  Ces

les valeurs seront correctes que si elle est définie par le noyau SVGA, ou avec fg_setbanks.

FG_MEMAVAIL renvoie la quantité de mémoire disponible pour DOS.

FG_SETBANKS définit le SVGA lire et écrire les numéros de banque. Cette routine est

généralement pas appelé dans une application, mais il est prévu comme une interface de haut niveau pour le noyau de SVGA Fastgraph.

FG_SETFUNC spécifie l'opération logique (remplacement ou, et,

ou exclusif) appliqué lorsque la mémoire vidéo change dans les modes graphiques EGA, VGA, SVGA et 16 couleurs. Cette routine n'a pas d'effet dans d'autres modes vidéo et ne concerne pas les informations écrites sur les tampons virtuels.

FG_VGASTATE enregistre ou restaure l'état du contrôleur graphique VGA

et les registres du contrôleur de séquence utilisés par Fastgraph.

FG_WAITVR désactive ou active la synchronisation de retour vertical au sein

Fastgraph.



Annexe A


Fastgraph Utilities 356 Guide de l'utilisateur Fastgraph


aperçu

Cette annexe décrit les programmes utilitaires fournis avec Fastgraph.  Par

par défaut, la procédure d'installation Fastgraph place ces utilitaires dans le répertoire \ FG. Pour utiliser ces utilitaires, vous devez soit (1) copier le fichier EXE de \ FG à votre répertoire courant, (2) faire \ FG votre répertoire courant, ou (3) inclure le répertoire \ FG dans votre spécification de chemin DOS.


INSTANTANÉ Utility

L'utilitaire INSTANTANÉ est un fin et rester programme résident (TSR) à

capturer des images graphiques. Il stocke l'image dans la norme pixel run (SPR) format Fastgraph. Pour charger INSTANTANÉ, il suffit d'entrer la commande INSTANTANÉ à l'invite DOS, et vous verrez des messages similaires aux cas INSTANTANÉ charges suivantes avec succès.


C> INSTANTANÉ
INSTANTANÉ Version 1.04
       Copyright (c) 1993 Ted Gruber Software.  Tous les droits sont réservés.
Appuyez sur <alt> - <shift gauche> pour l'activer.


Après des charges INSTANTANÉ, la commande revient à l'invite DOS.  À ce point,

vous pouvez utiliser tout procédé que ce soit pour afficher une image graphique et puis appuyez sur les touches Alt et Maj gauche en même temps pour capturer l'image. Vous ne devez pas charger INSTANTANÉ pour chaque capture d'image, une seule fois par le démarrage du système. INSTANTANÉ utilise environ 24.000 octets de mémoire conventionnelle, une fois chargés.

Pour illustrer l'utilisation de INSTANTANÉ, supposons que vous avez dessiné et sauvegardé un

image avec un programme de peinture commerciale, et que vous voulez incorporer cette image dans une application Fastgraph. Une fois que vous chargez INSTANTANÉ, démarrez le programme de peinture et de récupérer votre image. Ensuite, appuyez sur les touches Alt et Maj gauche simultanément et attendez la tonalité de réussite (trois sons de pente moyenne rapide). Enfin, quittez le programme de peinture pour revenir à l'invite DOS.

La séquence décrite dans le paragraphe précédent va stocker le capturé

l'image au format pixel de fonctionnement standard de Fastgraph, dans un fichier nommé SNAPSHOT.nnn dans le répertoire courant. Le nnn de type de fichier sera la première séquence de chiffres qui ne donnent pas lieu à un nom de fichier dupliqué. Autrement dit, s'il n'y a pas des fichiers d'images capturées dans le répertoire courant, INSTANTANÉ utilisera le nom du fichier SNAPSHOT.000. La prochaine fois que vous prenez une photo, INSTANTANÉ va stocker dans SNAPSHOT.001, puis SNAPSHOT.002, et ainsi de suite. Si vous renommez ou supprimez un de ces fichiers, INSTANTANÉ sera à nouveau utiliser ce nom de fichier. Par exemple, si vous supprimez SNAPSHOT.000 mais gardez SNAPSHOT.001, INSTANTANÉ va stocker l'image suivante il capture en SNAPSHOT.000.

Si SNAPSHOT est incapable de capturer l'image, il produira son erreur

ton (un son unique à faible pente). La cause la plus courante de cette tente de capturer une image à partir d'un texte en mode vidéo, mais il sera également se produire s'il n'y a pas assez d'espace disque ou si tous les 1000 noms de fichiers d'image sont déjà utilisés.

Annexe A: Fastgraph Utilities 357


Utilitaire CLIP

L'utilitaire INSTANTANÉ décrit dans la section précédente capture la

tout l'écran. Bien que cela puisse être souhaitable dans certains cas, d'autres fois vous aurez juste besoin d'une partie de l'écran. CLIP est un utilitaire interactif que vous pouvez utiliser pour réduire la taille d'une image stockée au format pixel d'exécution standard ou emballé de Fastgraph. La syntaxe de la commande pour appeler l'utilitaire CLIP à partir de l'invite DOS est

CLIP fichier_entrée les options output_file

où fichier_entrée est le nom du fichier d'image d'origine, et output_file est le nom du nouveau fichier image. CLIP ne modifie pas le fichier_entrée en aucune façon, mais il écrasera le output_file si un fichier portant le même nom existe dans le répertoire en cours. La liste des options spécifie un ou plusieurs commutateurs en option comme indiqué ici:

Option sens

/ M: Mode Indique le numéro de mode vidéo dans lequel pour afficher l'image. le

La valeur de mode doit être un nombre entier compris entre 0 et 29. Si ce mode vidéo
        est un mode texte, un mode graphique non pris en charge, ou un indisponible
        mode graphique, CLIP affiche un message d'erreur indiquant cela.  Si la
        / M commutateur est pas présent, CLIP utilise le premier mode vidéo disponible
        à partir de la liste 18, 16, 15, 19, 13, 9, 4, 12.

/ P Indique le fichier_entrée est au format pixel de course emballé de Fastgraph.

Si le commutateur / P est pas présent, CLIP suppose qu'il est dans la norme
        pixel Format exécuté. Output_file le sera dans le même format que le
        fichier_entrée.

/ W: largeur Indique la largeur de l'image en pixels. La valeur de largeur doit être un

entier compris entre 1 et la résolution horizontale de l'sélectionné
        mode vidéo. Si le commutateur / W est pas présent, CLIP utilise le
        la résolution horizontale du mode vidéo sélectionné.

Par exemple, si vous voulez créer le fichier image PARTIAL.PPR du SCREEN.PPR de fichier d'exécution de pixel emballé, et utiliser le 320x200 graphiques EGA mode vidéo natif (mode 13), vous commencez CLIP avec la commande suivante.

CLIP PARTIAL.PPR SCREEN.PPR / P / M: 13

Parce qu'aucun commutateur / W apparaît dans la commande ci-dessus et la résolution horizontale de mode 13 est de 320 pixels, CLIP prend la largeur de l'image est de 320 pixels.

Lorsque CLIP affiche l'image et le curseur en forme de plus-, vous êtes prêt à

définir un coin de la zone de découpage (cette partie de l'image utilisée pour créer le output_file). Pour ce faire, utilisez les touches directionnelles du clavier numérique pour déplacer le curseur à la position désirée, puis appuyez sur la touche Entrée. Vous êtes alors prêt à définir le coin opposé de la zone de découpage. Encore une fois, utilisez les touches directionnelles pour déplacer le curseur à la position désirée. Lors de la définition du deuxième coin, cependant, CLIP utilise une boîte rectangulaire au lieu du curseur en forme de plus- pour simplifier le marquage des limites de la zone de découpage. Une fois que vous appuyez sur Entrée pour définir le deuxième virage, CLIP crée le output_file et le Guide de l'utilisateur 358 Fastgraph


affiche la largeur de l'image résultante et le nombre de pixel exécute l'image contient.

CLIP inclut d'autres fonctionnalités pour aider à définir la zone de découpage.  Vous pouvez

changer la distance le curseur se déplace en réponse aux touches directionnelles, afficher les courants (x, y) les coordonnées de pixels du curseur, et changer la couleur du curseur. Le tableau suivant explique les frappes que CLIP reconnaît lorsque vous définissez la zone de découpage.

signification clé

F1 Affiche le (x, y) de coordonnées barre en haut de l'écran. Si la

coordonner bar est déjà allumé, F1 supprime.

F2 Affiche le (x, y) de coordonnées barre en bas de l'écran. Si

la barre de coordonnées est déjà allumé, F2 supprime.

F3 Transforme le curseur ou la boîte de couleur du blanc au noir, ou du noir

au blanc.

F4 Affiche un résumé des touches CLIP reconnaît lors de la définition de la

zone de découpage.

KP1 Déplace le curseur d'une unité vers le bas et vers la gauche. KP2 Déplace le curseur un vers le bas de l'unité. KP3 Déplace le curseur d'une unité vers le bas et vers la droite. KP4 Déplace le curseur d'une unité vers la gauche. KP6 Déplace le curseur d'une unité vers la droite. KP7 Déplace le curseur d'une unité et à la gauche. KP8 Déplace le curseur d'une unité vers le haut. KP9 Déplace le curseur d'une unité et à droite. + Augmente l'unité de déplacement du curseur d'un pixel. Le défaut

le mouvement du curseur est un pixel.

- Diminue l'unité de déplacement du curseur d'un pixel. Entrez Définit un coin de la zone de découpage à la position du curseur. Esc Quitte à DOS sans créer output_file. CLIP sera d'abord question

un "Exit to DOS?" rapide en cas vous avez appuyé sur la touche Echap

        accidentellement.


CONVERT Utility

L'utilitaire CONVERT vous permet de traduire des fichiers entre la SPR et de Fastgraph

PPR formats de fichier d'image. La syntaxe de la commande pour appeler CONVERT partir de l'invite DOS est

CONVERT output_file fichier_entrée

où fichier_entrée est le nom du fichier d'image d'origine, et output_file est le nom du nouveau fichier image traduit. CONVERT ne modifie pas le fichier_entrée en aucune façon, mais il écrasera le output_file si un fichier portant le même nom existe dans le répertoire en cours.

Par défaut, le type de fichier de l'fichier_entrée et output_file déterminer la

format d'image de ce fichier. Si le type de fichier est PPR, CONVERT assume l'image est au format pixel de course emballé de Fastgraph. Si le type de fichier est SPR, CONVERT suppose qu'il est au format pixel de fonctionnement standard de l'Fastgraph. Si vos fichiers d'images utilisent d'autres types de fichiers, vous pouvez spécifier explicitement le format d'image du fichier en ajoutant l'un des commutateurs / PPR ou / SPR au nom de fichier. Le fichier_entrée

Annexe A: Fastgraph Utilities 359


et output_file ne doit pas aussi bien spécifier le même format d'image (CONVERT affichera un message d'erreur si tel est le cas).

La commande suivante traduire le fichier pixel d'exécution norme

PICTURE.SPR au format compressé. L'image emballé sera stockée dans le fichier PICTURE.IMG, nous devons donc ajouter le commutateur / PPR pour dire CONVERT que ce sera un fichier compressé.

CONVERSION PICTURE.SPR PICTURE.IMG / PPR


EDITSPR Utility

L'utilitaire EDITSPR change toutes les courses de pixels d'une couleur à une autre couleur

dans un fichier image stocké dans la norme pixel run (SPR) format Fastgraph. La syntaxe de la commande pour appeler l'utilitaire EDITSPR de l'invite de commande DOS est

EDITSPR fichier_entrée output_file

où fichier_entrée est le nom du fichier d'image d'origine, et output_file est le nom du nouveau fichier image. EDITSPR ne modifie pas le fichier_entrée en aucune façon, mais il écrasera le output_file si un fichier portant le même nom existe dans le répertoire en cours.

Après il lit les pistes de pixels de l'fichier_entrée, EDITSPR effectuera

les changements de couleur requises. Elle le fait de manière itérative en demandant une valeur de couleur ancienne suivie d'une nouvelle valeur de couleur (chaque valeur doit être comprise entre 0 et 255). EDITSPR trouve alors les pistes de pixels de la valeur de couleur vieux et les changements à la nouvelle valeur de couleur. Par la suite, EDITSPR affiche un message indiquant le nombre de pixel court il a changé. Ce processus se répète jusqu'à ce que vous entrez un nombre négatif pour l'une des valeurs de couleur.

EDITSPR va ensuite combiner pistes de pixels adjacents de couleurs semblables.  Pour

exemple, supposons que le fichier image d'origine contenait une couleur 1 pixel course de longueur 50, suivi d'un pixel run couleur 2 de longueur 20, suivie d'une autre couleur 1 pixel course de longueur 10. Si vous avez changé toutes les couleurs 2 pixel fonctionne à la couleur 1 , EDITSPR va combiner ces trois points de pixels en une seule course de longueur 80.


GrabRGB Utility

L'utilitaire GrabRGB est une fin et rester programme résident (TSR) à

capturer les rouges, verts et bleus composantes de couleur actuelles de vidéo registres du CAD dans les modes graphiques 256 couleurs. Vous pouvez utiliser GrabRGB conjointement avec l'utilitaire de INSTANTANÉ de Fastgraph pour préserver les couleurs d'origine d'une image capturée.

Pour charger GrabRGB, il suffit d'entrer la commande GRABRGB à l'invite DOS.  Après

charges GrabRGB, le contrôle revient à l'invite DOS. À ce stade, vous pouvez utiliser tout procédé que ce soit pour afficher une image graphique 256 couleurs, puis appuyez sur la touche Alt et décalage à droite des touches en même temps pour capturer les valeurs du CAD actuelles. Vous ne devez charger GrabRGB pour chaque image, une seule fois par le démarrage du système. GrabRGB utilise environ 28.000 octets de mémoire conventionnelle, une fois chargés. Guide de l'utilisateur 360 Fastgraph


Pour illustrer l'utilisation de GrabRGB, supposons que vous avez dessiné et enregistré un 256-

image couleur avec un programme de peinture commerciale, et que vous voulez incorporer cette image dans une application Fastgraph. Une fois que vous chargez INSTANTANÉ et GrabRGB, démarrez le programme de peinture et de récupérer votre image. Ensuite, appuyez sur les touches Maj gauche Alt et pour capturer l'image avec SNAPSHOT. Après le succès de ton de INSTANTANÉ (trois sons de pente moyenne rapide), appuyez sur Alt et Maj de droite pour saisir les composantes RVB de chaque CNA enregistrent avec GrabRGB, et attendre pour le succès de ton de GrabRGB. Enfin, quittez le programme de peinture et de revenir à l'invite DOS.

La séquence décrite dans le paragraphe précédent écrira le RGB

composantes de couleur pour chaque DAC enregistrent dans un fichier nommé GRABRGB.nnn dans le répertoire courant. Le nnn de type de fichier sera la première séquence de chiffres qui ne donnent pas lieu à un nom de fichier dupliqué. Autrement dit, s'il n'y a pas de fichiers de sortie GrabRGB dans le répertoire courant, GrabRGB utilisera le nom du fichier GRABRGB.000. La prochaine fois que vous utilisez GrabRGB, il va stocker les informations RVB dans GRABRGB.001, puis GRABRGB.002, et ainsi de suite. Si vous renommez ou supprimez un de ces fichiers, GrabRGB sera à nouveau utiliser ce nom de fichier. Par exemple, si vous supprimez GRABRGB.000 mais gardez GRABRGB.001, GrabRGB va ensuite utiliser le nom du fichier GRABRGB.000.

Si GrabRGB est incapable d'obtenir les composantes RVB de chaque registre DAC,

il produira sa tonalité d'erreur (un son unique à faible pente). La cause la plus courante de cette tente de capturer une image à partir d'un mode vidéo de texte ou d'un mode graphique vidéo avec moins de 256 couleurs. Il sera également se produire s'il n'y a pas assez d'espace disque ou si tous les 1000 noms de fichiers de sortie sont déjà utilisés.

Chaque ligne dans le fichier de sortie créé par GrabRGB est de la forme
nnn, rr, gg, bb,

où nnn est un indice de registre DAC (entre 0 et 255), rr est la composante rouge de ce registre DAC, gg est la composante verte, et bb est la composante bleue. Chaque composante de couleur est comprise entre 0 et 63. Vous pouvez éditer et reformater ces lignes que nécessaire pour l'inclusion dans un C ou la liste d'initialisation de C, une déclaration de données BASIC ou FORTRAN, ou une liste constante de type tableau Pascal. Un tel réseau de composants RVB, mais sans les indices nnn, est dans le format attendu par fg_setdacs.

Par défaut, GrabRGB capture des informations pour tous les 256 registres du CAD.  Si

vous voulez considérer que le CAD enregistre avec des composants de couleurs différentes de leurs valeurs par défaut, juste inclure l'option / D lorsque vous chargez GrabRGB (qui est, utilisez la commande GRABRGB / D). Si vous spécifiez l'option / D et les 256 DACs utiliser leurs valeurs par défaut, le fichier de sortie contiendra un message indiquant cela.


HERCFIX Utility

L'utilitaire HERCFIX vous permet d'utiliser INSTANTANÉ (et éventuellement d'autres programmes)

avec des programmes qui ne mettent pas à jour la zone de données du BIOS lors de l'établissement du mode graphique 720x348 Hercules. Si vous utilisez INSTANTANÉ avec un tel programme, il pense que le mode texte monochrome (mode vidéo 7) est actif et produira sa tonalité d'erreur grave lorsqu'il est activé.

Annexe A: Fastgraph Utilities 361


Si cela se produit, utilisez HERCFIX pour charger l'application à partir de laquelle vous êtes

essayant de capturer l'image. Pour ce faire, entrez

commande HERCFIX

à l'invite DOS, où la commande est la commande qui démarre l'application. Par exemple, supposons que vous utilisez la commande PEINTRE / H pour lancer un programme de peinture commerciale en mode graphique Hercules. Pour charger le programme de peinture avec HERCFIX, entrez la commande HERCFIX PEINTRE / H.


PCXHEAD Utility

L'utilitaire PCXHEAD affiche les informations les plus importantes de la

en-tête d'un fichier PCX. Cela comprend le numéro de version PCX, le nombre de bits par pixel, le nombre de plans de bits, la largeur de ligne de balayage, et la position des dimensions de l'image et de l'écran. Il propose également le mode vidéo optimal pour afficher le fichier PCX. Par optimal, on entend le mode vidéo compatible ayant la plus basse résolution est supérieure ou égale aux dimensions de l'image. Pour 256- images couleur PCX, PCXHEAD affiche la palette de couleurs étendue si l'on est présent.

La syntaxe de la commande pour appeler l'utilitaire PCXHEAD du DOS

invite de commande est

PCXHEAD pcx_file

où pcx_file est le nom du fichier PCX à examiner. PCXHEAD ne modifie pas la pcx_file en aucune façon. Si le fichier PCX comprend une palette de couleurs étendue, vous pouvez préférer diriger la sortie PCXHEAD à un fichier en utilisant l'opérateur de redirection DOS (>). Guide de l'utilisateur 362 Fastgraph



Appendice B


Utilisation de Fastgraph du Guide de l'Assemblée Langue 364 Fastgraph utilisateur


Les informations contenues dans cette annexe fournit des informations sur l'appel

routines Fastgraph de programmes en langage assembleur. Il ne vise pas à être un tutoriel complet sur le sujet, mais il devrait fournir des programmeurs expérimentés en langage assembleur avec suffisamment de détails pour appeler routines Fastgraph dans leurs applications.

Fastgraph utilise la même dénomination et conventions d'appel basée sur la pile utilisée

par Borland, Microsoft et d'autres entreprises dans leur C et les compilateurs C de. Les détails de ces conventions importantes à la programmation en langage assembleur sont résumés ci-dessous. Si vous appelez routines Fastgraph d'un programme en langage assembleur, le programme doit suivre ces conventions.

* Tous les tableaux et les pointeurs sont passés par référence.
         * Tous les autres éléments sont passés par valeur.
         * Les arguments sont poussés sur la pile dans le sens inverse
              commande.
         * Le programme appelant est responsable de l'enlèvement
             les arguments de la pile.
         * Les valeurs de fonction 16 bits sont retournés dans l'AX
              registre.
         * valeurs de fonction 32 bits sont retournés dans le DX: AX
             enregistrer paire dans des environnements 16 bits, ou l'EAX
             inscrivez-vous dans des environnements 32 bits.
         * Les noms de routine Fastgraph sont préfixés par un
              souligner.

Les bibliothèques Fastgraph petites et moyennes modèle en mode réel passent des tableaux et des pointeurs par référence proche (un décalage dans DGROUP), tandis que le grand modèle et 16 bits des bibliothèques en mode protégé font par référence loin (un segment: paire offset: offset ou sélecteur) . Les bibliothèques protégées en mode 32 bits utilisent une architecture de modèle plat, ce qui signifie des tableaux et des pointeurs sont transmis sous forme de décalages 32 bits dans DGROUP. Ceci est cohérent avec les conventions et les bibliothèques d'exécution pour les compilateurs pris en charge.

Toutes les routines Fastgraph préserver la (E) BP, (E) DI, (E) SI, et DS

registres. Dans les 32 bits des bibliothèques en mode protégé, les EBX et ES registres sont également conservés. Le contenu de tous les autres registres sont inconnus lors du retour d'une routine Fastgraph (sauf pour le (E) registre AX, qui soit contenir zéro ou la valeur de retour de la routine).

Exemple B-1 appelle fg_getmode, fg_setmode, fg_reset et fg_version de

un programme en langage assembleur. La routine fg_getmode renvoie sa valeur de fonction dans le (E) registre AX. La routine de fg_setmode a un seul argument, alors que fg_reset n'a pas d'arguments. La routine de fg_version a deux arguments, à la fois passé par référence. Remarquez comment ils sont poussés sur la pile dans l'ordre inverse. Cet exemple est écrit pour le modèle de mémoire moyenne. Pour le faire fonctionner avec les grandes bibliothèques de modèles, ajouter 8 au lieu de 4 à la (E) registre de SP qui suit l'appel à fg_version (parce que les grands éléments de modèles passés par référence sont 32 bits des valeurs segmentées). Pour le faire fonctionner avec la petite bibliothèque de modèles, changer le mot «bien» à «proche» dans les déclarations de EXTRN, et changer le nom du segment de code de "main_TEXT" à "_TEXT".

Cet exemple est dans le fichier BB-01.ASM dans le répertoire \ FG \ EXEMPLES.  le

commandes suivantes montrent comment utiliser MASM ou TASM pour assembler ce programme et le lien avec le modèle moyen en mode réel bibliothèque Fastgraph.

Annexe B: Fastgraph de l'Assemblée Langue 365


Microsoft Macro Assembler (MASM) Version 5:
        MASM BB-01.ASM;
        LINK / CP: 4096 BB-01, NUL, MGF;
Microsoft Macro Assembler (MASM) la version 6:
        ML / c / Cx / Zm BB-01.ASM
        LINK / CP: 4096 BB-01, NUL, MGF;
Turbo Assembler (TASM):
        TASM BB-01.ASM
        TLink BB-01.OBJ FGM.LIB
Exemple B-1.

_fg_getmode EXTRN: loin; La routine de getMode de Fastgraph

              _fg_reset EXTRN: loin; la routine RESET de Fastgraph
              _fg_setmode EXTRN: loin; La routine de setMode de Fastgraph
              _fg_version EXTRN: loin; La routine VERSION de Fastgraph
stackseg SEGMENT pile
              db 1024 dup (?); utiliser une pile 1K
    ENDS stackseg
_DATA Mot SEGMENT 'DATA' publique
    dw majeur?  ; numéro de version majeure
    dw mineure?  ; numéro de version mineure
    old_mode dw?  ; mode vidéo d'origine
    ENDS _data
dgroup GROUP _DATA
              ASSUMER cs: main_TEXT, ds: dgroup
octet SEGMENT main_TEXT 'CODE' publique

commencer: mov ax, _DATA; Emplacement du segment de charge

              mov ds, ax; dans le registre DS

appeler _fg_getmode; AX = mode vidéo actuel

              mov old_mode, ax; sauvegarde le

mov ax, 4; utiliser le mode vidéo 4

              pousser la hache; passer l'argument fg_setmode
              appeler _fg_setmode; établir CGA mode quatre couleurs
              ajouter sp, 2; retirer argument fg_setmode

pousser old_mode; passer argument pour fg_setmode

              appeler _fg_setmode; rétablir le mode vidéo original
              ajouter sp, 2; retirer argument fg_setmode

appeler _fg_reset; restaurer les attributs d'écran

lea ax, mineur; obtenir l'adresse de la variable mineure

              pousser la hache; passer l'argument # 2 à fg_version
              lea ax, major; obtenir l'adresse de la variable majeure
              pousser la hache; passer l'argument n ° 1 à fg_version   

Guide de l'utilisateur 366 Fastgraph


appeler _fg_version; obtenir le numéro de version Fastgraph

              ajouter sp, 4; supprimer des arguments fg_version

mov ah, 76; fonction 76: processus fin

              xor al, al; errorlevel 0
              int 21h; sortie sur DOS
ENDS main_TEXT
              début END   



Annexe C


Guide de Interruptions et Fastgraph 368 Fastgraph utilisateur


Utilisé par Fastgraph Les interruptions

DOS maintient une table de vecteur d'interruption où il stocke les adresses des

256 gestionnaires d'interruption, ou des routines, qui exécutent diverses fonctions. Les gestionnaires sont généralement référencées par leur numéro d'interruption hexadécimal, entre 00 et FF. Parmi ceux-ci, seulement interrompt 60 à 66 et F1 par le biais de FF ne sont pas utilisés par le DOS, le BIOS ROM, ou un autre logiciel et sont donc disponibles pour les applications de l'utilisateur.

Certaines routines de Fastgraph utilisent certaines des interruptions disponibles.  Tout

routines Fastgraph / lumière utilisent interruption 62. En outre, le gestionnaire de clavier de bas niveau de Fastgraph remplace interruption 09. Si votre programme définit ses propres gestionnaires d'interruption, il ne faut pas utiliser des interruptions réservées aux Fastgraph (à moins, bien sûr, il n'utilise pas toutes les routines Fastgraph qui pourraient créer un conflit).


L'extension du temps d'interruption de journée

Comme indiqué au chapitre 16, l'horloge du BIOS heure du jour est incrémenté

un gestionnaire d'interruption. La routine qui fait cela est d'interruption 08, une interruption matérielle automatiquement activée 18,2 fois par seconde. Après incrémentation de l'horloge, interrompent 08 invoque interrompent 1C, qui par des références par défaut un gestionnaire "ne rien faire" interruption. En changeant d'interruption 08 peut être délicat, il est assez simple de définir notre propre gestionnaire pour 1C interruption. Ce gestionnaire sera également exécutée automatiquement 18.2 fois par seconde. Exemple C-1 illustre comment faire cela.

Lorsque nous avons discuté joysticks dans le chapitre 14, nous avons dit qu'il y avait deux façons de

surveiller joystick état de la touche. La première consiste à entremêler les appels à fg_button à des endroits stratégiques dans votre programme, puis prendre les mesures nécessaires en fonction de l'état du bouton. Cependant, le problème avec ce système est la possibilité de manquer une pression sur le bouton - si vous appuyez sur le bouton de la manette, puis relâchez entre les appels à fg_button, le programme ne sera pas détecter l'activité du joystick. Un procédé préférable consiste à appeler fg_button à partir d'un gestionnaire pour 1C interruption, qui prévoit essentiellement une surveillance continue des boutons du joystick. Lorsque nous avons besoin de l'état de bouton dans notre programme, tout ce que nous devons faire est examiner une variable globale.

Exemple C-1 est constitué d'un programme principal (écrit en C) et un ensemble

sous-programme de langage appelé int1C (approprié pour le modèle de support de mémoire en mode réel). Le programme principal appelle int1C pour définir un gestionnaire pour 1C interruption. En réponse à une combinaison de touches (sauf Echap), le programme affiche les informations de presse de bouton pour chaque manette depuis la touche précédente (reportez-vous à la discussion de fg_button pour les significations des valeurs d'état). Lorsque vous appuyez sur la touche Echap, le programme sort de DOS, mais pas avant d'appeler int1C pour restaurer le gestionnaire d'origine d'interruption de 1C.

Exemple C-1 (programme principal).
#include <fastgraf.h>
              #include <stdio.h>
             void main (void);
#define ESC 27   
                                 Annexe C: Interruptions et Fastgraph 369


int status1, status2;
void main ()
              {
                unsigned clé de char, aux;
int1C (1);
status1 = 0;
                status2 = 0;
faire {
                    printf ( "\ n");
                   printf ( "Joystick 1 statut:% d \ n", status1);
                   printf ( "Joystick 2 Statut:% d \ n", status2);
                   status1 = 0;
                   status2 = 0;
                   fg_getkey (touche &, & aux);
                    }
                while (key = ESC!);
int1C (0);
              }


Nous allons maintenant examiner le sous-programme int1C en langage assembleur.  Il fait

se compose de trois parties: une partie pour permettre à notre gestionnaire d'interruption, notre gestionnaire lui-même, et une partie de désactiver le gestionnaire. Lorsque nous appelons int1C avec un argument non nul, il enregistre le segment de données d'origine (afin que nous puissions accéder aux variables globales au sein du gestionnaire), enregistre l'adresse du gestionnaire original (appelé le vecteur) pour 1C interruption, puis permet à notre gestionnaire, qui prend la forme d'une procédure beaucoup.

La routine de gestionnaire commence alors à être activés 18,2 fois par seconde.

Après avoir enregistré tous les registres importants, le gestionnaire appelle la routine fg_button Fastgraph deux fois, une fois pour chaque manette. Les valeurs de retour sont logiquement OU avec les STATUS 1 et status2 C variables globales pour mettre à jour les informations d'état du bouton. Enfin, le gestionnaire restaure les registres originaux et renvoie le contrôle au point de l'interruption.

Avant les sorties principales du programme, il appelle int1C avec un argument zéro à

restaurer le gestionnaire d'interruption d'origine pour 1C. Aucune disposition ne prévoit dans le programme pour vérifier si nous avions précédemment défini notre propre gestionnaire (et donc sauvé le 1C vecteur d'interruption d'origine), mais cela pourrait être ajouté avec peu de difficulté.

Exemple C-1 (langage d'assemblage sous-programme).

_status1 EXTRN: mot; C variable globale pour le bouton 1 état

         _status2 EXTRN: mot; C variable globale pour le bouton 2 état
         _fg_button EXTRN: loin; routine Fastgraph

octet SEGMENT int1C_TEXT 'CODE' publique

ASSUMER cs: int1C_TEXT   

Guide de l'utilisateur 370 Fastgraph


int1C_CS dw? ; détient d'origine INT 1C adresse de segment int1C_IP dw? ; détient INT d'origine 1C décalage orig_DS dw? ; détient le segment de données d'origine

_int1C PROC loin

PUBLIC _int1C

pousser bp; sauvegarder le registre BP de l'appelant

         mov pb, sp; faire le point à la liste d'arguments BP
         si push; sauvegarder le registre SI de l'appelant
         di-poussoir; sauvegarder le registre DI de l'appelant

mov dx, [pb + 6]; obtenir le paramètre de drapeau

         ou dx dx; remplacer l'ancien gestionnaire d'interruption?
         jz remplacer; oui, branche pour que le traitement

définir un nouveau gestionnaire pour INT 1C

définir: mov ax, ds; mettre segment de données en cours dans AX

mov cs: orig_DS, ax; enregistrez-le dans la zone d'information de commande

mov al, 1Ch; vecteur d'interruption pour sauver

         mov ah, 53; fonction 53: obtenir vecteur d'interruption
         int 21h; obtenir le vecteur d'interruption
         mov cs: int1C_CS, es; enregistrer le segment
         mov cs: int1C_IP, bx; enregistrer le décalage

pousser ds; sauver notre registre DS

         mov dx, gestionnaire de décalage; obtenir décalage de gestionnaire d'interruption
         mov ax, gestionnaire seg; obtenir segment du gestionnaire d'interruption
         mov ds, ax; mettre dans DS
         mov al, 1Ch; vecteur d'interruption pour changer
         mov ah, 37; fonction 37: set vecteur d'interruption
         int 21h; changer le vecteur INT 1C à notre gestionnaire
         ds pop; restaurer notre registre DS

rendement à court jmp; retourner à l'appelant

remplacer le gestionnaire original pour INT 1C

remplacer: pousser ds; sauver notre registre DS

mov dx, cs: int1C_IP; mettre offset DX originale 1C INT

         ds mov, cs: int1C_CS; mettre segment original INT 1C DS
         mov ah, 37; fonction 37: set vecteur d'interruption
         mov al, 1Ch; interruption vecteur 1C
         int 21h; restauration originale vecteur INT 1C
         ds pop; restaurer notre registre DS

retour: xor ax, ax; en cas int1C a été appelé en fonction

di pop; restaurer notre registre DI

         si pop; restaurer notre registre SI
         pop pb; restaurer notre registre BP
          ret

_int1C ENDP

Annexe C: Interruptions et Fastgraph 371


gestionnaire PROC loin; le gestionnaire d'interruption qui remplace INT 1C

cli; interruptions désactiver tout gestionnaire actif

         pousser la hache; sauvegarder les registres qui peuvent être modifiés
         poussoir bx
         poussoir cx
         poussoir dx
         poussoir di
         poussoir si
         pousser ds
         pousser es

ds mov, cs: orig_DS; récupérer le segment de données d'origine

mov ax, 1; utilisation joystick 1

         pousser la hache; transmettre le numéro de manette pour le bouton de routine
         appeler _fg_button; AX = état de la touche pour joystick 1
         ajouter sp, 2; supprimer l'argument
         ou _status1, ax; mise à jour variable d'état pour joystick 1

mov ax, 2; utilisation joystick 2

         pousser la hache; transmettre le numéro de manette pour le bouton de routine
         appeler _fg_button; AX = état de la touche pour joystick 2
         ajouter sp, 2; supprimer l'argument
         ou _status2, ax; mise à jour variable d'état pour joystick 2

es pop; restaurer les registres modifiés

         ds pop
         pop si
         pop di
         pop dx
         pop cx
         pop bx
         pop ax
         iret; retour de la routine d'interruption

gestionnaire ENDP

ENDS int1C_TEXT

 FIN
L'exemple vient d'être présenté ne vise pas à être un tutoriel sur les interruptions;

il y a beaucoup de bonnes références sur DOS qui les expliquent en détail. Cependant, un exemple spécifique à Fastgraph devrait être utile. Guide de l'utilisateur 372 Fastgraph



Annexe D


Contenu du compilateur spécifique Bibliothèques Guide de 374 Fastgraph utilisateur


Pour la plupart des compilateurs, Fastgraph fournit une bibliothèque spécifique au compilateur (également

appelé la bibliothèque Fastgraph auxiliaire) qui contient les routines suivantes:

fg_boxw fg_drawxw fg_panw fg_setsize
   fg_boxxw fg_drectw fg_pointw fg_setsizew
   fg_circlew fg_ellipsew fg_pointxw fg_setworld
   fg_circlefw fg_ellipsfw fg_polygonw fg_swchar
   fg_clprectw fg_floodw fg_rectw fg_swlength
   fg_dashrw fg_getworld fg_restorew fg_swtext
   fg_dashw fg_initw fg_savew fg_xscreen
   fg_drawrw fg_moverw fg_setangle fg_xworld
   fg_drawrxw fg_movew fg_setclipw fg_yscreen
   fg_draww fg_paintw fg_setratio fg_yworld

Ces routines utilisent l'espace de système de coordonnées, soit directement, soit en interne. Aucun d'entre eux sont inclus dans Fastgraph / Lumière.

Comme mentionné dans le chapitre 1, si votre programme utilise l'une de ces routines,

vous devez lier avec la bibliothèque générale Fastgraph et la bibliothèque Fastgraph auxiliaire correspondant. Certains compilateurs, tels que Microsoft Visual C ++ 32- bit Edition, Microsoft FORTRAN PowerStation et compilateurs BASIC pris en charge de Fastgraph ne nécessitent pas une bibliothèque auxiliaire parce que les routines énumérées ci-dessus sont inclus directement dans la bibliothèque Fastgraph pour les compilateurs.



Annexe E


Contenu du Guide de l'Fichiers Pascal Unit 376 Fastgraph utilisateur


Borland Pascal et Turbo Pascal limitent la taille totale de l'ensemble du code

segments dans une unité fichier 65,520 octets. Parce que la taille du code de Fastgraph dépasse ce montant, les fonctions Fastgraph sont répartis entre plusieurs fichiers unité. Cette annexe énumère le contenu de chaque fichier unité Pascal.

des routines de Fastgraph dans FGBITMAP

fg_clipmap fg_flpimage fg_pack fg_scale
   fg_clipmask fg_getblock fg_print fg_shear
   fg_clpimage fg_getimage fg_printc fg_text
   fg_drawmap fg_getmap fg_putblock fg_textc
   fg_drawmask fg_imagebuf fg_putimage fg_unpack
   fg_drwimage fg_imagesiz fg_revimage
   fg_flipmask fg_invert fg_revmask

des routines de Fastgraph dans FGFLIC

fg_flicdone fg_flicmode fg_flicplay fg_flicskip
   fg_flichead fg_flicopen fg_flicsize fg_showflic

des routines de Fastgraph dans FGGIF

fg_gifhead fg_gifpal fg_makegif fg_showgif
   fg_gifmode fg_gifrange

des routines de Fastgraph dans FGMISC

fg_button fg_kbinit fg_mousemov fg_setcaps
   fg_capslock fg_kblast fg_mousepos fg_setnum
   fg_cursor fg_kbreset fg_mouseptr fg_sound
   fg_getclock fg_kbtest fg_mousespd fg_sounds
   fg_getkey fg_measure fg_mousevis fg_suspend
   fg_getxjoy fg_memavail fg_music fg_voice
   fg_getyjoy fg_mouse256 fg_musicb fg_voices
   fg_hush fg_mousebut fg_numlock fg_waitfor
   fg_hushnext fg_mousecur fg_playing fg_waitkey
   fg_initjoy fg_mousefin fg_quiet
   fg_intjoy fg_mouseini fg_resume
   fg_intkey fg_mouselim fg_scrlock

des routines de Fastgraph dans FGPCX

fg_loadpcx fg_pcxhead fg_pcxpal fg_showpcx
   fg_makepcx fg_pcxmode fg_pcxrange

des routines de Fastgraph dans FGPR

fg_dispfile fg_displayp fg_makespr fg_showspr
   fg_display fg_makeppr fg_showppr

des routines de Fastgraph dans FGSVGA

fg_defpages fg_memory fg_svgainit fg_svgaver
   fg_getbanks fg_setbanks fg_svgastat

des routines de Fastgraph dans FGVB

fg_vbaddr fg_vbcut fg_vbinit fg_vbundef
   fg_vballoc fg_vbdefine fg_vbopen
   fg_vbclose fg_vbfree fg_vbpaste
   fg_vbcopy fg_vbhandle fg_vbtcxfer   
                        Annexe E: Contenu du Pascal Unité FIles 377


Les routines spatiales mondiales énumérées à l'annexe D sont dans l'unité de FGWORLD. Toute autre routine Fastgraph ne figure pas dans cette annexe se trouve dans l'unité de FGMAIN.

Comme mentionné dans le chapitre 1, les programmes Pascal doivent inclure une déclaration des utilisations énumérant toutes les unités référencées dans le programme. L'unité de fgmain est toujours nécessaire dans tous les programmes, est l'unité WinAPI dans les programmes protégés en mode 16 bits. D'autres fichiers unitaires sont nécessaires lorsque vous appelez les routines Fastgraph qu'ils contiennent. Guide de l'utilisateur 378 Fastgraph



Annexe F


Intégration Fastgraph Avec Autres Graphics Software Le Guide de l'utilisateur 380 Fastgraph


Parfois, vous voudrez peut-être utiliser Fastgraph avec d'autres logiciels graphiques,

tels que lors de la conversion d'une application graphique existante à Fastgraph. Cette annexe peut éclaircir certains points à faire cela.

Tout d'abord, laissez les autres logiciels graphiques établir le mode vidéo, puis

initialiser Fastgraph pour ce mode en appelant fg_setmode (-1). Passant -1 à fg_setmode ne change pas physiquement modes vidéo, mais initialise simplement les paramètres internes de Fastgraph pour le mode vidéo actuel.

Deuxièmement, si vous utilisez les modes EGA / VGA / SVGA 16 couleurs graphiques (modes

13 à 18, 28 et 29), vous aurez probablement besoin de définir explicitement la valeur de l'EGA / VGA Activer Set / Reset registre (adresse de port 03CE hex, index 01). Les fonctions de Fastgraph attendre ce registre pour avoir la valeur hexadécimale de 0F; cela permet Fastgraph profiter d'une variante plus efficace disponible en EGA / VGA mode d'écriture 0. La valeur par défaut pour l'option Activer Set / Reset registre est égal à zéro.

Une fois que vous avez appelé fg_setmode (-1) et besoin d'appeler un tiers

fonction graphique, réglez l'option Activer Set / Reset registre à sa valeur par défaut en incluant la déclaration suivante juste avant d'appeler la fonction de tiers:

outport (0x03CE, 0x0001); Borland C ++, Turbo C / C ++, ou Power C outpw (0x03CE, 0x0001); Microsoft C / C ++, QuickC, WATCOM C / C ++ OUT & h03CE, 1: OUT & h03CF, 0 QuickBASIC, BASIC PDS, ou Visual Basic

Juste avant d'appeler la fonction suivante Fastgraph, restaurer la Set / valeur du registre de réinitialisation avec l'énoncé suivant Activer:

outport (0x03CE, 0x0F01); Borland C ++, Turbo C / C ++, ou Power C outpw (0x03CE, 0x0F01); Microsoft C / C ++, QuickC, WATCOM C / C ++ OUT & h03CE, 1: OUT & h03CF, 15 QuickBASIC, BASIC PDS, ou Visual Basic



Annexe G


Conversion de programmes au Guide de mode protégé 382 Fastgraph utilisateur


Dans cette annexe, nous allons décrire les étapes nécessaires pour le portage en mode réel

applications Fastgraph en mode protégé. Nous allons aussi couvrir les changements communs nécessaires lors de la conversion des applications 16 bits en mode protégé 32 bits.


Mode protégé Initialisation

La première et la plus évidente étape lors de la conversion des programmes visant à protéger

le mode est d'appeler fg_initpm. Cette routine met en place des fonctionnalités du mode protégé pour chaque extension DOS pris en charge et doivent être appelées avant toute autre routine Fastgraph dans les programmes en mode protégé. Le non-respect cela se traduira par un défaut de protection, généralement immédiatement après le réglage du mode vidéo. La routine de fg_initpm n'a pas d'arguments et aucune valeur de retour. Il est inclus dans les bibliothèques de support spécifiques à extension (par exemple, dans FG16DPMI.LIB) si Fastgraph prend en charge plus d'une extension DOS pour un compilateur donné.


Considérations pour les pages logiques

En mode réel, Fastgraph vous permet de créer des pages logiques classiques

la mémoire (avec fg_alloccms), mémoire étendue (avec fg_allocems), ou mémoire étendue (avec fg_allocxms). En mode protégé, la distinction entre la mémoire conventionnelle, élargi et étendu disparaît parce que DOS extenders essentiellement traiter toute la mémoire système comme mémoire conventionnelle. Pour cette raison, les fg_initems et fg_initxms routines ne sont pas significatifs et donc toujours revenir -1 en mode protégé bibliothèques Fastgraph. Cela désactive efficacement les fg_allocems et fg_allocxms routines, vous devez donc créer des pages logiques avec fg_alloccms en mode protégé.

Si vous avez de réelles applications Fastgraph de mode qui utilisent des pages logiques, il est

très simple pour les convertir en mode protégé - il suffit de changer tous les fg_allocems et fg_allocxms appels à fg_alloccms.


Considérations pour Tampons Virtuels

Le chapitre 8 décrit les différentes méthodes disponibles pour l'allocation de mémoire

pour les tampons virtuels. Parce que certains compilateurs en mode réel ont un soutien pour d'énormes réseaux limités (blocs de mémoire supérieure à 64K octets), fg_vballoc et fg_vbfree les routines de Fastgraph sont prévus pour allouer et libérer la mémoire appropriée pour les tampons virtuels. Tous les compilateurs en mode protégé fournissent un support complet pour les tableaux énormes, de sorte que ces deux fonctions ne sont pas nécessaires (en fait, ils ne sont pas encore inclus dans les bibliothèques en mode protégé). Ainsi, vous devez remplacer les fg_vballoc et fg_vbfree appels avec les fonctions correspondantes de gestion de la mémoire de votre compilateur comme indiqué dans le chapitre 8 et utiliser fg_vbdefine pour créer le tampon virtuel.


Curseur de la souris Définition

La routine fg_mouseptr attend l'écran et curseur masques de résider dans

un réseau de 32 éléments de valeurs 16 bits. Si vous convertissez un C ou d'une application C ++ Fastgraph à partir d'un 16 bits à un environnement 32 bits, vous devez modifier le type du tableau de masque écran / curseur est passé à fg_mouseptr de int à court données.

Annexe G: Conversion de programmes pour le mode protégé 383


les programmeurs FORTRAN devraient être sûr de passer un INTEGER * 2 tableau au lieu d'un tableau de INTEGER ordinaire.


Types de données FORTRAN

Lors de la conversion des programmes FORTRAN en mode protégé 32 bits, tout ENTIER * 2

quantités passés aux fonctions Fastgraph doivent être modifiés pour des entiers sur quatre octets. Pour une portabilité maximale, nous vous recommandons de les changer de type integer, ce qui équivaut à ENTIER * 2 dans les environnements 16 bits et équivalent à INTEGER * 4 dans des environnements 32 bits.


Incompatible comportement du mode réel

Après avoir ajouté l'appel fg_initpm et fait les autres changements

décrit jusqu'à présent, vous devez tester votre programme pour voir si elle fonctionne en mode protégé. La plupart des programmes linguistiques de haut niveau travailleront à ce point avec aucun autre changement requis.

Cependant, certains programmes comprennent des fonctionnalités qui sont acceptables en mode réel

mais pas en mode protégé (souvent ce comportement est involontaire). Ces pratiques comprennent le chargement des adresses physiques dans les registres de segment, en utilisant des adresses de segments physiques pointeurs loin, écriture de données sur un segment de code, le référencement des arguments de ligne de commande non précisés, l'accès à la mémoire au-delà de la limite d'un segment, et le déréférencement des pointeurs nuls. Quand un programme en mode protégé rencontre l'un de ces problèmes lors de l'exécution, il sort pour DOS avec une erreur de protection générale ou GPF.

La documentation livrée avec votre extension DOS fournira probablement

informations sur l'isolement des erreurs de protection et d'offrir des suggestions sur la façon de les corriger. Deux autres références, extension DOS édité par Ray Duncan (Addison- Wesley, 1992) et DOS et mode protégé de Windows par Al Williams (Addison- Wesley, 1993) sont des ressources précieuses pour la programmation en mode protégé. Les deux livres comprennent des informations détaillées sur les différences entre le mode réel et en mode protégé et discuter des problèmes et des solutions communes protégées de programmation de mode. Guide de l'utilisateur 384 Fastgraph



Annexe H


Guide de fichier image en-tête Formats 386 Fastgraph utilisateur


images PCX, GIF et FLI / FLC incluent les en-têtes de fichiers qui définissent l'image

taille, le nombre de couleurs, et d'autres informations nécessaires pour afficher l'image. Fastgraph fournit des routines pour lire les en-têtes d'image et de récupérer leurs éléments les plus utiles. Cependant, il peut y avoir des moments où vous avez besoin d'informations supplémentaires stockées dans l'en-tête du fichier. Cette annexe fournit des détails complets sur la structure du PCX, GIF, et en-têtes de fichier flic. Dans les tableaux qui suivent, nous supposerons que tous les décalages commencent à zéro, toutes les tailles de champ sont en octets, et toutes les valeurs entières sont stockées avec l'octet le moins significatif en premier.

fichiers PCX commencent par un en-tête de 128 octets:

décalage taille description
0 1 octet du fabricant, doit être de 10 décimales
      1 1 PCX numéro de version
                    0 = PC Paintbrush version 2.5
                    2 = PC Paintbrush 2.8 avec des informations de la palette
                    3 = PC Paintbrush 2.8 sans information de la palette
                    4 = PC Paintbrush pour Windows
                    5 = PC Paintbrush 3.0 ou version ultérieure, PC Paintbrush plus
      2 1 run octet longueur de codage, doit être 1
      3 1 nombre de bits par pixel par plan de bits
      4 8 limites de l'image en pixels: Xmin, Ymin, Xmax, Ymax
     12 2 points horizontaux par pouce lorsque imprimés (peu fiable)
     14 2 points verticaux par pouce lorsque imprimés (peu fiable)
     16 48 palette de 16 couleurs (16 RGB triple entre 0-255)
     64 1 réservé, doit être nul
     65 1 nombre de plans de bits
     66 2 mémoire vidéo octets par image rangée
     68 2 16 palette de couleurs interprétation (peu fiable)
                    0 = couleur ou b & w, 1 = niveaux de gris
     70 2 résolution horizontale de l'écran - 1 (peu fiable)
     72 2 résolution verticale de l'écran - 1 (peu fiable)
     74 54 réservé, doit être nul

Les fichiers GIF commencent par un en-tête global de 13 octets et un en-tête locale de 10 octets:

décalage taille description
0 6 GIF signature, doit être GIF87a ou GIF89a
      6 2 résolution horizontale de la création de mode vidéo (non fiable)
      8 2 résolution verticale de la création mode vidéo (non fiable)
     10 1 octet indicateur global
                    bit 7 est défini si la carte de couleur globale est présent
                    les bits 0-3 sont le nombre de couleurs (2 ** (n + 1)),
     couleur 11 1 fond
     12 1 pour GIF87a, doit être nul
                  pour GIF89a, rapport d'aspect
     13 0 réservé, doit être 44 décimal (ASCII virgule)
     14 2 bord gauche de l'image en pixels
     16 2 bord supérieur de l'image en pixels
     18 2 Largeur de l'image en pixels
     hauteur 20 2 image en pixels
     22 1 octet de drapeau locale
                    bit 7 est défini si la carte de la couleur locale est présente   
                                Annexe H: Image File Formats d'en-tête 387


bit 6 est réglé si l'image est entrelacée
                    les bits 0-3 sont le nombre de couleurs (2 ** (n + 1)),


Les fichiers FLI et FLC commencent par un en-tête de 128 octets:

décalage taille description
taille 0 4 du fichier en octets
      4 2 signature, AF11 hex pour les fichiers FLI, AF12 hex pour les fichiers FLC
      6 2 nombre d'images
      8 2 Largeur de l'image en pixels
     hauteur 10 2 image en pixels
     12 2 bits par pixel, doit être 8
     14 2 réservé, doit être 3
     retard 16 4 temps entre les images
                    unités sont 1/70 seconde pour les fichiers FLI
                    unités sont millisecondes pour les fichiers FLC
     20 2 réservé, doit être nul
     22 4 fichier création date / heure (format MS-DOS)
     le numéro de série 26 4 créateur (non fiable)
     30 4 révision du fichier de date / heure (format MS-DOS)
     le numéro de série 34 4 updater (peu fiable)
     38 4 horizontal rapport d'aspect de la création de mode vidéo
     40 2 vertical rapport d'aspect de la création de mode vidéo
     42 38 réservé, doit être nul
     80 4 octets de décalage au début de la première image
     84 4 octets de décalage au début de la seconde trame
     88 40 réservé, doit être nul

L

es champs à partir du décalage 22 et ci-dessus dans l'en-tête de fichier flac appliquent aux fichiers FLC seulement. Pour les fichiers FLI, ils devraient tous être zéro. Guide de l'utilisateur 388 Fastgraph

Index 389

Menu de navigation

   français
   Créer un compte Tarifs
   Se connecter 
   Page
   Discussion
   Lire
   Modificateur
   Modifier le wikicode
   Historique










Fastgraph (r)



User's Guide � Copyright (c) 1991-1995 by Ted Gruber Software, Inc.

All rights reserved. No part of this publication may be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical, photocopying, recording, or otherwise, without express written permission from Ted Gruber Software. The software described in this publication is furnished under a license agreement and may be used or copied only in accordance with the terms of that agreement.

This publication and its associated software are sold without warranties, either expressed or implied, regarding their merchantability or fitness for any particular application or purpose. The information in this publication is subject to change without notice and does not represent a commitment on the part of Ted Gruber Software. In no event shall Ted Gruber Software be liable for any loss of profit or any other commercial damage, including but not limited to special, incidental, consequential, or other damages resulting from the use of or the inability to use this product, even if Ted Gruber Software has been notified of the possibility of such damages.


First Printing, August 1994

Fastgraph version 4.0






All brand and product names mentioned in this publication are trademarks or registered trademarks of their respective holders. �

                      T a b l e   o f   C o n t e n t s


Chapter 1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 1

    What is Fastgraph? . . . . . . . . . . . . . . . . . . . . . . . . .    2
    Fastgraph/Light  . . . . . . . . . . . . . . . . . . . . . . . . . .    2
    Prerequisite Knowledge . . . . . . . . . . . . . . . . . . . . . . .    3
    Supported Compilers  . . . . . . . . . . . . . . . . . . . . . . . .    3
    Real Mode, Protected Mode, and DOS Extenders . . . . . . . . . . . .    4
    Memory Models  . . . . . . . . . . . . . . . . . . . . . . . . . . .    5
    Installing Fastgraph . . . . . . . . . . . . . . . . . . . . . . . .    6
    The READ.ME File . . . . . . . . . . . . . . . . . . . . . . . . . .    7
    The WHATS.NEW File . . . . . . . . . . . . . . . . . . . . . . . . .    7
    Fastgraph Naming Conventions . . . . . . . . . . . . . . . . . . . .    7
    Compilation and Linking  . . . . . . . . . . . . . . . . . . . . . .    7
         Borland C++ . . . . . . . . . . . . . . . . . . . . . . . . . .   10
         Borland Pascal  . . . . . . . . . . . . . . . . . . . . . . . .   12
         MetaWare High C/C++ . . . . . . . . . . . . . . . . . . . . . .   13
         Microsoft BASIC Professional Development System . . . . . . . .   14
         Microsoft C/C++ . . . . . . . . . . . . . . . . . . . . . . . .   15
         Microsoft FORTRAN . . . . . . . . . . . . . . . . . . . . . . .   16
         Microsoft FORTRAN PowerStation  . . . . . . . . . . . . . . . .   17
         Microsoft QuickBASIC  . . . . . . . . . . . . . . . . . . . . .   18
         Microsoft QuickC  . . . . . . . . . . . . . . . . . . . . . . .   19
         Microsoft Visual Basic for DOS  . . . . . . . . . . . . . . . .   20
         Microsoft Visual C++  . . . . . . . . . . . . . . . . . . . . .   21
         Microsoft Visual C++ 32-bit Edition . . . . . . . . . . . . . .   22
         Power C . . . . . . . . . . . . . . . . . . . . . . . . . . . .   23
         Turbo C and Turbo C++ . . . . . . . . . . . . . . . . . . . . .   24
         Turbo Pascal  . . . . . . . . . . . . . . . . . . . . . . . . .   25
         WATCOM C/C++  . . . . . . . . . . . . . . . . . . . . . . . . .   26
         WATCOM C32 for DOS  . . . . . . . . . . . . . . . . . . . . . .   26
         Zortech C++ . . . . . . . . . . . . . . . . . . . . . . . . . .   27
    Fastgraph/Light Video Driver . . . . . . . . . . . . . . . . . . . .   28

Chapter 2 PC and PS/2 Video Modes . . . . . . . . . . . . . . . . . . . 29

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   30
    Text Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   31
    Graphics Modes . . . . . . . . . . . . . . . . . . . . . . . . . . .   33
         CGA Graphics Modes  . . . . . . . . . . . . . . . . . . . . . .   33
         Tandy 1000 and PCjr Graphics Modes  . . . . . . . . . . . . . .   34
         Hercules Graphics Modes . . . . . . . . . . . . . . . . . . . .   34
         EGA Graphics Modes  . . . . . . . . . . . . . . . . . . . . . .   35
         VGA and MCGA Graphics Modes . . . . . . . . . . . . . . . . . .   36
         Extended VGA (XVGA) Graphics Modes  . . . . . . . . . . . . . .   37
         SuperVGA (SVGA) Graphics Modes  . . . . . . . . . . . . . . . .   38

Chapter 3 Initializing the Video Environment . . . . . . . . . . . . . . 41

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   42
    Establishing a Text Mode . . . . . . . . . . . . . . . . . . . . . .   42
    43-line and 50-line Text Modes . . . . . . . . . . . . . . . . . . .   45
    Establishing a Graphics Mode . . . . . . . . . . . . . . . . . . . .   46
    SuperVGA Graphics Modes  . . . . . . . . . . . . . . . . . . . . . .   50
    Summary of Video Initialization Routines . . . . . . . . . . . . . .   55


                                     iii                                      �

Chapter 4 Coordinate Systems . . . . . . . . . . . . . . . . . . . . . . 57

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   58
    Character Space  . . . . . . . . . . . . . . . . . . . . . . . . . .   58
    Screen Space . . . . . . . . . . . . . . . . . . . . . . . . . . . .   59
    Viewports  . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   60
    World Space  . . . . . . . . . . . . . . . . . . . . . . . . . . . .   62
    Conversion Routines  . . . . . . . . . . . . . . . . . . . . . . . .   64
    Summary of Coordinate Routines . . . . . . . . . . . . . . . . . . .   64

Chapter 5 The Use of Color . . . . . . . . . . . . . . . . . . . . . . . 67

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   68
    Text Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   68
         Color Text Modes  . . . . . . . . . . . . . . . . . . . . . . .   68
         Monochrome Text Mode  . . . . . . . . . . . . . . . . . . . . .   69
    Graphics Modes . . . . . . . . . . . . . . . . . . . . . . . . . . .   70
         CGA Color Modes . . . . . . . . . . . . . . . . . . . . . . . .   70
         CGA Two-Color Mode  . . . . . . . . . . . . . . . . . . . . . .   72
         Tandy and PCjr Modes  . . . . . . . . . . . . . . . . . . . . .   73
         Hercules Mode . . . . . . . . . . . . . . . . . . . . . . . . .   74
         Hercules Low-Resolution Mode  . . . . . . . . . . . . . . . . .   75
         EGA 200-Line Modes  . . . . . . . . . . . . . . . . . . . . . .   76
         EGA Monochrome Mode . . . . . . . . . . . . . . . . . . . . . .   78
         EGA Enhanced Mode . . . . . . . . . . . . . . . . . . . . . . .   79
         VGA and MCGA Two-Color Mode . . . . . . . . . . . . . . . . . .   81
         VGA/SVGA 16-Color Modes . . . . . . . . . . . . . . . . . . . .   83
         256-Color Modes . . . . . . . . . . . . . . . . . . . . . . . .   83
    Using Video DAC Registers in EGA Modes . . . . . . . . . . . . . . .   87
    RGB Color Mapping  . . . . . . . . . . . . . . . . . . . . . . . . .   89
    Defining All Palette Registers . . . . . . . . . . . . . . . . . . .   90
    Virtual Colors . . . . . . . . . . . . . . . . . . . . . . . . . . .   90
    A Multiple-Mode Example  . . . . . . . . . . . . . . . . . . . . . .   92
    Summary of Color-Related Routines  . . . . . . . . . . . . . . . . .   94

Chapter 6 Graphics Fundamentals . . . . . . . . . . . . . . . . . . . . 97

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   98
    Clearing the Screen  . . . . . . . . . . . . . . . . . . . . . . . .   98
    Clipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   98
    Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   99
    The Graphics Cursor  . . . . . . . . . . . . . . . . . . . . . . . .  100
    Solid Lines  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  101
    Dashed Lines . . . . . . . . . . . . . . . . . . . . . . . . . . . .  103
    Polygons . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  104
    Circles and Ellipses . . . . . . . . . . . . . . . . . . . . . . . .  107
    Solid Rectangles . . . . . . . . . . . . . . . . . . . . . . . . . .  109
    Unfilled Rectangles  . . . . . . . . . . . . . . . . . . . . . . . .  110
    Dithered Rectangles  . . . . . . . . . . . . . . . . . . . . . . . .  112
    Region Fill  . . . . . . . . . . . . . . . . . . . . . . . . . . . .  119
    Summary of Fundamental Graphics Routines . . . . . . . . . . . . . .  121

Chapter 7 Character Display Routines . . . . . . . . . . . . . . . . . . 125

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  126
    Character Space  . . . . . . . . . . . . . . . . . . . . . . . . . .  126
    Hardware Characters  . . . . . . . . . . . . . . . . . . . . . . . .  127
    Character Height . . . . . . . . . . . . . . . . . . . . . . . . . .  135
    Conversion Routines  . . . . . . . . . . . . . . . . . . . . . . . .  137
    Software Characters  . . . . . . . . . . . . . . . . . . . . . . . .  138


                                     iv                                       �
    Bitmapped Characters . . . . . . . . . . . . . . . . . . . . . . . .  143
    Summary of Character Display Routines  . . . . . . . . . . . . . . .  144

Chapter 8 Video Pages and Virtual Buffers . . . . . . . . . . . . . . . 147

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  148
    Physical Pages and Virtual Pages . . . . . . . . . . . . . . . . . .  148
    Pages With Special Meanings  . . . . . . . . . . . . . . . . . . . .  150
    Some Simple Examples . . . . . . . . . . . . . . . . . . . . . . . .  150
    Text Cursors . . . . . . . . . . . . . . . . . . . . . . . . . . . .  157
    Obtaining Video Page Information . . . . . . . . . . . . . . . . . .  158
    Considerations for Virtual Pages . . . . . . . . . . . . . . . . . .  159
    Considerations for SuperVGA Pages  . . . . . . . . . . . . . . . . .  160
    Logical Pages  . . . . . . . . . . . . . . . . . . . . . . . . . . .  161
    Extended Video Pages . . . . . . . . . . . . . . . . . . . . . . . .  163
    Video Page Resizing  . . . . . . . . . . . . . . . . . . . . . . . .  166
    Preserving Video Page Contents Across Mode Switches  . . . . . . . .  167
    Controlling Page Allocation  . . . . . . . . . . . . . . . . . . . .  169
    Virtual Buffers  . . . . . . . . . . . . . . . . . . . . . . . . . .  171
    Summary of Video Page and Virtual Buffer Routines  . . . . . . . . .  180

Chapter 9 Image Files . . . . . . . . . . . . . . . . . . . . . . . . . 183

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  184
    PCX Files  . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  184
    GIF Files  . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  189
    FLI and FLC files  . . . . . . . . . . . . . . . . . . . . . . . . .  192
    Pixel Run Files  . . . . . . . . . . . . . . . . . . . . . . . . . .  196
    Display Patterns . . . . . . . . . . . . . . . . . . . . . . . . . .  200
    Controlling the Image Buffer Size  . . . . . . . . . . . . . . . . .  206
    Summary of Image File Routines . . . . . . . . . . . . . . . . . . .  208

Chapter 10 Bitmapped Images . . . . . . . . . . . . . . . . . . . . . . 211

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  212
    Mode-Independent Bitmapped Images  . . . . . . . . . . . . . . . . .  212
    Mode-Specific Bitmapped Images . . . . . . . . . . . . . . . . . . .  217
         Regular Images  . . . . . . . . . . . . . . . . . . . . . . . .  217
         Clipped Images  . . . . . . . . . . . . . . . . . . . . . . . .  225
         Reversed Images . . . . . . . . . . . . . . . . . . . . . . . .  225
         Reversed Clipped Images . . . . . . . . . . . . . . . . . . . .  226
         Images Without Transparent Pixels . . . . . . . . . . . . . . .  226
         Some Examples . . . . . . . . . . . . . . . . . . . . . . . . .  226
    Retrieving Images  . . . . . . . . . . . . . . . . . . . . . . . . .  229
    Inverting Bitmaps  . . . . . . . . . . . . . . . . . . . . . . . . .  234
    Converting Mode-Specific Bitmaps . . . . . . . . . . . . . . . . . .  236
    Bitmap Scaling and Shearing  . . . . . . . . . . . . . . . . . . . .  239
    Pixel Run Maps . . . . . . . . . . . . . . . . . . . . . . . . . . .  244
    Masking Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . .  248
    Summary of Bitmapped Image Display Routines  . . . . . . . . . . . .  251

Chapter 11 Block Transfer Routines . . . . . . . . . . . . . . . . . . . 255

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  256
    Full Page Transfer . . . . . . . . . . . . . . . . . . . . . . . . .  256
    Byte Boundaries  . . . . . . . . . . . . . . . . . . . . . . . . . .  257
    Dual SVGA Banks  . . . . . . . . . . . . . . . . . . . . . . . . . .  259
    The "Hidden" Video Page  . . . . . . . . . . . . . . . . . . . . . .  259
    Saving and Restoring Blocks  . . . . . . . . . . . . . . . . . . . .  259
    A More General Block Transfer Routine  . . . . . . . . . . . . . . .  262


                                      v                                       �
    Block Transfer Routines for Virtual Buffers  . . . . . . . . . . . .  266
    Blocks with Transparent Colors . . . . . . . . . . . . . . . . . . .  267
    Transparent Block Transfers for Virtual Buffers  . . . . . . . . . .  269
    Transferring Blocks to and from Conventional Memory  . . . . . . . .  270
    Summary of Block Transfer Routines . . . . . . . . . . . . . . . . .  271

Chapter 12 Animation Techniques . . . . . . . . . . . . . . . . . . . . 273

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  274
    Simple Animation . . . . . . . . . . . . . . . . . . . . . . . . . .  274
    XOR Animation  . . . . . . . . . . . . . . . . . . . . . . . . . . .  276
    Static Frame Animation . . . . . . . . . . . . . . . . . . . . . . .  278
    Dynamic Frame Animation  . . . . . . . . . . . . . . . . . . . . . .  280
    Page Flipping  . . . . . . . . . . . . . . . . . . . . . . . . . . .  282
    An Animation Example: The Fastgraph Fish Tank  . . . . . . . . . . .  284
    Summary of Animation Techniques  . . . . . . . . . . . . . . . . . .  284

Chapter 13 Special Effects . . . . . . . . . . . . . . . . . . . . . . . 287

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  288
    Screen Dissolving  . . . . . . . . . . . . . . . . . . . . . . . . .  288
    Scrolling  . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  290
    Changing the Screen Origin . . . . . . . . . . . . . . . . . . . . .  293
    Panning With Virtual Buffers . . . . . . . . . . . . . . . . . . . .  296
    Split Screen . . . . . . . . . . . . . . . . . . . . . . . . . . . .  298
    Summary of Special Effects Routines  . . . . . . . . . . . . . . . .  300

Chapter 14 Input Device Support . . . . . . . . . . . . . . . . . . . . 301

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  302
    Keyboard Support . . . . . . . . . . . . . . . . . . . . . . . . . .  302
         Reading Keystrokes  . . . . . . . . . . . . . . . . . . . . . .  304
         Testing and Setting Key States  . . . . . . . . . . . . . . . .  305
         Low-Level Keyboard Handler  . . . . . . . . . . . . . . . . . .  307
    Mouse Support  . . . . . . . . . . . . . . . . . . . . . . . . . . .  309
         Initializing the Mouse  . . . . . . . . . . . . . . . . . . . .  309
         XVGA and SVGA Mouse Considerations  . . . . . . . . . . . . . .  310
         Controlling the Mouse Cursor  . . . . . . . . . . . . . . . . .  311
         Reporting the Mouse Status  . . . . . . . . . . . . . . . . . .  313
         Defining the Mouse Cursor . . . . . . . . . . . . . . . . . . .  315
    Joystick Support . . . . . . . . . . . . . . . . . . . . . . . . . .  323
         Initializing Joysticks  . . . . . . . . . . . . . . . . . . . .  323
         Reporting Joystick Status . . . . . . . . . . . . . . . . . . .  324
         Keyboard Emulation  . . . . . . . . . . . . . . . . . . . . . .  325
         Special Joystick Considerations . . . . . . . . . . . . . . . .  326
    Summary of Input Routines  . . . . . . . . . . . . . . . . . . . . .  326

Chapter 15 Sound Effects . . . . . . . . . . . . . . . . . . . . . . . . 329

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  330
    Sound Sources  . . . . . . . . . . . . . . . . . . . . . . . . . . .  330
    Synchronous Sound  . . . . . . . . . . . . . . . . . . . . . . . . .  330
    Asynchronous Sound . . . . . . . . . . . . . . . . . . . . . . . . .  335
    Summary of Sound Routines  . . . . . . . . . . . . . . . . . . . . .  340

Chapter 16 Program Timing . . . . . . . . . . . . . . . . . . . . . . . 343

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  344
    Real-Time Routines . . . . . . . . . . . . . . . . . . . . . . . . .  344
    Routines Dependent on the System Speed . . . . . . . . . . . . . . .  345
    Summary of Timing Routines . . . . . . . . . . . . . . . . . . . . .  347


                                     vi                                       �

Chapter 17 Miscellaneous Routines . . . . . . . . . . . . . . . . . . . 349

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  350
    Determining Available Memory . . . . . . . . . . . . . . . . . . . .  350
    Choosing the Video Memory Update Function  . . . . . . . . . . . . .  351
    Controlling Vertical Retrace Synchronization . . . . . . . . . . . .  352
    External SVGA Bank Switching . . . . . . . . . . . . . . . . . . . .  353
    Saving and Restoring the Video State . . . . . . . . . . . . . . . .  353
    Summary of Miscellaneous Routines  . . . . . . . . . . . . . . . . .  354

Appendix A Fastgraph Utilities . . . . . . . . . . . . . . . . . . . . . 355

    Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .  356
    SNAPSHOT Utility . . . . . . . . . . . . . . . . . . . . . . . . . .  356
    CLIP Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . .  357
    CONVERT Utility  . . . . . . . . . . . . . . . . . . . . . . . . . .  358
    EDITSPR Utility  . . . . . . . . . . . . . . . . . . . . . . . . . .  359
    GrabRGB Utility  . . . . . . . . . . . . . . . . . . . . . . . . . .  359
    HERCFIX Utility  . . . . . . . . . . . . . . . . . . . . . . . . . .  360
    PCXHEAD Utility  . . . . . . . . . . . . . . . . . . . . . . . . . .  361

Appendix B Using Fastgraph from Assembly Language . . . . . . . . . . . 363

Appendix C Interrupts and Fastgraph . . . . . . . . . . . . . . . . . . 367

    Interrupts Used by Fastgraph . . . . . . . . . . . . . . . . . . . .  368
    Extending the Time-of-Day Interrupt  . . . . . . . . . . . . . . . .  368

Appendix D Contents of the Compiler-Specific Libraries . . . . . . . . . 373

Appendix E Contents of the Pascal Unit Files . . . . . . . . . . . . . . 375

Appendix F Integrating Fastgraph With Other Graphics Software . . . . . 379

Appendix G Converting Programs to Protected Mode . . . . . . . . . . . . 381

    Protected Mode Initialization  . . . . . . . . . . . . . . . . . . .  382
    Considerations for Logical Pages . . . . . . . . . . . . . . . . . .  382
    Considerations for Virtual Buffers . . . . . . . . . . . . . . . . .  382
    Mouse Cursor Definition  . . . . . . . . . . . . . . . . . . . . . .  382
    FORTRAN Data Types . . . . . . . . . . . . . . . . . . . . . . . . .  383
    Incompatible Real Mode Behavior  . . . . . . . . . . . . . . . . . .  383

Appendix H Image File Header Formats . . . . . . . . . . . . . . . . . . 385









                                     vii                                      �






























                                    viii                                      �




Chapter 1



Introduction � 2 Fastgraph User's Guide


What is Fastgraph?

    Fastgraph is a library of more than 275 highly-optimized routines that

are callable from high-level and assembly language programs running under the MS-DOS or PC-DOS operating systems. This collection of routines provides a programmer with proven, powerful tools to take command of the PC and PS/2 video environment. In addition to its video support, Fastgraph also includes routines to perform keyboard, mouse, and joystick control, as well as music and sound capabilities. Fastgraph is an ideal development tool for entertainment and educational software, presentation graphics products, scientific and engineering applications, CAD/CAM, animation, or any application that demands robust graphics.

    As its name implies, the most notable feature of Fastgraph is its speed.

Virtually all of Fastgraph is written in assembly language, and each routine has been optimized by hand to provide maximum performance. Fastgraph's protected mode libraries take advantage of the features offered by the 80286 and 80386 instruction sets.

    Fastgraph supports all the standard text and graphics video modes used by

the IBM PC and compatible systems (PC, PC/XT, and PC/AT, 80386, 80486, and Pentium) and IBM PS/2 family. In addition, Fastgraph provides support for six SuperVGA (SVGA) graphics modes, four extended VGA (XVGA) graphics modes, and a 16-color graphics mode unique to Tandy 1000 series computers and the PCjr. Even though the graphics mode of the Hercules Graphics Card is not an IBM standard, its one-time popularity has made it a de facto standard, and for this reason Fastgraph also supports it. In total, Fastgraph supports 23 graphics modes and 5 text modes. A complete discussion of these video modes appears in the next chapter.


Fastgraph/Light

    Fastgraph/Light is a subset of Fastgraph. It includes all of Fastgraph's

features except the GIF file support routines, redefinable world space coordinate system, and the routines pertaining to software characters. Programs created using Fastgraph/Light are 100% source code compatible with Fastgraph.

    The most important difference between Fastgraph/Light and Fastgraph is

the method of running a program created with the two products. With Fastgraph, any of its routines used in your program are linked directly into the resulting EXE file. With Fastgraph/Light, however, this is not the case. Instead, the Fastgraph/Light routines provide an interface to an external driver, called the Fastgraph/Light Video Driver, which must be loaded separately before running programs that call any Fastgraph/Light routines. See the last section of this chapter for more information.

    Another important difference between Fastgraph and Fastgraph/Light is the

name of the library (LIB) files. All Fastgraph libraries begin with the two characters FG, while the equivalent Fastgraph/Light libraries begin with the three characters FGL. For example, FGS.LIB is the small model Fastgraph library used with most C compilers, but FGLS.LIB is the equivalent Fastgraph/Light library name. Note that the Pascal unit files always begin with FG, whether you're using Fastgraph or Fastgraph/Light. �

                                                 Chapter 1:  Introduction   3


    In the Fastgraph User's Guide and the accompanying Fastgraph Reference

Manual, references to Fastgraph also apply to Fastgraph/Light unless stated otherwise.


Prerequisite Knowledge

    Fastgraph is a programming tool, which means programmers are its intended

audience. For this reason, the Fastgraph User's Guide and Fastgraph Reference Manual assume you have a knowledge of programming. Additionally, a knowledge of converting numbers between binary, decimal, and hexadecimal is assumed.

    Virtually all the examples in this manual are written in the C

programming language, so a knowledge of C would be especially helpful. The examples intentionally avoid using any of C's features and idioms that might not be readily apparent to a programmer unfamiliar with C. If you're programming in real mode, don't be confused by the fact that all the examples call Fastgraph's fg_initpm routine for protected mode initialization -- in real mode, fg_initpm simply returns to the caller. Finally, we'd like to point out that the examples should be read not by themselves, but as part of the surrounding text.


Supported Compilers

    You can use Fastgraph with any compilers or assemblers that use the same

calling and naming conventions as the small, medium, large, or flat memory models of the supported compilers. Mixed language programming is allowed where supported by the language translators, linker, and DOS extender being used. Fastgraph supports the following compilers:

    * Borland C++ (version 2.0 or later)
    * Borland Pascal (version 7.0 or later)
    * MetaWare High C/C++ (version 3.0 or later)
    * Microsoft BASIC Professional Development System (version 7.0 or 7.1)
    * Microsoft C/C++ (version 5.1 or later)
    * Microsoft FORTRAN (version 4.0 or later)
    * Microsoft FORTRAN PowerStation (version 1.0 or later)
    * Microsoft QuickBASIC (version 4.0 or later)
    * Microsoft QuickC (version 2.0 or later)
    * Microsoft Visual Basic for DOS (version 1.0 or later)
    * Microsoft Visual C++ (version 1.0 or later)
    * Microsoft Visual C++ 32-bit Edition (version 1.0 or later)
    * Power C (version 2.0 or later)
    * Turbo C (version 2.0 or later)
    * Turbo C++ (version 1.0 or later)
    * Turbo Pascal (version 6.0 or later)
    * WATCOM C/C++ (version 9.5 or later)
    * WATCOM C32 for DOS (version 9.5 or later)
    * Zortech C++ (version 3.0 or later)

The listed version numbers are the compiler versions under which Fastgraph was developed and tested. Fastgraph may or may not work with earlier versions of these compilers. As we constantly add support for new compilers, please check the READ.ME file in the \FG directory for possible additions to the above � 4 Fastgraph User's Guide

list. The use of Fastgraph from assembly language programs is addressed in Appendix B.


Real Mode, Protected Mode, and DOS Extenders

    DOS is inherently a real mode operating system. Real mode is the native

(and only) operating mode of the 8086 and 8088 microprocessors, upon which the original IBM PC and PC/XT systems were based. While these processors provided the ability to address one megabyte of memory, IBM reserved the upper 384K of this one megabyte address space for such things as video memory and the ROM BIOS. This left a maximum of 640K for DOS applications.

    Intel's later microprocessors (80286, 80386, 80486, and Pentium) provide

a second operating mode called protected mode. Perhaps the most important aspect of protected mode is its ability to use much more memory. When running in protected mode, the 16-bit 80286 processor has a 16 megabyte addressability, while the 32-bit 80386 and later processors can address four gigabytes. Expanded and extended memory services provide limited access to this larger address space, but a program must run in protected mode if it wants to treat this memory like conventional DOS memory. Because DOS is a real mode operating system, DOS applications running on 80286 and later processors are still restricted to DOS's ubiquitous 640K barrier. In this case, these systems function merely as faster 8086 or 8088 systems.

    When a DOS-compatible protected mode operating system did not appear, DOS

extenders arrived instead. A DOS extender is a product, a "mini-operating system" if you will, that can run protected mode applications under DOS. The DOS extender accomplishes this by executing a real mode stub program that switches the processor to protected mode and passes control to your program. Your program continues to run in protected mode until it issues a BIOS or DOS service such as a file I/O request. The extender then switches back to real mode to satisfy the request, and upon completion reverts to protected mode. When your program terminates, the DOS extender switches back to real mode and returns control to DOS. This is of course an oversimplification of how a DOS extender works, but these behind the scenes tasks are transparent to your program's end users. From their perspective, an extended DOS application executes just like any ordinary DOS application.

    DOS extenders come in two flavors: 16-bit and 32-bit. Programs written

for 16-bit DOS extenders require at least an 80286-based system, while those written for 32-bit extenders require an 80386 or better. Many real mode compilers can create 16-bit extended DOS applications, but you'll need special 32-bit compilers to create 32-bit extended DOS applications. Fastgraph supports the following 16-bit DOS extenders:

    * Blinker
    * Borland Pascal 7 (built in DPMI extender)
    * Borland PowerPack for DOS
    * Phar Lap 286|Dos-Extender SDK
    * Phar Lap 286|Dos-Extender Lite
    * Rational Systems DOS/16M

Fastgraph supports the following 32-bit DOS extenders:

    * Borland PowerPack for DOS
    * CauseWay
                                                 Chapter 1:  Introduction   5
    * DOSXMSF (supplied with Microsoft FORTRAN PowerStation)                  �
    * FlashTek X-32
    * Phar Lap TNT Dos-Extender SDK (formerly 386|Dos-Extender SDK)
    * Phar Lap TNT Dos-Extender Lite
    * Rational Systems DOS/4G
    * Rational Systems DOS/4GW (supplied with 32-bit WATCOM compilers)
    * Rational Systems DOS/4GW Professional

Please check the READ.ME file in the \FG directory for possible additions to the above lists.

    Note that some DOS extenders require licensing fees or royalty payments

before you can include or bind their components with applications you distribute. We recommend checking your DOS extender manuals or license agreement for details, or if you're not sure, contacting the DOS extender manufacturer directly.

Memory Models

    Fastgraph's supported real mode C, C++, and FORTRAN compilers offer

several memory models. A memory model defines how memory is set up for a program's code and data segments. Fastgraph includes real mode libraries for the small, medium, and large memory models and protected mode libraries for 16-bit and 32-bit environments. The 16-bit protected mode libraries use an extension of the large memory model, while the 32-bit libraries use a special flat memory model.

    The small memory model allows for one code segment and one data segment.

Programs that use the small model can thus have a maximum of 64K bytes of code and 64K bytes of data. Because the small model implements call instructions and data references through near pointers, it produces the most efficient code of the three supported real mode memory models. The small memory model is specific to real mode compilers.

    The medium memory model allows for multiple code segments and one data

segment. Programs that use the medium model thus have no compiler-imposed limit to the code size (although no one segment can exceed 64K bytes) and a maximum of 64K bytes of data. Like the small model, the medium model implements data references through near pointers, but it implements call instructions through far pointers. The use of far pointers adds two bytes of code and 13 clock cycles for each subprogram call. The medium model is a popular choice for real mode programs and is specific to real mode compilers.

    The large memory model supports multiple code and data segments. Programs

that use the large model do not have any compiler-imposed limits for code and data sizes. However, no single code or data segment can exceed 64K bytes. Because the large model implements call instructions and data references through far pointers, it produces the least efficient code of the three supported memory models. In real mode, the total size of all code and data segments is limited by the DOS 640K barrier, though in reality the true limit will be somewhat less depending on the target system's configuration and resident programs. In 16-bit protected mode, the total size of all code and data segments can reach 16 megabytes, although no one segment can exceed 64K bytes.

    The flat memory model allows for one code segment and one data segment,

just like the small memory model. The flat model differs in that the segment � 6 Fastgraph User's Guide


sizes can be up to four gigabytes instead of 64K. By default, the flat model implements call instructions and data references through 32-bit near pointers, virtually eliminating the need for segments. The flat memory model is specific to 32-bit protected mode compilers.

    For more information about memory models, please refer to the user's

guide or reference manual supplied with your compiler.


Installing Fastgraph

    This section explains how to use the INSTALL program to load Fastgraph

(or Fastgraph/Light) and its related files on a hard disk. The installation program lets you select the compilers, memory models, and DOS extenders you wish to use with Fastgraph. It also gives you the opportunity to load many example Fastgraph programs specific to the compilers you choose.

    Before you start the installation, we recommend using the DOS commands

COPY or DISKCOPY to make working copies of the Fastgraph distribution disks (refer to your DOS reference manual if you are unfamiliar with these commands). Once you have created the working copies, store the original disks in a safe place. Install Fastgraph from the working copies you just created.

    For simplicity, we'll assume you are installing Fastgraph from the

diskette drive A: to the hard drive C:, but you of course can use any available drives. The Fastgraph distribution disk labeled Installation and Utilities contains Fastgraph's INSTALL program. Place this disk in the A: drive, make A: your current drive, and enter the command INSTALL, as shown here:

                                 C> A:
                                 A> INSTALL

From this point, just follow the directions on each screen. At any time, you can press the Escape key to abort the installation.

    The INSTALL program will ask you for the compilers, memory models, and

DOS extenders you'll use with Fastgraph, as well as the directory names for the Fastgraph utilities, libraries, and include files. For the utilities, the default directory is C:\FG. For the include files and libraries, we recommend using directories where the compiler you've chosen normally searches for such files. INSTALL will automatically try to determine these directories and propose them as defaults.

    You can install support for additional compilers, memory models, or DOS

extenders at any time. If you choose to do this, you should use the command INSTALL /L to avoid copying the files common to all environments.


The READ.ME File

    The READ.ME file contains additions and changes that may have been made

to Fastgraph since the publication of the manuals. We encourage you to examine the READ.ME file immediately after installing Fastgraph. READ.ME is an ASCII text file, suitable for any printer or text editor. The INSTALL program places the READ.ME file in the Fastgraph utilities directory (C:\FG by default). �

                                                 Chapter 1:  Introduction   7



The WHATS.NEW File

    The WHATS.NEW file contains information about new features added in

Fastgraph version 4.0. Programmers who've used earlier versions of Fastgraph may want to examine the WHATS.NEW file to learn about Fastgraph's new functionality and possible changes needed when converting applications to version 4.0. WHATS.NEW is an ASCII text file, suitable for any printer or text editor. The INSTALL program places the WHATS.NEW file in the Fastgraph utilities directory (C:\FG by default).


Fastgraph Naming Conventions

    The names of all Fastgraph routines begin with the three characters

"fg_". This prefix helps identify Fastgraph routines within a program, and it also reduces the chance of name conflicts that might otherwise occur between Fastgraph and other third party libraries.

    Because BASIC does not permit underscores in identifiers, the BASIC

versions of Fastgraph routines begin with the two characters "FG". For example, the fg_version routine is named FGversion in the BASIC libraries. All future references to Fastgraph routines in the Fastgraph User's Guide and the Fastgraph Reference Manual will use the fg_ naming convention instead of the BASIC names.


Compilation and Linking

    To build an executable (EXE) file for a program that uses Fastgraph

routines, first compile or assemble the program using one of the supported memory models. This step produces an object file, which you then link with one or more Fastgraph libraries (or Pascal unit files) and possibly other libraries to produce an executable file. When creating protected mode executables, additional binding steps may be needed as described in your compiler or DOS extender manuals. The Fastgraph libraries or Pascal unit files must reside in a directory where the linker normally searches for such files.

    Example 1-1 uses the Fastgraph routine fg_version to display the version

number for your copy of Fastgraph. It also uses one other Fastgraph routine, fg_initpm, to set up Fastgraph's protected mode kernel for the selected DOS extender (when using the real mode Fastgraph libraries, fg_initpm does nothing). Versions of this program are presented for each high-level language Fastgraph supports: C/C++, BASIC, FORTRAN, and Pascal. If you loaded the example programs when you installed Fastgraph, the files \FG\EXAMPLES\01-01.C, 01-01.BAS, 01-01.FOR, and 01-01.PAS contain the source code for these examples. You can use them to test the compilation and linking process for the compilers you'll be using with Fastgraph.

                        Example 1-1 (C/C++ version).
     #include <fastgraf.h>
     #include <stdio.h>
     void main(void);                                                         �

8 Fastgraph User's Guide


     void main()
     {
        int major;
        int minor;
        fg_initpm();
        fg_version(&major,&minor);
        printf("This is version %d.%2.2d of Fastgraph.\n",major,minor);
     }


    The header file FASTGRAF.H contains the C and C++ function prototypes for

each Fastgraph routine. It must reside in a directory where the compiler normally searches for other header files. When creating 32-bit protected mode applications, FASTGRAF.H will define the symbol FG32. This symbol is useful for controlling conditional compilation when creating applications that run in both 16-bit and 32-bit environments.

                        Example 1-1 (BASIC version).
         REM $INCLUDE: 'fastgraf.bi'
         DEFINT A-Z
         FGversion Major, Minor
         Version! = Major + Minor*0.01
         PRINT USING "This is version #.## of Fastgraph."; Version!
         END


    You must include the DECLARE commands in the file FASTGRAF.BI at the

beginning of each BASIC module. This file should reside in a directory where the compiler normally searches for BI files, or in any of the directories specified by the INCLUDE environment variable. The DECLARE commands in this file automatically provide the calling convention and naming convention for each Fastgraph routine. In addition, they relieve the BASIC programmer of distinguishing arguments passed by value from those passed by reference.

                       Example 1-1 (FORTRAN version).
     $INCLUDE: '\FG\FASTGRAF.FI'
           PROGRAM MAIN
           INTEGER MAJOR
           INTEGER MINOR
           CALL FG_INITPM
           CALL FG_VERSION (MAJOR, MINOR)
           WRITE (6,10) MAJOR, MINOR
     10    FORMAT (' This is version ', I1, '.', I2.2, ' of Fastgraph.')
           STOP ' '                                                           �
                                                 Chapter 1:  Introduction   9


           END


    You must include the INTERFACE statements in the file FASTGRAF.FI at the

beginning of FORTRAN programs (this file should reside in the \FG directory). The INTERFACE statements in this file automatically provide the calling convention and naming convention for each Fastgraph routine. In addition, they relieve the FORTRAN programmer of distinguishing arguments passed by value from those passed by reference.

                        Example 1-1 (Pascal version).
      program main;
      uses fgmain;
      var
        Major : integer;
        Minor : integer;
      begin
        fg_initpm;
        fg_version(Major,Minor);
        writeln('This is version ',Major,'.',Minor:2,' of Fastgraph.');
      end.


    Pascal programs that use Fastgraph or Fastgraph/Light must include a uses

statement specifying the names of the unit files (TPU or TPP files) needed in the program. This list must always include the fgmain unit; for protected mode programs that call GlobalAllocPtr, GlobalFreePtr, or other functions in WinAPI, it also must include the WinAPI unit. All unit files must reside in a directory where the compiler normally searches for such files. Appendix E lists the Fastgraph functions in each unit.

    The following sections show the simplest procedures for compiling a

program and linking it with Fastgraph. Information is presented for each supported compiler, listed alphabetically by the compiler name. In what follows, items enclosed in angle brackets, such as <source_file>, are placeholders for parameters you must supply (the name of a file in this case). Items enclosed in square brackets, such as [/E], are optional. For simplicity, we'll only show the Fastgraph library names. If you're using Fastgraph/Light, the library names will begin with "FGL" instead of "FG". For example, FGS.LIB is the real mode small model Fastgraph for most C compilers, while FGLS.LIB is the equivalent library for Fastgraph/Light. Note that Fastgraph/Light does not support protected mode environments. � 10 Fastgraph User's Guide


Borland C++

    Borland C++ can create real mode, 16-bit protected mode, and 32-bit

protected mode applications (Borland C++ 4.0 or later is required for 32-bit protected mode). You can compile and link programs directly from the DOS command line or from the Borland C++ integrated development environment (IDE). The following Fastgraph libraries are compatible with Borland C++:

    FGS.LIB        Real mode small model general library
    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGTCS.LIB      Real mode small model auxiliary library
    FGTCM.LIB      Real mode medium model auxiliary library
    FGTCL.LIB      Real mode large model auxiliary library
    FG16.LIB       16-bit protected mode general library
    FG16BC.LIB     16-bit protected mode auxiliary library
    FG16DPMI.LIB   16-bit DPMI-compliant DOS extender support library
    FG16PHAR.LIB   Phar Lap 286|Dos-Extender support library
    FG32.LIB       32-bit protected mode general library
    FG32BC.LIB     32-bit protected mode auxiliary library
    FG32DPMI.LIB   32-bit DPMI-compliant DOS extender support library
    FG32PHAR.LIB   Phar Lap TNT|Dos-Extender support library
    To build real mode Fastgraph applications in the Borland C++ IDE, the

compiler options must match one of Fastgraph's available memory models (small, medium, or large). 16-bit protected mode programs must use the large memory model, while 32-bit protected mode programs must be compiled as console applications. In any case, you also must create a project file that includes the name of each C, CPP, and LIB file required by your application (refer to your Borland C++ manuals for information about project files). For Borland C++ 4.0 and above, the project file also specifies the platform: DOS for real mode applications, DOS (16-bit DPMI) for 16-bit protected mode applications, or DOS (32-bit DPMI) for 32-bit protected mode applications. Project files are only needed when using the IDE.

    You can also compile and link programs from the DOS command line using

the BCC or BCC32 commands. Here are example BCC and BCC32 commands for compiling a Borland C++ program and linking it with Fastgraph. The compiler- specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D.

    Real mode, small memory model:
       BCC -ms <source_file> FGS.LIB [FGTCS.LIB]
    Real mode, medium memory model:
       BCC -mm <source_file> FGM.LIB [FGTCM.LIB]
    Real mode, large memory model:
       BCC -ml <source_file> FGL.LIB [FGTCL.LIB]
    16-bit protected mode, Borland PowerPack DOS extender:
       BCC -ml -WX <source_file> FG16.LIB FG16DPMI.LIB [FG16BC.LIB]
    16-bit protected mode, Phar Lap 286|Dos-Extender:
       BCC286 <source_file> FG16.LIB FG16PHAR.LIB [FG16BC.LIB]                �
                                                Chapter 1:  Introduction   11


    32-bit protected mode, Borland PowerPack DOS extender:
       BCC32 -WX <source_file> FG32.LIB FG32DPMI.LIB [FG32BC.LIB]

To create Borland C++ 16-bit protected mode programs using the Rational Systems DOS/16M extender, please refer to the DOS/16M User's Guide. To create Borland C++ 32-bit protected mode programs using the Phar Lap TNT|Dos-Extender, please refer to Phar Lap's C/C++ User's Guide to TNT Dos-Extender.

    For more information about memory models or other compilation and linking

options, please refer to the Borland C++ User's Guide, Borland PowerPack for DOS User's Guide, Phar Lap's Borland C++ User's Guide to 286 Dos-Extender, or the DOS/16M User's Guide. � 12 Fastgraph User's Guide


Borland Pascal

    Borland Pascal can create real mode and 16-bit protected mode

applications. Protected mode applications can be built without a third party DOS extender, as the necessary protected mode extensions are implemented through a DOS Protected Mode Interface (DPMI) server and a run-time manager. You can compile real mode and protected mode programs directly from the DOS command line or from the Borland Pascal integrated development environment (IDE).

    To build Fastgraph applications in the Borland Pascal IDE, just start the

IDE as you would for any other Pascal program, making sure the Fastgraph unit files reside in one of the directories listed in the IDE's "Unit Directories" option. If you're creating a protected mode application from the IDE, choose Compile|Target and select "Protected-mode Application" from the Target Platform dialog box.

    You can also compile Borland Pascal programs from the DOS command line

using the BPC or TPC commands, as shown here. Real mode programs can use either BPC or TPC, while protected mode programs must use BPC.

    Real mode:
       BPC <source_file>
       TPC <source_file>
    16-bit protected mode:
       BPC /CP <source_file>
    For more information about other compilation and linking options, please

refer to the Borland Pascal With Objects User's Guide.

    All remaining example programs in the Fastgraph User's Guide are written

in the C programming language. However, when you install Fastgraph for Borland Pascal, the installation procedure copies Pascal versions of the example programs to the \FG\EXAMPLES directory. �

                                                Chapter 1:  Introduction   13


MetaWare High C/C++

    MetaWare High C/C++ is strictly a 32-bit protected mode compiler. It

supports the Phar Lap TNT|Dos-Extender SDK and the Rational Systems DOS/4G extender. The following Fastgraph libraries are compatible with MetaWare High C/C++:

    FG32.LIB       32-bit protected mode general library
    FG32HC.LIB     32-bit protected mode auxiliary library
    FG32DPMI.LIB   32-bit DPMI-compliant DOS extender support library
    FG32PHAR.LIB   Phar Lap TNT|Dos-Extender support library
    Programs are compiled and linked from the DOS command line using the

HC386 command. Here are example HC386 commands for compiling a MetaWare High C/C++ program and linking it with Fastgraph. The compiler-specific auxiliary library (FG32HC) only needs to be included when your program uses any of the Fastgraph routines listed in Appendix D.

    32-bit protected mode, Phar Lap TNT|Dos-Extender:
       HC386 <source_file> -lFG32 -lFG32PHAR [-lFG32HC] -nomap -onecase
    32-bit protected mode, Rational Systems DOS/4G extender:
       HC386 <source_file> -Hdos4g -lFG32 -lFG32DPMI [-lFG32HC]
    For more information about other compilation and linking options, please

refer to the MetaWare High C/C++ Programmer's Guide, Phar Lap's C/C++ User's Guide to TNT Dos-Extender, or the DOS/4G User's Manual. � 14 Fastgraph User's Guide


Microsoft BASIC Professional Development System

    You can compile and link Microsoft BASIC Professional Development System

(PDS) programs directly from the DOS command line or from the PDS programming environment. In either case, BASIC PDS always creates real mode programs. The following Fastgraph libraries are compatible with BASIC PDS:

    FGQBX.LIB      Stand-alone library for BASIC PDS
    FGQBX.QLB      Quick library for BASIC PDS
    To build Fastgraph applications in the PDS programming environment, just

specify the quick library name FGQBX when starting BASIC PDS:

       QBX /LFGQBX [<source_file>]

You must use the default "Far Strings" setting within the PDS environment. There are no near string Fastgraph libraries available for BASIC PDS.

    To compile a BASIC PDS program from the DOS command line and link it with

Fastgraph, use the BC and LINK commands:

       BC /Fs [/O] <source_file>;
       LINK [/E] <object_file>,,NUL,FGQBX;

The /O option on the BC command is recommended because it creates EXE files that do not require the BASIC PDS run-time module. The /E linker option is not required but will produce a smaller EXE file if specified. For more information about other compilation and linking options, please refer to the Microsoft BASIC Professional Development System Programmer's Guide.

    All remaining example programs in the Fastgraph User's Guide are written

in the C programming language. However, when you install Fastgraph for Microsoft BASIC PDS, the installation procedure copies BASIC versions of the example programs to the \FG\EXAMPLES directory. �

                                                Chapter 1:  Introduction   15


Microsoft C/C++

    Microsoft C/C++ can create real mode and 16-bit protected mode

applications. For protected mode, it supports the Phar Lap 286|Dos-Extender (both SDK and Lite versions) and the Rational Systems DOS/16M extender. The following Fastgraph libraries are compatible with Microsoft C/C++:

    FGS.LIB        Real mode small model general library
    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGMSCS.LIB     Real mode small model auxiliary library
    FGMSCM.LIB     Real mode medium model auxiliary library
    FGMSCL.LIB     Real mode large model auxiliary library
    FG16.LIB       16-bit protected mode general library
    FG16MSC.LIB    16-bit protected mode auxiliary library
    FG16DPMI.LIB   16-bit DPMI-compliant DOS extender support library
    FG16PHAR.LIB   Phar Lap 286|Dos-Extender support library
    Programs are compiled and linked from the DOS command line using the CL

command. Here are example CL commands for compiling a Microsoft C/C++ program and linking it with Fastgraph. The compiler-specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D. In the real mode examples, the /E linker option is not required but will produce a smaller EXE file if specified.

    Real mode, small memory model:
       CL /AS <source_file> /link FGS.LIB [FGMSCS.LIB] [/E]
    Real mode, medium memory model:
       CL /AM <source_file> /link FGM.LIB [FGMSCM.LIB] [/E]
    Real mode, large memory model:
       CL /AL <source_file> /link FGL.LIB [FGMSCL.LIB] [/E]
    16-bit protected mode, Phar Lap 286 SDK or Lite extender:
       CL /AL /Lp <source_file> /link FG16.LIB FG16PHAR.LIB [FG16MSC.LIB]

To create Microsoft C/C++ protected mode programs using the Rational Systems DOS/16M extender, please refer to the DOS/16M User's Guide.

    For more information about memory models or other compilation and linking

options, please refer to the Microsoft C Optimizing Compiler User's Guide, Phar Lap's Microsoft C & C++ User's Guide to 286|Dos-Extender, or the DOS/16M User's Guide. � 16 Fastgraph User's Guide


Microsoft FORTRAN

    Microsoft FORTRAN creates real mode applications. The following Fastgraph

libraries are compatible with Microsoft FORTRAN:

    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGMSFM.LIB     Real mode medium model auxiliary library
    FGMSFL.LIB     Real mode large model auxiliary library
    Programs are compiled and linked from the DOS command line using the FL

command. Here are example FL commands for compiling a Microsoft FORTRAN program and linking it with Fastgraph. The compiler-specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D. The /E linker option is not required but will produce a smaller EXE file if specified.

    Medium memory model:
       FL /AM /FPi /4I2 /4Nt <source_file> /link FGM.LIB [FGMSFM.LIB] [/E]
    Large memory model:
       FL /AL /FPi /4I2 /4Nt <source_file> /link FGL.LIB [FGMSFL.LIB] [/E]
    For more information about memory models or other compilation and linking

options, please refer to the Microsoft FORTRAN Optimizing Compiler User's Guide.

    All remaining example programs in the Fastgraph User's Guide are written

in the C programming language. However, when you install Fastgraph for the Microsoft FORTRAN compiler, the installation procedure copies FORTRAN versions of the example programs to the \FG\EXAMPLES directory. �

                                                Chapter 1:  Introduction   17


Microsoft FORTRAN PowerStation

    Microsoft FORTRAN PowerStation is strictly a 32-bit protected mode

compiler. It supports the DOSXMSF DOS extender included with the compiler and the Phar Lap TNT|Dos-Extender SDK (DOSXMSF is a subset of the TNT|Dos-Extender). The following Fastgraph library is compatible with Microsoft FORTRAN PowerStation:

    FG32MSF.LIB    32-bit PM library for Microsoft FORTRAN PowerStation

FG32MSF.LIB includes Fastgraph's Phar Lap support functions normally found in the FG32PHAR.LIB library.

    Programs are compiled and linked from the DOS command line using the FL32

command:

       FL32 <source_file> FG32MSF.LIB

This command invokes the PowerStation compiler and Microsoft Portable Executable Linker (LINK32) to create a 32-bit protected mode executable.

    For more information about other compilation and linking options, please

refer to the Microsoft FORTRAN PowerStation User's Guide or Phar Lap's FORTRAN User's Guide to TNT Dos-Extender. � 18 Fastgraph User's Guide


Microsoft QuickBASIC

    You can compile and link Microsoft QuickBASIC programs directly from the

DOS command line or from the QuickBASIC programming environment. In either case, QuickBASIC always creates real mode programs. The following Fastgraph libraries are compatible with QuickBASIC:

    FGQB.LIB       Stand-alone library for QuickBASIC
    FGQB.QLB       Quick library for QuickBASIC
    To build Fastgraph applications in QuickBASIC's programming environment,

just specify the quick library name FGQB when starting QuickBASIC:

       QB /LFGQB [<source_file>]

To compile a QuickBASIC program from the DOS command line and link it with Fastgraph, use the BC and LINK commands:

       BC [/O] <source_file>;
       LINK [/E] <object_file>,,NUL,FGQB;

The /O option on the BC command is recommended because it creates EXE files that do not require the QuickBASIC run-time module. The /E linker option is not required but will produce a smaller EXE file if specified. For more information about other compilation and linking options, please refer to the Microsoft QuickBASIC: Programming in BASIC manual.

    All remaining example programs in the Fastgraph User's Guide are written

in the C programming language. However, when you install Fastgraph for Microsoft QuickBASIC, the installation procedure copies BASIC versions of the example programs to the \FG\EXAMPLES directory. �

                                                Chapter 1:  Introduction   19


Microsoft QuickC

    You can compile and link Microsoft QuickC programs directly from the DOS

command line or from the QuickC programming environment. In either case, QuickC always creates real mode programs. The following Fastgraph libraries are compatible with QuickC:

    FGS.LIB        Real mode small model general library
    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGMSCS.LIB     Real mode small model auxiliary library
    FGMSCM.LIB     Real mode medium model auxiliary library
    FGMSCL.LIB     Real mode large model auxiliary library
    To build Fastgraph applications in the QuickC programming environment,

you must make sure the compiler options match one of Fastgraph's available memory models (small, medium, or large) and then create a make file that includes the corresponding Fastgraph library names.

    To compile a QuickC program from the DOS command line and link it with

Fastgraph, use the QCL command. Here are example QCL commands for compiling a QuickC program and linking it with Fastgraph. The compiler-specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D. The /E linker option is not required but will produce a smaller EXE file if specified.

    Small memory model:
       QCL /AS <source_file> /link FGS.LIB [FGMSCS.LIB] [/E]
    Medium memory model:
       QCL /AM <source_file> /link FGM.LIB [FGMSCM.LIB] [/E]
    Large memory model:
       QCL /AL <source_file> /link FGL.LIB [FGMSCL.LIB] [/E]
    For more information about make files, memory models, or other

compilation and linking options, please refer to the Microsoft QuickC Tool Kit manual. � 20 Fastgraph User's Guide


Microsoft Visual Basic for DOS

    You can compile and link Microsoft Visual Basic for DOS programs directly

from the DOS command line or from the Visual Basic programming environment. In either case, Visual Basic always creates real mode programs. The following Fastgraph libraries are compatible with Visual Basic:

    FGVBDOS.LIB    Stand-alone library for Visual Basic
    FGVBDOS.QLB    Quick library for Visual Basic
    To build Fastgraph applications in Visual Basic's programming

environment, just specify the quick library name FGVBDOS when starting Visual Basic:

       VBDOS /LFGVBDOS [<source_file>]

When using the programming environment, you may get an "Out of Memory" or "Out of String Space" error message when trying to build an EXE file or run an application within the environment. Should this occur, you must specify the /S option on the VBDOS command line to increase the amount of memory available to your application. If you have EMS or XMS memory installed on your system, it's also useful to specify the /E or /X options to make portions of the programming environment resident in EMS or XMS. For more information about these options, refer to Appendix B of the Microsoft Visual Basic Programmer's Guide.

    To compile a Visual Basic program from the DOS command line and link it

with Fastgraph, use the BC and LINK commands:

       BC [/O] <source_file>;
       LINK [/E] <object_file>,,NUL,FGVBDOS;

The /O option on the BC command is recommended because it creates EXE files that do not require the Visual Basic run-time module. The /E linker option is not required but will produce a smaller EXE file if specified. For more information about other compilation and linking options, please refer to the Microsoft Visual Basic Programmer's Guide.

    When linking Visual Basic for DOS programs that call Fastgraph's world

space or software character routines (that is, any of the routines listed in Appendix D), you may need to increase the number of segments available to the linker. Use the /SEG:n option on the LINK command to do this. The default value of n is 128 segments; usually a slightly larger value, such as 144, will be enough.

    All remaining example programs in the Fastgraph User's Guide are written

in the C programming language. However, when you install Fastgraph for Visual Basic, the installation procedure copies BASIC versions of the example programs to the \FG\EXAMPLES directory. �

                                                Chapter 1:  Introduction   21


Microsoft Visual C++

    Microsoft Visual C++ can create real mode and 16-bit protected mode

applications. For protected mode, it supports the Phar Lap 286|Dos-Extender (both SDK and Lite versions) and the Rational Systems DOS/16M extender. The following Fastgraph libraries are compatible with Visual C++:

    FGS.LIB        Real mode small model general library
    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGMSCS.LIB     Real mode small model auxiliary library
    FGMSCM.LIB     Real mode medium model auxiliary library
    FGMSCL.LIB     Real mode large model auxiliary library
    FG16.LIB       16-bit protected mode general library
    FG16MSC.LIB    16-bit protected mode auxiliary library
    FG16DPMI.LIB   16-bit DPMI-compliant DOS extender support library
    FG16PHAR.LIB   Phar Lap 286|Dos-Extender support library
    Programs are compiled and linked from the DOS command line using the CL

command. Here are example CL commands for compiling a Visual C++ program and linking it with Fastgraph. The compiler-specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D. In the real mode examples, the /E linker option is not required but will produce a smaller EXE file if specified.

    Real mode, small memory model:
       CL /AS <source_file> /link FGS.LIB [FGMSCS.LIB] [/E]
    Real mode, medium memory model:
       CL /AM <source_file> /link FGM.LIB [FGMSCM.LIB] [/E]
    Real mode, large memory model:
       CL /AL <source_file> /link FGL.LIB [FGMSCL.LIB] [/E]
    16-bit protected mode, Phar Lap 286 SDK or Lite extender:
       CL /AL /Lp <source_file> /link FG16.LIB FG16PHAR.LIB [FG16MSC.LIB]

To create Visual C++ protected mode programs using the Rational Systems DOS/16M extender, please refer to the DOS/16M User's Guide.

    For more information about memory models or other compilation and linking

options, please refer to the Visual C++ Command-Line Utilities User's Guide, Phar Lap's Microsoft C & C++ User's Guide to 286|Dos-Extender, or the DOS/16M User's Guide. � 22 Fastgraph User's Guide


Microsoft Visual C++ 32-bit Edition

    As its name suggests, Microsoft Visual C++ 32-bit Edition is strictly a

32-bit protected mode compiler. It supports the Phar Lap TNT|Dos-Extender SDK and the Phar Lap TNT|Dos-Extender Lite. The following Fastgraph library is compatible with the 32-bit Edition of Visual C++:

    FG32VC.LIB     32-bit PM library for Microsoft Visual C++ 32-bit Edition

FG32VC.LIB includes Fastgraph's Phar Lap support functions normally found in the FG32PHAR.LIB library.

    There are two basic methods of creating 32-bit protected mode executables

with Visual C++ 32-bit Edition. The first method compiles and links the program in a single command and uses the Microsoft 32-bit linker:

       CL <source_file> /link /stub:\TNT\BIN\GOTNT.EXE FG32VC.LIB

The second method compiles and links the program in separate commands and uses Phar Lap's 386|Link utility:

       CL /c <source_file>
       386LINK <obj_file> @MSVC32.DOS -lib FG32VC -nomap -onecase

The Phar Lap linker has problems with Fastgraph's world space routines. If your program uses any of the Fastgraph routines listed in Appendix D, you should use the Microsoft 32-bit linker.

    For more information about other compilation and linking options, please

refer to Phar Lap's C/C++ User's Guide to TNT Dos-Extender. �

                                                Chapter 1:  Introduction   23


Power C

    Power C is an inexpensive real mode command-line compiler. The following

Fastgraph libraries are compatible with Power C:

    FGS.MIX        Small model general library
    FGM.MIX        Medium model general library
    FGL.MIX        Large model general library
    FGPCS.MIX      Small model auxiliary library
    FGPCM.MIX      Medium model auxiliary library
    FGPCL.MIX      Large model auxiliary library
    To compile a Power C program from the DOS command line and link it with

Fastgraph, use the PC and PCL commands. Here are example command sequences for compiling a Power C program and linking it with Fastgraph. The compiler- specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D.

    Small memory model:
       PC /ms <source_file>
       PCL <mix_file> ;FGS [;FGPCS]
    Medium memory model:
       PC /mm <source_file>
       PCL <mix_file> ;FGM [;FGPCM]
    Large memory model:
       PC /ml <source_file>
       PCL <mix_file> ;FGL [;FGPCL]

For more information about memory models or other compilation and linking options, please refer to the Power C manual, published by Mix Software, Inc. � 24 Fastgraph User's Guide


Turbo C and Turbo C++

    Turbo C and Turbo C++ can create real mode and 16-bit protected mode

applications. For protected mode, only the Rational Systems DOS/16M extender is supported. You can compile and link programs directly from the DOS command line or from the Turbo C/C++ integrated development environment (IDE). The following Fastgraph libraries are compatible with Turbo C/C++:

    FGS.LIB        Real mode small model general library
    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGTCS.LIB      Real mode small model auxiliary library
    FGTCM.LIB      Real mode medium model auxiliary library
    FGTCL.LIB      Real mode large model auxiliary library
    FG16.LIB       16-bit protected mode general library
    FG16BC.LIB     16-bit protected mode auxiliary library
    FG16DPMI.LIB   16-bit DPMI-compliant DOS extender support library
    To build Fastgraph applications in the Turbo C/C++ IDE, the compiler

options must match one of Fastgraph's available memory models (small, medium, or large). You also must create a project file that includes the name of each C, CPP, and LIB file required by your application (refer to your Turbo C or Turbo C++ manuals for information about project files). Project files are only needed when using the IDE.

    You can also compile and link programs from the DOS command line using

the TCC command. Here are example TCC commands for compiling a Turbo C or Turbo C++ program and linking it with Fastgraph. The compiler-specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D.

    Real mode, small memory model:
       TCC -ms <source_file> FGS.LIB [FGTCS.LIB]
    Real mode, medium memory model:
       TCC -mm <source_file> FGM.LIB [FGTCM.LIB]
    Real mode, large memory model:
       TCC -ml <source_file> FGL.LIB [FGTCL.LIB]

To create Turbo C/C++ protected mode programs using the Rational Systems DOS/16M extender, please refer to the DOS/16M User's Guide.

    For more information about memory models or other compilation and linking

options, please refer to the Turbo C User's Guide, Turbo C Reference Guide, or the DOS/16M User's Guide. �

                                                Chapter 1:  Introduction   25


Turbo Pascal

    Turbo Pascal can build real mode programs directly from the DOS command

line or from the Turbo Pascal integrated development environment (IDE).

    To build Fastgraph applications in the Turbo Pascal IDE, just start the

IDE as you would for any other Pascal program, making sure the Fastgraph unit files reside in one of the directories listed in the IDE's "Unit Directories" option.

    You also can compile Turbo Pascal programs from the DOS command line

using the TPC command, as shown here:

       TPC <source_file>

For more information about other compilation and linking options, please refer to the Turbo Pascal User's Guide.

    All remaining example programs in the Fastgraph User's Guide are written

in the C programming language. However, when you install Fastgraph for Turbo Pascal, the installation procedure copies Pascal versions of the example programs to the \FG\EXAMPLES directory. � 26 Fastgraph User's Guide


WATCOM C/C++ WATCOM C32 for DOS

    WATCOM C/C++ and WATCOM C32 for DOS both are 16-bit real mode and 32-bit

protected mode compilers (for simplicity, we'll use the term WATCOM C/C++ to refer to either compiler). Both compilers support the DOS/4G, DOS/4GW, and DOS/4GW Professional DOS extenders from Rational Systems (DOS/4GW is supplied with both compilers), as well as the Phar Lap TNT|Dos-Extender SDK. The following Fastgraph libraries are compatible with the WATCOM compilers:

    FGS.LIB        Real mode small model general library
    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGWCS.LIB      Real mode small model auxiliary library
    FGWCM.LIB      Real mode medium model auxiliary library
    FGWCL.LIB      Real mode large model auxiliary library
    FG32.LIB       32-bit protected mode general library
    FG32WC.LIB     32-bit protected mode auxiliary library
    FG32DPMI.LIB   32-bit DPMI-compliant DOS extender support library
    FG32PHAR.LIB   Phar Lap TNT|Dos-Extender support library
    Programs are compiled and linked from the DOS command line using the WCL

or WCL386 commands. Here are example commands for compiling a WATCOM C/C++ program and linking it with Fastgraph. The compiler-specific auxiliary libraries (FGWCS, FGWCM, FGWCL, and FG32WC) only need to be included when your program uses any of the Fastgraph routines listed in Appendix D.

Real mode, small memory model:

    WCL /ms <source_file> FGS.LIB [FGWCS.LIB]

Real mode, medium memory model:

    WCL /mm <source_file> FGM.LIB [FGWCM.LIB]

Real mode, large memory model:

    WCL /ml <source_file> FGL.LIB [FGWCL.LIB]

32-bit protected mode, any Rational Systems DOS/4G extender:

    WCL386 /l=dos4g <source_file> FG32.LIB FG32DPMI.LIB [FG32WC.LIB]

32-bit protected mode, Phar Lap TNT|Dos-Extender:

    WCL386 /l=pharlap <source_file> FG32.LIB FG32PHAR.LIB [FG32WC.LIB]
    For more information about other compilation and linking options, please

refer to the WATCOM C/C++ User's Guide, Phar Lap's C/C++ User's Guide to TNT Dos-Extender, or the DOS/4G User's Manual. �

                                                Chapter 1:  Introduction   27


Zortech C++

    Zortech C++ creates real mode applications. The following Fastgraph

libraries are compatible with Zortech C++:

    FGS.LIB        Real mode small model general library
    FGM.LIB        Real mode medium model general library
    FGL.LIB        Real mode large model general library
    FGZCS.LIB      Real mode small model auxiliary library
    FGZCM.LIB      Real mode medium model auxiliary library
    FGZCL.LIB      Real mode large model auxiliary library
    Programs are compiled and linked from the DOS command line using the ZTC

command. Here are example ZTC commands for compiling a Zortech C++ program and linking it with Fastgraph. The compiler-specific auxiliary library names only need to be included when your program uses any of the Fastgraph routines listed in Appendix D.

    Small memory model:
       ZTC -ms <source_file> FGS.LIB [FGZCS.LIB]
    Medium memory model:
       ZTC -mm <source_file> FGM.LIB [FGZCM.LIB]
    Large memory model:
       ZTC -ml <source_file> FGL.LIB [FGZCL.LIB]

For more information about memory models or other compilation and linking options, please refer to the manuals supplied with your Zortech C++ compiler. � 28 Fastgraph User's Guide


Fastgraph/Light Video Driver

    As mentioned earlier, running any program created with Fastgraph/Light

requires an external program called the Fastgraph/Light Video Driver. The video driver is a terminate and stay resident program (TSR) that provides an interface between your program and Fastgraph.

    To load the video driver, enter the command FGDRIVER at the DOS command

prompt (assuming FGDRIVER.EXE is in the current directory, or the \FG directory is in your DOS path specification). The driver will display a message indicating whether or not it loaded successfully. After you load the driver, just run a program created with Fastgraph/Light as you would any other program. If you try running a program that uses Fastgraph/Light without first loading the video driver, the message "Fastgraph/Light video driver not installed" will appear.

    You don't need to load the driver before running each program, just once

per system boot (in fact, the driver will display an "already loaded" message if you try to load it more than once). If you want to unload the video driver, just enter FGDRIVER /U at the DOS command prompt. The unload operation will work completely only if the video driver was the last TSR loaded. If it wasn't the last TSR, the driver will still unload, but the memory it uses will not be released back to DOS.




Chapter 2



PC and PS/2 Video Modes � 30 Fastgraph User's Guide


Overview

    In the PC and PS/2 worlds, video modes determine the way information

appears on the computer's display screen. The available video modes have different resolutions, different character or pixel attributes, different video memory structures, and other inherent hardware differences. However, you do not need an in-depth knowledge of these video internals, because Fastgraph handles the necessary details.

    The PC and PS/2 video modes may be separated into two major classes: text

modes and graphics modes. In text modes, the display screen is divided into character cells. By default, there are 25 rows and either 40 or 80 columns of cells, and in each cell we can store any of the 256 characters in the IBM PC character set. Each character has an associated attribute that determines such things as its foreground color, its background color, and whether or not the character blinks. In graphics modes, the display screen is divided into picture elements, or pixels. Depending on the video mode, the number of pixel rows ranges between 200 and 768, while the number of columns ranges between 320 and 1,024. Each pixel has an associated value that determines the color of the pixel. The number of character cells or pixels available is called the resolution of the screen.

    The display adapter (graphics card) and the video display (monitor)

connected to it determine the video modes available on a given system. The following table summarizes the characteristics of the PC and PS/2 video modes that Fastgraph supports.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
    0    T       40x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    1    T       40x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    2    T       80x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    3    T       80x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    4    G      320x200      4    CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    5    G      320x200      4    CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    6    G      640x200    2/16   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    7    T       80x25      b/w   MDA,HGC,EGA,VGA,SVGA        Monochrome
    9    G      320x200     16       Tandy 1000,PCjr             RGB
   11    G      720x348     b/w            HGC                Monochrome
   12    G      320x200     b/w            HGC                Monochrome
   13    G      320x200     16        EGA,VGA,SVGA         RGB,ECD,VGA,SVGA
   14    G      640x200     16        EGA,VGA,SVGA         RGB,ECD,VGA,SVGA
   15    G      640x350     b/w       EGA,VGA,SVGA          Mono,VGA,SVGA
   16    G      640x350    16/64      EGA,VGA,SVGA           ECD,VGA,SVGA
   17    G      640x480   2/256K      VGA,MCGA,SVGA            VGA,SVGA
   18    G      640x480   16/256K       VGA,SVGA               VGA,SVGA
   19    G      320x200  256/256K     VGA,MCGA,SVGA            VGA,SVGA
   20    G      320x200  256/256K       VGA,SVGA               VGA,SVGA
   21    G      320x400  256/256K       VGA,SVGA               VGA,SVGA
   22    G      320x240  256/256K       VGA,SVGA               VGA,SVGA
   23    G      320x480  256/256K       VGA,SVGA               VGA,SVGA
   24    G      640x400  256/256K         SVGA                   SVGA
   25    G      640x480  256/256K         SVGA                   SVGA
   26    G      800x600  256/256K         SVGA                   SVGA         �
                                     Chapter 2:  PC and PS/2 Video Modes   31


   27    G     1024x768  256/256K         SVGA                   SVGA
   28    G      800x600   16/256K         SVGA                   SVGA
   29    G     1024x768   16/256K         SVGA                   SVGA
    Some notes about the format and abbreviations used in this table are in

order. In the "type" column, "T" means a text mode and "G" means a graphics mode. A single value in the "number of colors" column refers to the number of colors available in that video mode. In text modes, a pair of numbers such as 16/8 means each displayed character can have one of 16 foreground colors and one of 8 background colors. In graphics modes, a pair of numbers such as 16/64 means 16 colors can be displayed simultaneously from a collection, or palette, of 64. The "b/w" listed in the monochrome modes stands for "black and white". Characters or pixels in these video modes do not really have associated colors but instead have display attributes such as blinking or different intensities.

    The meanings of the abbreviations in the "supported adapters" and

"supported displays" columns are:

    CGA       Color Graphics Adapter
    ECD       Enhanced Color Display
    EGA       Enhanced Graphics Adapter
    HGC       Hercules Graphics Card
    MCGA      Multi-Color Graphics Array
    MDA       Monochrome Display Adapter
    RGB       Red-Green-Blue Color Display
    SVGA      SuperVGA
    VGA       Video Graphics Array

The use of the term "VGA" in the "supported display" column refers to any analog display, such as a VGA or Multisync monitor. The term "SVGA" refers explicitly to a SuperVGA monitor or adapter.

    The IBM PS/2 systems do not have a traditional adapter and display

combination. Instead, the video hardware in these systems is called the video subsystem. The Model 25 and Model 30 have an MCGA-based video subsystem, while other models have a VGA-based video subsystem. From Fastgraph's perspective, the PS/2 video subsystem is no different from an ordinary VGA card and monitor.

    This rest of this chapter will provide an overview of the most important

features and restrictions of each video mode. The first section will discuss the text modes, while the following section will discuss the graphics modes.


Text Modes

    There are five text video modes in the IBM PC and PS/2 family. Four of

these modes (0, 1, 2, and 3) are designed for color displays, while the remaining mode (7) is designed for monochrome displays. All text modes were introduced with the original IBM PC.

    In text modes, the screen is divided into character cells. There are two

bytes of video memory associated with each character cell -- one byte for the character's ASCII value, and another for the character's display attribute. The amount of video memory required to store one screen of information (called a video page) is thus � 32 Fastgraph User's Guide


                   number_of_columns x number_of_rows x 2

All text modes use 25 rows, so for the 40-column modes (0 and 1) the size of a video page is 2,000 bytes, and for the 80-column modes (2, 3, and 7) the size of a video page is 4,000 bytes.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
    0    T       40x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    1    T       40x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    2    T       80x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    3    T       80x25     16/8   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    7    T       80x25      b/w   MDA,HGC,EGA,VGA,SVGA        Monochrome
    The remainder of this section will describe the text video modes in more

detail.

Mode 0

    Mode 0 is a 40-column by 25-row color text mode. It is often called a

colorless mode since it was designed to be used with composite or television monitors (as opposed to RGB monitors). When used with these types of monitors, the available 16 "colors" appear as distinct shades of gray. When used with an RGB monitor, mode 0 is identical in all respects to mode 1. The use of composite or television monitors as PC video displays has virtually disappeared today. As a result, mode 0 is used infrequently.

Mode 1

    Mode 1 is a 40-column by 25-row color text mode. It is supported across

all video adapter and color display combinations in the PC and PS/2 families. Characters displayed in mode 1 have an associated display attribute that defines the character's foreground color, its background color, and whether or not it blinks. Sixteen foreground colors and eight background colors are available.

Mode 2

    Mode 2 is an 80-column by 25-row color text mode. Like mode 0, it is

often called a colorless mode since it was designed to be used with composite or television monitors (as opposed to RGB monitors). When used with these types of monitors, the available 16 "colors" appear as distinct shades of gray. When used with an RGB monitor, mode 2 is identical in all respects to mode 3. The use of composite or television monitors as PC video displays has virtually disappeared today. As a result, mode 2 is used infrequently.

Mode 3

    Mode 3 is an 80-column by 25-row color text mode. It is the default video

mode for systems that use any type of color display. This mode is supported across all video adapter and color display combinations in the PC and PS/2 families. Characters displayed in mode 3 have an associated display attribute that defines the character's foreground color, its background color, and �

                                     Chapter 2:  PC and PS/2 Video Modes   33


whether or not it blinks. Sixteen foreground colors and eight background colors are available.

Mode 7

    Mode 7 is the 80-column by 25-row monochrome text mode. It is the default

video mode for systems that use a monochrome display. To use this mode, you must have a Monochrome Display Adapter (MDA), Hercules Graphics Card (HGC), or an Enhanced Graphics Adapter (EGA) connected to a monochrome display. Most VGA and SVGA display adapters also provide an emulation mode that allows you to use mode 7 with analog displays. Characters displayed in mode 7 have an associated display attribute that defines whether the character is invisible, normal, bold, underlined, reversed, blinking, or a combination of these.


Graphics Modes

    There are 13 standard graphics video modes available in the IBM PC and

PS/2 family. Fastgraph provides support for 11 of the 13 modes (modes 8 and 10, specific to the PCjr and Tandy 1000 systems, are not supported). In addition to these 13 modes, Fastgraph supports six SuperVGA graphics modes (modes 24 to 29), four extended VGA modes (modes 20 to 23), and two video modes for the Hercules Graphics Card (modes 11 and 12). The following sections discuss these graphics modes in more detail. The discussions include an overview of video memory organization in each mode, but you don't need a knowledge of this subject to use Fastgraph.


CGA Graphics Modes

    Modes 4, 5, and 6 are designed to be used with the Color Graphics Adapter

(CGA) and for this reason are called the native CGA modes. They were the only graphics modes available with the original IBM PC. Newer graphics adapters (EGA, VGA, MCGA, and SVGA) can emulate the CGA, which means that the CGA graphics modes are available on any PC or PS/2 system equipped with a color display.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
    4    G      320x200      4    CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    5    G      320x200      4    CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA
    6    G      640x200    2/16   CGA,EGA,VGA,MCGA,SVGA    RGB,ECD,VGA,SVGA

Mode 4

    Mode 4 is a CGA graphics mode with a resolution of 320 horizontal pixels

by 200 vertical pixels. Each pixel can assume one of four colors (the available colors are determined by which one of six palettes has been selected), so each pixel requires two bits of video memory. This means each byte of video memory represents four pixels. � 34 Fastgraph User's Guide


Mode 5

    Mode 5 is the colorless analog of mode 4. It was designed to be used with

composite or television monitors (as opposed to RGB monitors). When used with these types of monitors, the four colors appear as distinct shades of gray. When used with an RGB monitor, mode 5 is essentially identical to mode 4. The use of composite or television monitors as PC video displays has virtually disappeared today. As a result, mode 5 is used infrequently.

Mode 6

    Mode 6 is a CGA graphics mode with a resolution of 640 horizontal pixels

by 200 vertical pixels. Each pixel can assume two states -- on or off. The color in which the "on" pixels appear can be selected from a palette of 16 available colors. Each pixel thus requires one bit of video memory, which means each byte of video memory represents eight pixels.


Tandy 1000 and PCjr Graphics Modes

    Modes 8, 9, and 10 are only available on the PCjr and Tandy 1000 series

computers (these systems also support modes 4, 5, and 6). Modes 8 and 10 are not widely used, and for this reason Fastgraph does not support them.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
    8    G      160x200     16       Tandy 1000,PCjr             RGB
    9    G      320x200     16       Tandy 1000,PCjr             RGB
   10    G      640x200      4       Tandy 1000,PCjr             RGB

Mode 9

    Mode 9 is a Tandy 1000 and PCjr graphics mode with a resolution of 320

horizontal pixels by 200 vertical pixels. Each pixel can assume one of 16 colors, so each pixel requires four bits of video memory. This means each byte of video memory represents two pixels. The Tandy 1000 and PCjr use standard random-access memory (RAM) as video memory.


Hercules Graphics Modes

    Modes 11 and 12 are used with the Hercules Graphics Card (HGC) and a

monochrome display. As such, they are not true IBM video modes, but because of the popularity of the HGC, Fastgraph provides support for this adapter.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
   11    G      720x348     b/w            HGC                Monochrome
   12    G      320x200     b/w            HGC                Monochrome      �
                                     Chapter 2:  PC and PS/2 Video Modes   35


Mode 11

    Mode 11 is a true Hercules graphics mode with a resolution of 720

horizontal pixels by 348 vertical pixels. Each pixel can assume two states -- on or off. Each pixel thus requires one bit of video memory, which means each byte of video memory represents eight pixels.

Mode 12

    Mode 12 is a software-simulated Hercules graphics mode with an effective

resolution of 320 horizontal pixels by 200 vertical pixels. Its purpose is to provide a resolution that is available with all other graphics display adapters.

    This mode converts all coordinates from the 320x200 space (called virtual

coordinates) into the 720x348 coordinate system (called physical coordinates). It does this by using two physical pixels for each virtual pixel and scan doubling the odd-numbered virtual rows. Finally, offsets are added to the resulting physical coordinates to center the image area on the display. This creates an image area bounded horizontally by the physical coordinates 40 and 679 and vertically by the physical coordinates 24 and 323.


EGA Graphics Modes

    Modes 13 through 16 were introduced with the Enhanced Graphics Adapter

(EGA) and for this reason are called the native EGA modes. VGA and SVGA adapters also provide support for these modes, but the MCGA does not. The original IBM EGA only contained 64K bytes of video memory, but memory could be added in 64K increments to fully populate the adapter with 256K bytes of video memory. As other manufacturers developed EGA cards, they generally included 256K bytes of video memory as a standard feature.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
   13    G      320x200     16        EGA,VGA,SVGA         RGB,ECD,VGA,SVGA
   14    G      640x200     16        EGA,VGA,SVGA         RGB,ECD,VGA,SVGA
   15    G      640x350     b/w       EGA,VGA,SVGA          Mono,VGA,SVGA
   16    G      640x350    16/64      EGA,VGA,SVGA           ECD,VGA,SVGA

Mode 13

    Mode 13 is an EGA graphics mode with a resolution of 320 horizontal

pixels by 200 vertical pixels. Each pixel can assume one of 16 colors, so each pixel requires four bits of video memory. In this mode, video memory is organized as four bit planes. Each video memory address actually references four bytes, one in each plane. Put another way, each video memory byte references eight pixels, stored one bit per plane.

Mode 14

    Mode 14 is an EGA graphics mode with a resolution of 640 horizontal

pixels by 200 vertical pixels. Each pixel can assume one of 16 colors, so each pixel requires four bits of video memory. In this mode, video memory is organized as four bit planes. Each video memory address actually references � 36 Fastgraph User's Guide


four bytes, one in each plane. Put another way, each video memory byte references eight pixels, stored one bit per plane.

Mode 15

    Mode 15 is an EGA monochrome graphics mode with a resolution of 640

horizontal pixels by 350 vertical pixels. Each pixel can assume one of 4 display attributes, so each pixel requires two bits of video memory. In this mode, video memory is organized as four bit planes, two of which are disabled. Each video memory address actually references two bytes, one in each enabled plane. Put another way, each video memory byte references eight pixels, stored one bit per plane.

Mode 16

    Mode 16 is an EGA graphics mode with a resolution of 640 horizontal

pixels by 350 vertical pixels.1 Each pixel can assume one of 16 colors (the 16 colors can be selected from a palette of 64 colors), so each pixel requires four bits of video memory. In this mode, video memory is organized as four bit planes. Each video memory address actually references four bytes, one in each plane. Put another way, each video memory byte references eight pixels, stored one bit per plane.


VGA and MCGA Graphics Modes

    Modes 17, 18, and 19 were introduced with the MCGA and VGA video

subsystems of the IBM PS/2 computers. Since the introduction of the PS/2, other manufacturers have developed VGA cards that can be used with the PC family. VGA and SVGA adapters support all three of these modes, but the MCGA does not support mode 18. Modes 17 and 18 are called native VGA modes.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
   17    G      640x480   2/256K      VGA,MCGA,SVGA            VGA,SVGA
   18    G      640x480   16/256K       VGA,SVGA               VGA,SVGA
   19    G      320x200  256/256K     VGA,MCGA,SVGA            VGA,SVGA

Mode 17

    Mode 17 is a VGA and MCGA graphics mode with a resolution of 640

horizontal pixels by 480 vertical pixels. Each pixel can assume two states -- on or off. The color in which the "on" and "off" pixels appear can be selected from a palette of 262,144 available colors. Each pixel thus requires one bit of video memory, which means each byte of video memory represents eight pixels. On VGA and SVGA systems, video memory is organized as four bit planes, and mode 17 is implemented by enabling one of these planes.


____________________

  (1) In mode 16, the video page size actually is 640 by 400 pixels, though

the screen resolution is 640 by 350. The final 50 pixel rows (350 to 399) on each video page are not displayed but are available for off-screen storage. �

                                     Chapter 2:  PC and PS/2 Video Modes   37


Mode 18

    Mode 18 is a native VGA graphics mode with a resolution of 640 horizontal

pixels by 480 vertical pixels. Each pixel can assume one of 16 colors (the 16 colors can be selected from a palette of 262,144 colors), so each pixel requires four bits of video memory. In this mode, video memory is organized as four bit planes. Each video memory address actually references four bytes, one in each plane. Put another way, each video memory byte references eight pixels, stored one bit per plane.

Mode 19

    Mode 19 is a VGA and MCGA graphics mode with a resolution of 320

horizontal pixels by 200 vertical pixels. Each pixel can assume one of 256 colors (the 256 colors can be selected from a palette of 262,144 colors), so each pixel requires eight bits of video memory. This means each byte of video memory represents one pixel.


Extended VGA (XVGA) Graphics Modes

    Modes 20 through 23 are the extended VGA or XVGA graphics modes. Although

these video modes are not standard VGA modes, they will work on any register- compatible VGA or SVGA adapter. These video modes are especially popular for game development because they offer video page resizing, whereas the standard 256-color mode does not. Mode 20 is the XVGA version of mode 19, while mode 21 uses scan doubling to achieve a 400-line display. Mode 22 is the so-called "mode X" and is appealing because it has a 1:1 aspect ratio. Mode 23 is identical to mode 22, but it uses scan doubling to achieve a 480-line display.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
   20    G      320x200  256/256K       VGA,SVGA               VGA,SVGA
   21    G      320x400  256/256K       VGA,SVGA               VGA,SVGA
   22    G      320x240  256/256K       VGA,SVGA               VGA,SVGA
   23    G      320x480  256/256K       VGA,SVGA               VGA,SVGA

Mode 20

    Mode 20 is an XVGA graphics mode with a resolution of 320 horizontal

pixels by 200 vertical pixels. Each pixel can assume one of 256 colors (the 256 colors can be selected from a palette of 262,144 colors), so each pixel requires eight bits of video memory. This means each byte of video memory represents one pixel. This mode offers the same resolution and number of colors as mode 19, but its video memory is organized as a series of four bit planes. Every fourth pixel is stored in the same plane (that is, a pixel whose horizontal coordinate is x resides in plane x modulo 4).

Mode 21

    Mode 21 is an XVGA color graphics mode with a resolution of 320

horizontal pixels by 400 vertical pixels. Except for the resolution, its video memory organization is identical to mode 20. � 38 Fastgraph User's Guide


Mode 22

    Mode 22 is an XVGA color graphics mode with a resolution of 320

horizontal pixels by 240 vertical pixels. This is the so-called "mode X" made famous by Michael Abrash in Dr. Dobb's Journal. Except for the resolution, its video memory organization is identical to mode 20.

Mode 23

    Mode 23 is an XVGA color graphics mode with a resolution of 320

horizontal pixels by 480 vertical pixels. Except for the resolution, its video memory organization is identical to mode 20.


SuperVGA (SVGA) Graphics Modes

    Modes 24 through 29 are the SuperVGA or SVGA graphics modes. If you've

done any work with SVGA cards, you probably know that different manufacturers use different numbers to reference the SVGA video modes. For example, the 640x480 256-color graphics mode number is 62 hex on ATI cards, 5D hex on Trident cards, and 2E hex on Tseng Labs cards. Fastgraph's SVGA kernel, described in detail in the next chapter, handles the details of mapping Fastgraph's general SVGA video mode numbers (24 to 29) to the chipset-specific video mode numbers of the supported SVGA cards.

  Mode                    No. of        Supported             Supported
   No. Type   Resolution  Colors        Adapters               Displays
   24    G      640x400  256/256K         SVGA                   SVGA
   25    G      640x480  256/256K         SVGA                   SVGA
   26    G      800x600  256/256K         SVGA                   SVGA
   27    G     1024x768  256/256K         SVGA                   SVGA
   28    G      800x600   16/256K         SVGA                   SVGA
   29    G     1024x768   16/256K         SVGA                   SVGA

Mode 24

    Mode 24 is a SuperVGA graphics mode with a resolution of 640 horizontal

pixels by 400 vertical pixels. Each pixel can assume one of 256 colors (the 256 colors can be selected from a palette of 262,144 colors), so each pixel requires eight bits of video memory. This means each byte of video memory represents one pixel, so at least 256K of video memory is needed for this mode. Note that a fair number of SVGA cards do not support this video mode.

Mode 25

    Mode 25 is a SuperVGA graphics mode with a resolution of 640 horizontal

pixels by 480 vertical pixels. It is probably the most popular SVGA graphics mode. Each pixel can assume one of 256 colors (the 256 colors can be selected from a palette of 262,144 colors), so each pixel requires eight bits of video memory. This means each byte of video memory represents one pixel, so at least 512K of video memory is needed for this mode. �

                                     Chapter 2:  PC and PS/2 Video Modes   39


Mode 26

    Mode 26 is a SuperVGA graphics mode with a resolution of 800 horizontal

pixels by 600 vertical pixels. Each pixel can assume one of 256 colors (the 256 colors can be selected from a palette of 262,144 colors), so each pixel requires eight bits of video memory. This means each byte of video memory represents one pixel, so at least 512K of video memory is needed for this mode.

Mode 27

    Mode 27 is a SuperVGA graphics mode with a resolution of 1024 horizontal

pixels by 768 vertical pixels. Each pixel can assume one of 256 colors (the 256 colors can be selected from a palette of 262,144 colors), so each pixel requires eight bits of video memory. This means each byte of video memory represents one pixel, so at least 768K of video memory is needed for this mode.

Mode 28

    Mode 28 is a SuperVGA graphics mode with a resolution of 800 horizontal

pixels by 600 vertical pixels. Each pixel can assume one of 16 colors (the 16 colors can be selected from a palette of 262,144 colors), so each pixel requires four bits of video memory. In this mode, video memory is organized as four bit planes. Each video memory address actually references four bytes, one in each plane. Put another way, each video memory byte references eight pixels, stored one bit per plane. At least 256K of video memory is needed to use this mode.

Mode 29

    Mode 29 is a SuperVGA graphics mode with a resolution of 1024 horizontal

pixels by 768 vertical pixels. Each pixel can assume one of 16 colors (the 16 colors can be selected from a palette of 262,144 colors), so each pixel requires four bits of video memory. In this mode, video memory is organized as four bit planes. Each video memory address actually references four bytes, one in each plane. Put another way, each video memory byte references eight pixels, stored one bit per plane. At least 512K of video memory is needed to use this mode. � 40 Fastgraph User's Guide




Chapter 3



Initializing the Video Environment � 42 Fastgraph User's Guide


Overview

    Before Fastgraph can perform any text or graphics video operations, you

must select a video mode in which your program will run. An important part of this selection depends on whether your program will run in a text mode, a graphics mode, or both. The first two sections in this chapter discuss the necessary video initialization for standard text and graphics modes, while the last section addresses the additional setup needed for SuperVGA (SVGA) graphics modes.


Establishing a Text Mode

    When you write a program that only uses text modes, you must determine if

the program will run on monochrome systems, color systems, or both. In general, there is no reason to exclude one type of system, because the additional programming required to support both is rather trivial.

    The Fastgraph routine fg_setmode establishes a video mode and initializes

Fastgraph's internal parameters for that mode. This routine has a single integer argument whose value is a video mode number between 0 and 29. Its value can also be -1, which tells Fastgraph to use the current video mode. Specifying an fg_setmode argument of -1 is often useful in programs that only use text video modes.

    When you establish a text video mode, the ROM BIOS text cursor is made

visible, and this is often undesirable. The Fastgraph routine fg_cursor controls the visibility of the text cursor. The fg_cursor routine has a single integer argument that specifies the cursor visibility. If its value is 0, the cursor is made invisible; if its value is 1, the cursor is made visible.

    At this point, an example may help clarify things. We'll start with a

variation of Kernighan and Ritchie's famous "Hello, world" program that shows how to initialize Fastgraph for the 80-column color text mode (mode 3) and turn off the text mode cursor. It uses two Fastgraph routines that we have not yet discussed, fg_setcolor and fg_text. For now, it should suffice to know that fg_setcolor(15) makes subsequent text appear in white, and fg_text displays the characters passed to it.

                                Example 3-1.
                       #include <fastgraf.h>
                       void main(void);
                       void main()
                       {
                          fg_initpm();
                          fg_setmode(3);
                          fg_cursor(0);
                          fg_setcolor(15);
                          fg_text("Hello, world.",13);
                       }                                                      �
                          Chapter 3:  Initializing the Video Environment   43


    If you run example 3-1, notice the text displayed by the program appears

in the upper left corner of the screen. On the line below this, the DOS prompt appears, waiting for your next DOS command. Furthermore, if your system uses the ANSI.SYS driver to set screen attributes (such as with Norton's SA program), you should also notice only the DOS prompt appears in the colors defined by the screen attributes -- the rest of the screen is blank.

    A more graceful return to DOS is needed. In example 3-2, we'll use the

Fastgraph routine fg_reset. This routine erases the screen, and if the ANSI.SYS driver is loaded, fg_reset also restores any previously set screen attributes. We've also included a call to the Fastgraph routine fg_waitkey to wait for a keystroke before exiting. If we didn't do this, we would never see the program's output.

                                Example 3-2.
                       #include <fastgraf.h>
                       void main(void);
                       void main()
                       {
                          fg_initpm();
                          fg_setmode(3);
                          fg_cursor(0);
                          fg_setcolor(15);
                          fg_text("Hello, world.",13);
                          fg_waitkey();
                          fg_reset();
                       }


    Since examples 3-1 and 3-2 specifically use video mode 3, they would not

work on a monochrome system. Ideally, we'd like to use fg_setmode(3) for color systems and fg_setmode(7) for monochrome systems. To do this, we need a way to determine whether the program is being run on a color system or on a monochrome system. The next example illustrates an easy way to do this.

    Example 3-3 uses the Fastgraph routine fg_testmode to determine if the

user's system will support the video mode number specified as its first argument (the second argument is the number of video pages required, which will be 1 for all examples in this section). The fg_testmode routine returns a value of 1 (as its function value) if the requested video mode can be used, and it returns 0 if not. The program first sees if an 80-column color text mode is available (mode 3), and if so, it selects that mode. If the color mode is not available, it checks if the monochrome text mode is available (mode 7), and if so, it chooses the monochrome mode. If neither mode is available, then the program assumes the user's system has a 40-column display, issues a message stating the program requires an 80-column display, and then exits.

                                Example 3-3.
                  #include <fastgraf.h>
                  #include <stdio.h>
                  #include <stdlib.h>                                         �

44 Fastgraph User's Guide


                  void main(void);
                  void main()
                  {
                     int old_mode;
                     fg_initpm();
                     old_mode = fg_getmode();
                     if (fg_testmode(3,1))
                        fg_setmode(3);
                     else if (fg_testmode(7,1))
                        fg_setmode(7);
                     else {
                        printf("This program requires\n");
                        printf("an 80-column display.\n");
                        exit(1);
                        }
                     fg_cursor(0);
                     fg_setcolor(15);
                     fg_text("Hello, world.",13);
                     fg_waitkey();
                     fg_setmode(old_mode);
                     fg_reset();
                  }


    Example 3-3 also illustrates another useful procedure. It is recommended,

especially in graphics modes, to restore the original video mode and screen attributes before a program returns to DOS. We've already seen how the fg_reset routine restores the screen attributes, but how do we restore the original video mode? The Fastgraph routine fg_getmode returns the current video mode as its function value. If we call fg_getmode before calling fg_setmode, we can save the fg_getmode return value and pass it to fg_setmode just before the program exits.

    You also can use another Fastgraph routine, fg_bestmode, to determine if

a video mode with a specific resolution is available on the user's system. The fg_bestmode routine requires three integer arguments: a horizontal resolution, a vertical resolution, and the number of video pages required. As its function value, fg_bestmode returns the video mode number that offers the most capabilities for the resolution and number of pages requested. It returns a value of -1 if no available video mode offers the requested criteria.

    For example, if we require an 80x25 text mode, we can use the function

call fg_bestmode(80,25,1) to pick the "best" video mode available that offers this capability. In text modes, the term best means to give preference to a color text mode over a monochrome text mode. Example 3-4 performs the same function as example 3-3, but it uses fg_bestmode rather than fg_testmode.

                                Example 3-4.
                  #include <fastgraf.h>
                  #include <stdio.h>                                          �
                          Chapter 3:  Initializing the Video Environment   45


                  #include <stdlib.h>
                  void main(void);
                  void main()
                  {
                     int old_mode;
                     int new_mode;
                     fg_initpm();
                     old_mode = fg_getmode();
                     new_mode = fg_bestmode(80,25,1);
                     if (new_mode < 0) {
                        printf("This program requires\n");
                        printf("an 80-column display.\n");
                        exit(1);
                        }
                     fg_setmode(new_mode);
                     fg_cursor(0);
                     fg_setcolor(15);
                     fg_text("Hello, world.",13);
                     fg_waitkey();
                     fg_setmode(old_mode);
                     fg_reset();
                  }


43-line and 50-line Text Modes

    When using an 80-column text mode on a system equipped with an EGA, VGA,

MCGA, or SVGA video display and adapter, you can extend the screen size from 25 lines to 43 or 50 lines. While all systems offer 25-line text modes, EGA systems also offer 43-line modes, MCGA systems also offer 50-line modes, and VGA and SVGA systems offer both 43-line and 50-line modes. The 43-line mode is not available on EGA systems equipped with an RGB display. If you extend the screen size to 43 or 50 lines, the physical character size is reduced proportionally so all lines appear on the screen.

    The fg_setlines routine defines the number of text rows per screen. It

has a single integer argument whose value must be 25, 43, or 50. If you pass any other value to fg_setlines, or pass a value not supported by the host system's video configuration, fg_setlines does nothing. In addition, calling fg_setlines makes the text cursor visible. Another Fastgraph routine, fg_getlines, returns as its function value the number of text rows currently in effect. You also can use fg_getlines in graphics video modes.

    Example 3-5 illustrates the use of the fg_setlines and fg_getlines

routines. The program first establishes the 80-column color text mode (this sets the screen size to its 25-line default) and makes the text cursor invisible. It then displays the words "first line" in the upper left corner of the screen. Next, the program checks if an EGA with enhanced display is available, and if so, changes the screen to 43 lines (video mode 16 is only � 46 Fastgraph User's Guide


available on EGA systems equipped with an enhanced display). Next, the program checks if a VGA, MCGA, or SVGA is available, and if so changes the screen to 50 lines (video mode 17 is only available on these systems). Finally, the program restores the original video mode, restores the number of lines per screen to its original setting, and restores the original screen attributes before exiting.

                                Example 3-5.
                        #include <fastgraf.h>
                        void main(void);
                        void main()
                        {
                           int lines;
                           int old_lines;
                           int old_mode;
                           fg_initpm();
                           old_lines = fg_getlines();
                           old_mode = fg_getmode();
                           fg_setmode(3);
                           fg_cursor(0);
                           fg_setcolor(15);
                           fg_text("first line",10);
                           fg_waitkey();
                           if (fg_testmode(16,0)) {
                              fg_setlines(43);
                              fg_cursor(0);
                              fg_waitkey();
                              }
                           if (fg_testmode(17,0)) {
                              fg_setlines(50);
                              fg_cursor(0);
                              fg_waitkey();
                              }
                           fg_setmode(old_mode);
                           fg_setlines(old_lines);
                           fg_reset();
                        }


Establishing a Graphics Mode

    The steps for establishing a graphics mode are similar to establishing a

text mode. However, there are more restrictions since some systems may not support all the graphics video modes. For example, a program could not run in mode 13 on a CGA system, nor could a program run in mode 9 on anything except a Tandy 1000 or PCjr system. �

                          Chapter 3:  Initializing the Video Environment   47


    For graphics programs, it may suffice to write a program to run in a

specific video mode, but it is often more desirable to write a program that will run in any of several video modes. This is especially true for commercial products, since they should ideally run on as many different video configurations as possible.

    Fastgraph includes a routine named fg_automode that determines the

graphics video mode that offers the most functionality for the user's video hardware configuration. For example, the Tandy 1000 series computers support all three CGA modes (4, 5, and 6) and the 320x200 16-color Tandy 1000 mode (9). Of these modes, mode 9 offers the most features from a graphics standpoint, so fg_automode will return a value of 9 when run on a Tandy 1000 computer. The following table summarizes the video mode numbers returned by fg_automode for given adapter-display combinations. To maintain compatibility with earlier versions of Fastgraph, fg_automode does not consider the extended VGA graphics modes (modes 20 to 23) or SVGA graphics modes (modes 24 to 29) when selecting a video mode.


                                        display
                      adapter   mono   RGB   ECD   VGA
                         MDA       7     0     7     7
                         HGC      11     0     0    11
                         CGA       0     4     0     0
                         EGA      15    13    16     0
                         VGA      17    17    17    18
                        MCGA      17    17    17    19
                       Tandy       7     9     0     0
                        PCjr       7     9     0     0


    Example 3-6 shows how to use fg_automode to determine the "best" graphics

mode for the user's video hardware. In graphics modes, the term best means the highest resolution, followed by the number of available colors. The program displays a message that includes the selected video mode number.

                                Example 3-6.
                   #include <fastgraf.h>
                   #include <stdio.h>
                   void main(void);
                   void main()
                   {
                      int old_mode;
                      int new_mode;
                      char string[4];
                      fg_initpm();
                      old_mode = fg_getmode();
                      new_mode = fg_automode();
                      fg_setmode(new_mode);
                      fg_setcolor(15);
                      fg_text("I'm running in mode ",20);                     �

48 Fastgraph User's Guide


                      sprintf(string,"%d.",new_mode);
                      fg_text(string,3);
                      fg_waitkey();
                      fg_setmode(old_mode);
                      fg_reset();
                   }


    For simple programs such as example 3-6, different screen resolutions may

not be an issue. However, in more complex graphics programs it is often desirable to write a program for a fixed screen resolution. A common practice is to develop graphics programs to run in modes 4 (for CGA), 9 (Tandy 1000 or PCjr), 12 (Hercules), 13 (EGA, VGA, or SVGA), and 19 or 20 (MCGA, VGA, or SVGA). The reason for selecting these five modes is they all use the same 320x200 resolution and will run on any IBM PC or PS/2 with graphics capabilities.

    Example 3-7 performs the same function as example 3-6, but it uses

fg_bestmode instead of fg_automode to restrict the program to 320x200 graphics modes. For this resolution, the fg_bestmode routine will first check the availability of mode 20, followed by modes 19, 13, 9, 4, and 12. If fg_bestmode determines no 320x200 graphics mode is available (indicated by a return value of -1), the program prints an informational message and exits. Otherwise it selects the video mode fg_bestmode proposes and continues.

                                Example 3-7.
    #include <fastgraf.h>
    #include <stdio.h>
    #include <stdlib.h>
    void main(void);
    void main()
    {
       int old_mode;
       int new_mode;
       char string[4];
       fg_initpm();
       old_mode = fg_getmode();
       new_mode = fg_bestmode(320,200,1);
       if (new_mode < 0) {
          printf("This program requires a 320 by 200 graphics mode.\n");
          exit(1);
          }
       fg_setmode(new_mode);
       fg_setcolor(15);
       fg_text("I'm running in mode ",20);
       sprintf(string,"%d.",new_mode);
       fg_text(string,3);
       fg_waitkey();                                                          �
                          Chapter 3:  Initializing the Video Environment   49


       fg_setmode(old_mode);
       fg_reset();
    }


    If a program will run in specific video modes, you may want to consider

using the fg_testmode routine instead of fg_bestmode to check for availability of these video modes. You also may want to use fg_testmode to change the video mode precedence used by fg_bestmode. For example, mode 13 (EGA) is faster than mode 19 (MCGA), so you may want to consider giving EGA precedence over MCGA, especially if your program does not use more than 16 colors.

    Example 3-8 is similar to example 3-7, but it will only run in the

320x200 EGA, MCGA, and CGA graphics modes (video modes 13, 19, and 4, respectively). The program uses fg_testmode to select its video mode. Note the order of calls to fg_testmode gives EGA precedence over MCGA, and MCGA precedence over CGA.

                                Example 3-8.
       #include <fastgraf.h>
       #include <stdio.h>
       #include <stdlib.h>
       void main(void);
       void main()
       {
          int old_mode;
          char string[4];
          fg_initpm();
          old_mode = fg_getmode();
          if (fg_testmode(13,1))
             fg_setmode(13);
          else if (fg_testmode(19,1))
             fg_setmode(19);
          else if (fg_testmode(4,1))
             fg_setmode(4);
          else {
             printf("This program requires an EGA, MCGA, or CGA.\n");
             exit(1);
             }
          fg_setcolor(15);
          fg_text("I'm running in mode ",20);
          sprintf(string,"%d.",getmode());
          fg_text(string,3);
          fg_waitkey();
          fg_setmode(old_mode);
          fg_reset();
       }                                                                      �

50 Fastgraph User's Guide

SuperVGA Graphics Modes

    Unlike previous generations of graphics cards, there was no video

standard in place when different companies began developing SVGA cards. As a result, they implemented enhanced SVGA features according to their own specifications based upon different video controller chips. Each such implementation is called a chipset. While each chipset generally offers the same video memory organization and common screen resolutions, the SVGA- specific features such as mode initialization, bank switching, and setting the display start address differ radically between chipsets. In other words, code written for one specific SVGA chipset will not run on another chipset, even at the same resolution. This is why many software vendors provide different SVGA drivers for their products.

    Fastgraph's integrated SVGA kernel makes these obscure differences

between SVGA chipsets transparent, without the need for external drivers. This means, for instance, if you write an application for the 1024 by 768 256-color SVGA graphics mode, it will run without changes on any supported SVGA chipset which offers that resolution. The SVGA kernel supports the chipsets listed in the table below. A "Y" entry means the chipset supports the video mode, and an "N" means it doesn't. The last two rows of the table show the minimum amount of video memory required to support each mode and Fastgraph's corresponding video mode numbers.

                           -------- 256 colors --------   -- 16 colors --

SVGA chipset 640x400 640x480 800x6001024x768 800x6001024x768 Ahead "A" type Y Y Y N Y Y Ahead "B" type Y Y Y Y Y Y ARK Logic 1000/2000 series Y Y Y Y Y Y ATI 18800 Y Y Y N Y N ATI 18800-1 Y Y Y N Y Y ATI 28800/mach32/mach64 Y Y Y Y Y Y Avance Logic 2000 series Y Y Y Y Y Y Chips & Technologies 82c451 Y N N N Y N Chips & Technologies 82c452 Y Y N N Y Y Chips & Technologies 82c453 Y Y Y Y Y Y Chips & Tech 64xxx/655xx Y Y Y Y Y Y Cirrus Logic 5400/6200/7540 N Y Y Y Y Y Cirrus Logic 6400 series Y Y Y Y Y Y Genoa 6000 series Y Y Y N Y Y Matrox MGA-2064W (Millennium) Y Y Y Y Y N NCR 77C22/77C32 Y Y Y Y Y Y Oak OTI-067 N Y Y N Y Y Oak OTI-077 N Y Y Y Y Y Oak OTI-087 Y Y Y N Y Y Paradise PVGA1a Y Y N N Y N Paradise WD90C00/10/24 Y Y N N Y Y Paradise WD90C11/30/31/33 Y Y Y Y Y Y Realtek 3100 series Y Y Y Y Y Y S3 N Y Y Y Y Y SiS Y Y Y Y Y Y Trident 8800 Y Y Y N Y Y Trident 8900/9000 Y Y Y Y Y Y Tseng ET3000 N Y Y N Y Y Tseng ET4000 Y Y Y Y Y Y Video7 Y Y Y Y Y Y minimum video RAM needed 256K 512K 512K 1MB 256K 512K Fastgraph mode number 24 25 26 27 28 29 �

                          Chapter 3:  Initializing the Video Environment   51



The SVGA kernel maps Fastgraph's video mode numbers (24 to 29) to the chipset- specific mode numbers. For example, the 640x480 256-color SVGA mode is 62 hex on an ATI card, 5D hex on a Trident card, and 2E hex on a Tseng card, but it's always mode 25 from Fastgraph's perspective. As we constantly add support for new SVGA chipsets, please refer to Fastgraph's READ.ME file for the current chipset list. The READ.ME file also lists known problems and limitations with the various chipsets.

    The Video Electronics Standards Association (VESA) has assumed the

complex task of improving software compatibility of SVGA cards from different companies. Most SVGA cards sold today include VESA compatibility, either directly in ROM or through loadable software drivers supplied with the card. Besides supporting specific chipsets, Fastgraph's SVGA kernel supports any SVGA card with VESA compatibility. Note that VESA is not a chipset, but a BIOS-level interface between an application (the SVGA kernel in this case) and chipset-specific functions. While the current VESA standard covers all six SVGA graphics modes that Fastgraph supports, these modes are only available if the underlying chipset also supports them.

    When using VESA compatibility, the VESA BIOS handles all chipset-specific

functions such as bank switching. The overhead imposed by the BIOS usually makes the VESA modes slower than using chipset-specific functions directly. For this reason, you can specify if you want to give precedence to the chipset-specific code or to the VESA BIOS. Chipset-specific precedence means the SVGA kernel will only use the VESA BIOS if no supported SVGA chipset is found. Conversely, VESA precedence means the kernel will only use the chipset- specific functions if no VESA BIOS is found.

    Before you use any SVGA graphics mode, you must use the fg_svgainit

routine to initialize the SVGA kernel (fg_svgainit must be called before fg_setmode, fg_bestmode, or fg_testmode). There are three ways to initialize the SVGA kernel with fg_svgainit:

    * autodetect the SVGA chipset, precedence to chipset-specific code
    * autodetect the SVGA chipset, precedence to the VESA BIOS
    * use a designated SVGA chipset

The fg_svgainit routine's argument is an integer value between 0 and 34 that specifies which initialization method to use. Passing 0 to fg_svgainit uses the first method, in which the SVGA kernel searches for all supported chipsets before checking if a VESA BIOS is present. This means the SVGA kernel will only use VESA functions if fg_svgainit doesn't find one of the supported chipsets. Passing 1 to fg_svgainit also performs a chipset autodetect, but in this case the SVGA kernel first searches for a VESA BIOS, then through the list of supported chipsets. This means chipset-specific code will be used only when no VESA BIOS is found. You can also initialize the SVGA kernel for a specific chipset by passing a value between 2 and 34 to fg_svgainit. The following table summarizes the fg_svgainit initialization codes.

       code   chipset
         0    autodetect (with chipset-specific precedence)
         1    autodetect (with VESA precedence)
         2    Ahead "A" type                                                  �
         3    Ahead "B" type

52 Fastgraph User's Guide

         4    ATI 18800
         5    ATI 18800-1
         6    ATI 28800/38800
         7    Chips & Technologies 82c451/455/456/457
         8    Chips & Technologies 82c452
         9    Chips & Technologies 82c450/453
        10    Genoa 6000 series
        11    Oak OTI-067
        12    Paradise PVGA1a
        13    Paradise WD90C00/WD90C10/WD90C24
        14    Paradise WD90C11/WD90C30/WD90C31/WD90C33
        15    Trident 8800
        16    Trident 8900/9000
        17    Tseng ET3000
        18    Tseng ET4000
        19    Video7
        20    Cirrus Logic 5400/6200/7540 series
        21    S3
        22    NCR 77C22/77C32
        23    Oak OTI-077
        24    Oak OTI-087
        25    Oak OTI-087 (Diamond Viper BIOS)
        26    Cirrus Logic 6400 series
        27    Avance Logic 2000 series
        28    ARK Logic 1000/2000
        29    ATI 68800 (mach32)
        30    ATI 88800 (mach64)
        31    Chips & Technologies 64000/65500 series
        32    Realtek 3100 series
        33    Matrox MGA-2064W (Millennium)
        34    SiS
    For autodetect requests, fg_svgainit returns a value between 1 and 32

corresponding to the SVGA chipset found. If the return value is 1, it means a VESA BIOS will be used. A value between 2 and 32 means a specific SVGA chipset (as listed in the preceding table) will be used. If no VESA BIOS or supported SVGA chipset is found, fg_svgainit returns zero. In this case, Fastgraph's SVGA graphics modes are not available.

    When you request initialization for a specific chipset, fg_svgainit

always returns the value passed to it. It does not check if that chipset is actually present, so this feature should be used judiciously.

    Example 3-9 is a simple program that checks if an SVGA card is present,

and if so, displays the name of the SVGA chipset. It also displays how much video memory is present on the SVGA card and the version number of Fastgraph's SVGA kernel.

                                Example 3-9.
           #include <fastgraf.h>
           #include <stdio.h>
           void main(void);
           char *description[] = {
              "cannot be determined",
              "VESA",
              "Ahead A",
              "Ahead B",
              "ATI 18800",                                                    �
              "ATI 18800-1",
                          Chapter 3:  Initializing the Video Environment   53
              "ATI 28800/38800",
              "Chips & Technologies 82c451/455/456/457",
              "Chips & Technologies 82c452",
              "Chips & Technologies 82c450/453",
              "Genoa 6000 series",
              "Oak OTI-067",
              "Paradise PVGA1a",
              "Paradise WD90C00/WD90C10",
              "Paradise WD90C11/WD90C30/WD90C31/WD90C33",
              "Trident 8800",
              "Trident 8900/9000",
              "Tseng ET3000",
              "Tseng ET4000",
              "Video7",
              "Cirrus Logic 5400/6200/7540 series",
              "S3",
              "NCR 77C22/77C32",
              "Oak OTI-077",
              "Oak OTI-087",
              "Oak OTI-087 (Diamond Viper BIOS)",
              "Cirrus Logic 6400 series",
              "Avance Logic 2000 series",
              "ARK Logic 1000/2000",
              "ATI 68800 (mach32)",
              "ATI 88800 (mach64)",
              "Chips & Technologies 64000/65500 series",
              "Realtek 3100 series",
              "Matrox MGA-2064W (Millennium)",
              "SiS"
           };
           void main()
           {
              int id, major, minor;
              fg_initpm();
              id = fg_svgainit(0);
              printf("SVGA chipset:  %s\n",description[id]);
              printf("video memory:  %d kilobytes\n",fg_memory());
              fg_svgaver(&major,&minor);
              printf("SVGA version:  %d.%2.2d\n",major,minor);
           }

This example uses fg_svgainit to detect the user's SVGA chipset automatically. It initializes the SVGA kernel so chipset-specific code is given precedence over VESA (passing 1 instead of 0 to fg_svgainit would give VESA precedence). Note that the program does not establish an SVGA graphics mode -- it just uses the fg_svgainit return value to identify which chipset is present.

    Example 3-9 also includes two other Fastgraph routines relevant to the

SVGA kernel. The fg_memory function returns the amount of video memory (in kilobytes) resident on the user's video card. For example, the fg_memory return value is 1,024 for a 1MB SVGA card. Another routine, fg_svgaver, returns the major and minor numbers for the SVGA kernel, similar to the fg_version routine mentioned in Chapter 1. Note that the SVGA kernel version number is not the same as the Fastgraph version number.

    Another useful function is fg_svgastat, which returns information about

the current state of Fastgraph's SVGA kernel. The function returns a bit mask in which bit 0 will be set if the SVGA kernel has been successfully initialized, and bit 1 will be set if the kernel is using the VESA BIOS. Other � 54 Fastgraph User's Guide


fg_svgastat bits provide information about the availability of extended video pages and whether or not the active chipset supports separate read and write banks. We'll discuss these features in later chapters.

    Our next example, 3-10, is an SVGA version of example 3-8. This program

initializes the SVGA kernel so that VESA will have precedence over chipset- specific code. It then calls fg_testmode to find a supported 256-color SVGA graphics mode, first trying mode 27 (1024 by 768), then mode 26 (800x600), and finally mode 25 (640x480). Checking the modes in this sequence insures the program will use the highest resolution available, given the user's SVGA chipset (not all chipsets support all resolutions) and the amount of video memory present (mode 27 requires 1MB video RAM; modes 26 and 25 need 512K).

    If all three fg_testmode calls fail in example 3-10, the program displays

an appropriate message and exits. This would happen if the program were run on a non-SVGA system, run on an unsupported SVGA chipset without VESA compatibility, or if the SVGA card does not have at least 512K video memory (modes 25, 26, and 27 all require at least 512K). In the first two cases, the fg_svgainit function wouldn't have initialized the SVGA kernel, so fg_testmode would fail when checking the availability of any SVGA graphics mode. That's why it's not necessary to check the fg_svgainit return value in this case.

                                Example 3-10.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             void main()
             {
                int old_mode;
                char string[4];
                fg_initpm();
                old_mode = fg_getmode();
                fg_svgainit(1);
                if (fg_testmode(27,1))
                   fg_setmode(27);
                else if (fg_testmode(26,1))
                   fg_setmode(26);
                else if (fg_testmode(25,1))
                   fg_setmode(25);
                else {
                   printf("This program requires an SVGA ");
                   printf("with at least 512K video memory.\n");
                   exit(1);
                   }
                fg_setcolor(15);
                fg_text("I'm running in mode ",20);
                sprintf(string,"%d.",fg_getmode());
                fg_text(string,3);
                fg_waitkey();                                                 �
                          Chapter 3:  Initializing the Video Environment   55


                fg_setmode(old_mode);
                fg_reset();
             }


    While the VESA specification defines a common programming interface for

chipset-specific SVGA functions, we must remember that VESA is just that -- a specification. Some manufacturers provide VESA drivers or BIOS implementations that realize the full VESA specification with only slight performance degradations. Others aren't as good, having problems with anything beyond the rudimentary functions of mode initialization and bank switching, not to mention performance issues.

    Other problems can occur with the few SVGA cards that do not completely

follow the chipset manufacturer's predefined video mode numbers and register definitions. While the SVGA kernel allows for these problems when known, it's just not possible to support every problematic SVGA card. To complicate matters, some of these troublesome video cards only exhibit problems in certain revisions, meaning two apparently identical cards will behave differently. Fortunately, such problematic cards are by far the exception.

    If you're developing an SVGA product for general distribution, we

recommend using Fastgraph's chipset-specific code by default, but also providing a way to override the chipset-specific code and use VESA support. Most often this is done by recognizing a command line switch or using an application-specific configuration file. Some programmers even take this one step farther by including a way to avoid the SVGA autodetection procedure and initialize Fastgraph's SVGA kernel for a specific chipset. This might be important if your product will run on laptop systems, which sometimes have SVGA video subsystems that don't respond to autodetection requests as reliably as their desktop counterparts.

    Another important point to consider when writing SVGA applications is the

compatibility between the video card and monitor. Virtually all SVGA monitors made today have no problems supporting the bandwidth required by any of Fastgraph's SVGA graphics modes. However, some monitors (most notably older multisync monitors) cannot support the higher resolution modes such as 800x600 and 1024 by 768. The SVGA kernel checks if the SVGA card supports the requested resolution, but it does not check if the card/monitor combination does.


Summary of Video Initialization Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_AUTOMODE determines the graphics video mode that offers the most

features for the user's display and adapter configuration. The value it returns helps determine a suitable value to pass to the fg_setmode routine.

    FG_BESTMODE is similar to fg_automode, but it excludes video modes that

do not offer the specified resolution and video page requirements. � 56 Fastgraph User's Guide


    FG_CURSOR makes the text mode cursor visible or invisible. This routine

has no effect when used in a graphics mode.

    FG_GETLINES returns the number of text rows per screen for the current

video mode.

    FG_GETMODE returns the current video mode. It is typically one of the

first Fastgraph routines called in a program. The value returned by fg_getmode can be used to restore the original video mode when a program transfers control back to DOS.

    FG_MEMORY returns the amount of video memory present (in kilobytes) on

the user's SVGA card. This routine is meaningful only after successfully initializing the SVGA kernel with fg_svgainit.

    FG_RESET is generally the last Fastgraph routine called in a program. It

only functions in text video modes. When the ANSI.SYS driver is not loaded, fg_reset merely erases the screen. When ANSI.SYS is loaded, fg_reset also restores any previously set screen attributes.

    FG_SETLINES extends an 80-column text mode to 25, 43, or 50 lines per

screen. This routine is only meaningful when running in 80-column text modes on EGA, VGA, or MCGA systems (in other cases it does nothing).

    FG_SETMODE establishes a video mode and initializes Fastgraph's internal

parameters for that video mode. It must be called before any Fastgraph routine that performs video output. A program can call fg_setmode as many times as needed to switch between different video modes.

    FG_SVGAINIT initializes Fastgraph's SVGA kernel and performs chipset-

specific SVGA initialization. This routine must be called before establishing an SVGA graphics mode with fg_setmode.

    FG_SVGASTAT returns information about the current state of Fastgraph's

SVGA kernel.

    FG_SVGAVER returns the SVGA kernel's major and minor version numbers.
    FG_TESTMODE determines whether or not a specified video mode (with a

given number of video pages) is available on the user's system.




Chapter 4



Coordinate Systems � 58 Fastgraph User's Guide


Overview

    Fastgraph uses three coordinate systems to perform text and graphics

output -- character space, screen space, and world space. Character space is used in text modes and optionally for displaying character strings in graphics modes. Screen space is the basic coordinate system for graphics video modes and uses the screen's physical device coordinates. Viewports are an extension of screen space that let you assign an alternate integer-based coordinate system to rectangular subsets of the screen. Finally, world space is a user- definable coordinate system for graphics modes that uses floating point values. The world space coordinate system is not available in Fastgraph/Light.


Character Space

    The coordinate system used for displaying characters is called character

space. Fastgraph uses character space for displaying characters in both text and graphics video modes (you can also use screen space to display characters in graphics modes). Character space can be thought of as a grid of rows and columns, with each cell in the grid holding one character. Each cell is identified by its unique (row,column) integer coordinates. The rows and columns are numbered starting at zero; the origin is always the upper left corner of the screen. For example, in the 80-column by 25-row text modes (2, 3, and 7), the default (row,column) coordinates of the screen corners are shown in the following diagram.


                           (0,0)           (0,79)


                           (24,0)         (24,79)


The number of rows and columns depends on the video mode, as shown in the following table. For graphics modes, the table also includes the width and height in pixels of a character cell.

                          Mode   No. of No. of Char. Char.
                         Number  Columns Rows  WidthHeight
                            0      40     25
                            1      40     25
                            2      80     25
                            3      80     25
                            4      40     25     8     8
                            5      40     25     8     8
                            6      80     25     8     8
                            7      80     25
                            9      40     25     8     8
                           11      80     25     9    14
                           12      40     25     8     8
                           13      40     25     8     8
                           14      80     25     8     8
                           15      80     25     8    14                      �
                                          Chapter 4:  Coordinate Systems   59


                           16      80     25     8    14
                           17      80     30     8    16
                           18      80     30     8    16
                           19      40     25     8     8
                           20      40     25     8     8
                           21      40     50     8     8
                           22      40     30     8     8
                           23      40     60     8     8
                           24      80     25     8    16
                           25      80     30     8    16
                           26      100    37     8    16
                           27      128    48     8    16
                           28      100    37     8    16
                           29      128    48     8    16
    Fastgraph includes two routines, fg_getmaxx and fg_getmaxy, that

respectively return the maximum column and row numbers in text modes. Example 4-1 demonstrates these two routines in a text mode. The program uses fg_getmaxx and fg_getmaxy to obtain the maximum column and row numbers in mode 3. It then displays these values (79 and 24).

                                Example 4-1.
                    #include <fastgraf.h>
                    #include <stdio.h>
                    void main(void);
                    void main()
                    {
                       int max_col;
                       int max_row;
                       int mode;
                       fg_initpm();
                       mode = fg_getmode();
                       fg_setmode(3);
                       max_col = fg_getmaxx();
                       max_row = fg_getmaxy();
                       fg_setmode(mode);
                       fg_reset();
                       printf("Last col = %d\n",max_col);
                       printf("Last row = %d\n",max_row);
                    }


Screen Space

    Screen space is one of two available coordinate systems in graphics

modes. It uses the physical device coordinates. Screen space can be thought of as a grid of rows and columns, with each unit in the grid holding one pixel. Each pixel is identified by its unique (x,y) integer coordinates. The pixel rows and columns are numbered starting at zero; the origin is always the upper � 60 Fastgraph User's Guide


left corner of the screen. For example, in the 320x200 graphics modes, the (x,y) coordinates of the screen corners are shown in the following diagram.


                           (0,0)          (319,0)


                           (0,199)      (319,199)


    The Fastgraph routines fg_getmaxx and fg_getmaxy return the maximum x and

y screen coordinates when used in graphics modes, as shown in example 4-2. The program uses fg_getmaxx and fg_getmaxy to obtain the maximum x and y coordinates in the standard VGA/MCGA 256-color graphics mode (mode 19). It then displays these values (319 and 199).

                                Example 4-2.
                      #include <fastgraf.h>
                      #include <stdio.h>
                      void main(void);
                      void main()
                      {
                         int maxx;
                         int maxy;
                         int mode;
                         fg_initpm();
                         mode = fg_getmode();
                         fg_setmode(19);
                         maxx = fg_getmaxx();
                         maxy = fg_getmaxy();
                         fg_setmode(mode);
                         fg_reset();
                         printf("(%d,%d)\n",maxx,maxy);
                      }


Viewports

    Viewports provide an alternate integer-based coordinate system for

referencing pixels. Fastgraph includes routines to create a viewport, return the viewport limits, and convert viewport coordinates to their screen space values.

    A viewport definition consists of its extremes in "viewport space" and

the corresponding limits in screen space. The fg_setview routine defines a viewport. Its first four parameters represent the minimum x, maximum x, minimum y, and maximum y viewport coordinates, and its last four parameters represent the corresponding screen space pixel values defining the viewport's physical size and location. For example, the call �

                                          Chapter 4:  Coordinate Systems   61


                   fg_setview(100,739,100,499,0,159,0,99);

would create a 640x400 viewport in the upper left corner of a 320x200 screen. The viewport's coordinates would range from 100 to 739 horizontally and 100 to 499 vertically. In other words, the viewport coordinate (100,100) would map to the screen space pixel (0,0). The following diagram illustrates this viewport. The viewport space coordinates appear in boldface, while the other values are the equivalent screen space coordinates.

                 (100,100)  (739,100)
                 (0,0)        (159,0)               (319,0)


                 (0,99)      (159,99)
                 (100,499)  (739,499)


                 (0,199)                          (319,199)


Fastgraph's fg_getview routine returns the current viewport limits and corresponding screen space limits, as defined in the most recent call to fg_setview.

    Once you've defined a viewport, the fg_xview and fg_yview functions

translate viewport coordinates to their screen space equivalents. The translated values can then be passed to any Fastgraph routine that expects screen space coordinates. For example, Fastgraph's fg_rect routine draws a filled rectangle in screen space. If you wanted to fill the viewport defined above with color 10 pixels, you could do this as follows:

      fg_setcolor(10);
      fg_rect(fg_xview(100),fg_xview(739),fg_yview(100),fg_yview(499));
    Example 4-3 demonstrates a simple use of viewports in the standard

320x200 VGA/MCGA 256-color graphics mode. After filling the screen with white (color 15) pixels, it sets up a viewport in the upper left quadrant of the screen and uses fg_rect to fill it with light blue (color 9) pixels. It then defines three new viewports in the other screen quadrants, similarly filling the upper right quadrant with light green (color 10) pixels, the lower left quadrant with light cyan (color 11) pixels, and finally the lower right quadrant with light red (color 12) pixels. Note how the same viewport coordinates are used to fill the viewport in each case; only the viewport position changes.

                                Example 4-3.
      #include <fastgraf.h>
      void main(void);
      void main()
      {
         int mode;                                                            �

62 Fastgraph User's Guide


         fg_initpm();
         mode = fg_getmode();
         fg_setmode(19);
         fg_setcolor(15);
         fg_rect(0,319,0,199);
         fg_waitkey();
         fg_setview(0,639,0,399,0,159,0,99);
         fg_setcolor(9);
         fg_rect(fg_xview(0),fg_xview(639),fg_yview(0),fg_yview(399));
         fg_waitkey();
         fg_setview(0,639,0,399,160,319,0,99);
         fg_setcolor(10);
         fg_rect(fg_xview(0),fg_xview(639),fg_yview(0),fg_yview(399));
         fg_waitkey();
         fg_setview(0,639,0,399,0,159,100,199);
         fg_setcolor(11);
         fg_rect(fg_xview(0),fg_xview(639),fg_yview(0),fg_yview(399));
         fg_waitkey();
         fg_setview(0,639,0,399,160,319,100,199);
         fg_setcolor(12);
         fg_rect(fg_xview(0),fg_xview(639),fg_yview(0),fg_yview(399));
         fg_waitkey();
         fg_setmode(mode);
         fg_reset();
      }


    To make a viewport a "true" viewport, it is often desirable to establish

clipping limits at the viewport's extremes. This way, Fastgraph's functions that support clipping will only draw within the viewport itself. The following call to fg_setclip will establish the desired clipping limits:

    fg_setclip(fg_xview(100),fg_xview(739),fg_yview(100),fg_yview(499));

The fg_setclip routine will be described in more detail in Chapter 6.


World Space

    World space is the other available coordinate system in graphics modes.

It utilizes user-defined floating point coordinates. Fastgraph translates world space coordinates into physical device coordinates (screen space), and because of this it is somewhat slower than using screen space. World space can be thought of as a standard cartesian plane extending from the lower left corner of the screen. The world space vertical orientation is thus inverted relative to screen space and viewports.

    Any program that uses world space coordinates must first initialize

Fastgraph's internal world space parameters. The Fastgraph routine fg_initw is �

                                          Chapter 4:  Coordinate Systems   63


provided for this purpose. The fg_initw routine has no arguments and must be called before any other routine that uses world space coordinates.

    The next step in using world space is to use the Fastgraph routine

fg_setworld to define the world space coordinates of the screen edges. The fg_setworld routine has four floating-point arguments -- the minimum x coordinate (left edge), the maximum x coordinate (right edge), the minimum y coordinate (bottom edge), and the maximum y coordinate (top edge). For example, if you define the world space coordinates with the statement

                      fg_setworld(-10.0,10.0,0.0,2.5);

the (x,y) coordinates of the screen corners would be defined as shown in the following diagram.


                           (-10.0,2.5) (10.0,2.5)


                           (-10.0,0.0) (10.0,0.0)


Fastgraph includes a routine fg_getworld that returns the world space extremes as defined in the most recent call to fg_setworld.

    Example 4-4 uses fg_setworld and fg_getworld to illustrate an interesting

application of world space. This program calls another routine named redraw (not shown) that erases the screen and draws a certain image using world space coordinates. The program draws the image, waits for a keystroke, reduces the world space by a factor of two in each direction, and then draws the image again. This produces a zoom effect in which the image appears twice as large as it was originally.

                                Example 4-4.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             void redraw(void);
             void main()
             {
                int new_mode, old_mode;
                double xmin, xmax, ymin, ymax;
                fg_initpm();
                old_mode = fg_getmode();
                new_mode = fg_automode();
                if (new_mode == 0) {
                   printf("This program requires graphics.\n");
                   exit(1);
                   }                                                          �

64 Fastgraph User's Guide


                fg_setmode(new_mode);
                fg_initw();
                fg_setworld(0.0,40.0,0.0,30.0);
                redraw();
                fg_waitkey();
                fg_getworld(&xmin,&xmax,&ymin,&ymax);
                fg_setworld(0.0,xmax*0.5,0.0,ymax*0.5);
                redraw();
                fg_waitkey();
                fg_setmode(old_mode);
                fg_reset();
             }


Conversion Routines

    Sometimes it's necessary to convert coordinates between character space,

screen space, and world space. Fastgraph includes eight conversion routines, four for x coordinates and four for y coordinates, to perform such conversions. These routines return the translated coordinate as their function value.

    The fg_xalpha and fg_yalpha routines convert screen space coordinates to

character space. The fg_xalpha routine converts a screen space x coordinate to the character space column that contains the coordinate. Similarly, the fg_yalpha routine converts a screen space y coordinate to the character space row that contains the coordinate.

    The fg_xconvert and fg_yconvert routines convert character space

coordinates to screen space. The fg_xconvert routine converts a character space column to the screen space coordinate of its leftmost pixel. Similarly, the fg_yconvert routine converts a character space row to the screen space coordinate of its top (lowest-numbered) pixel.

    The fg_xscreen and fg_yscreen routines convert world space coordinates to

screen space. The fg_xscreen routine translates x coordinates, while the fg_yscreen routine translates y coordinates. Conversely, the fg_xworld and fg_yworld routines convert screen space coordinates to world space. The fg_xworld routine translates x coordinates, while the fg_yworld routine translates y coordinates.


Summary of Coordinate Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_GETMAXX returns the maximum x coordinate in screen space when used in

a graphics mode. It returns the maximum column number in character space when used in a text mode. �

                                          Chapter 4:  Coordinate Systems   65


    FG_GETMAXY returns the maximum y coordinate in screen space when used in

a graphics mode. It returns the maximum row number in character space when used in a text mode.

    FG_GETVIEW returns the current viewport limits and their screen space

equivalents, as defined in the most recent call to fg_setview.

    FG_GETWORLD returns the current world space limits, as defined in the

most recent call to fg_setworld.

    FG_INITW initializes Fastgraph's internal parameters for world space.

This routine must be called once, before any other routine that uses world coordinates.

    FG_SETVIEW defines a viewport with the specified extremes at the

specified screen space position.

    FG_SETWORLD defines the world space coordinates that correspond to the

physical edges of the screen.

    FG_XALPHA and FG_YALPHA convert screen space coordinates to character

space.

    FG_XCONVERT and FG_YCONVERT convert character space coordinates to screen

space.

    FG_XSCREEN and FG_YSCREEN convert world space coordinates to screen

space.

    FG_XVIEW and FG_YVIEW convert viewport coordinates to screen space.
    FG_XWORLD and FG_YWORLD convert screen space coordinates to world space.  �

66 Fastgraph User's Guide




Chapter 5



The Use of Color � 68 Fastgraph User's Guide


Overview

    The use of color is an important part of any text or graphics

application. This chapter explains color as it applies to text and graphics modes. It also describes palettes and video DAC registers for the graphics video modes that offer this functionality. Finally, an explanation of Fastgraph's virtual colors is provided.


Text Modes

    The term color is not really correct in text modes because each character

cell has an associated attribute that controls the character's appearance in that cell. The meaning of the attribute differs for color and monochrome text modes.


Color Text Modes

    In color text modes (modes 0, 1, 2, and 3), the attribute determines a

character's foreground color (the color of the character itself), its background color (the color of that part of the character cell not covered by the character), and whether or not it blinks. Sixteen foreground colors (numbered 0 to 15) are available, but only eight background colors (numbered 0 to 7) are available. The colors assigned to these values are listed in the following table.

                     number     color    number     color
                        0       black       8     dark gray
                        1       blue        9    light blue
                        2       green      10    light green
                        3       cyan       11    light cyan
                        4        red       12     light red
                        5      magenta     13   light magenta
                        6       brown      14      yellow
                        7       gray       15       white

At first it may seem the numbers have been arbitrarily assigned to the colors. Upon further inspection, however, it becomes apparent this is not the case. Each color number is a four bit quantity of the form IRGB, with I representing the intensity, R the red component, G the green component, and B the blue component. If the corresponding bit is 1, it means the intensity or color component is set. For example, normal red would be represented by the IRGB bit pattern 0100, which is 4 decimal, the color number for red.

    The fg_setattr routine defines the current text attribute. Once

fg_setattr is called, Fastgraph displays all subsequent text using that attribute. The first argument of fg_setattr defines the foreground color, which must be an integer between 0 and 15. Its second argument defines the background color, which must be between 0 and 7. Its third argument determines if the foreground color blinks (1 means it blinks, 0 means it does not). For example, the statement

                             fg_setattr(14,1,0);                              �
                                            Chapter 5:  The Use of Color   69


specifies subsequent text will be displayed with a yellow foreground (14) on a blue background (1) and will not blink (0).

    Another Fastgraph routine, fg_setcolor, also can define text attributes.

The fg_setcolor routine packs the three values passed to fg_setattr into a single argument, as shown here:

                           bits         attribute
                            0-3     foreground color
                            4-6     background color
                             7          blinking

For example, calling fg_setcolor with an argument of 30 (1E hex) is equivalent to calling fg_setattr with arguments of 14, 1, and 0.

    The Fastgraph routine fg_getcolor returns the current text attribute, as

defined in the most recent call to fg_setattr or fg_setcolor. The fg_getcolor routine has no arguments and returns the attribute as its function value. The returned value is encoded using the same scheme for passing a text attribute to fg_setcolor.


Monochrome Text Mode

    In the monochrome text mode (mode 7), colors are obviously not available.

The attribute instead determines whether a character is invisible, normal, bold, reversed, or certain combinations of these. The following table shows the values assigned to the available display characteristics.

                   foreground     background   characteristic
                        0              0          invisible
                        0              7          reversed
                        1              0         underlined
                        7              0           normal
                        9              0       underlined bold
                       15              0            bold

Additionally, you can turn blinking on or off for each of these combinations. Any combination of foreground and background values not listed in the above table produces a normal display characteristic.

    As in the color modes, the Fastgraph routines fg_setattr and fg_setcolor

define the current text attribute. For example, the statement

                             fg_setattr(0,7,1);

specifies subsequent text will be displayed in reverse video (0,7) and will blink (1). The same attribute could be defined by calling fg_setcolor with an argument of 240 (F0 hex). The fg_getcolor routine is also available and works as it does in the color text modes. � 70 Fastgraph User's Guide


Graphics Modes

    In graphics modes, each pixel has an associated color value that

determines the color in which the pixel is displayed. The number of available colors depends on the video mode and can be obtained through the fg_colors function. Some graphics modes also have palette registers or video DAC registers to provide additional color capabilities, such as choosing a set of colors from a larger palette of colors. The example programs presented in this section show the use of color in specific graphics video modes.

    The following subsections will discuss the use of color in each graphics

video mode. In these discussions, there will be several references to a group of colors called the standard color set. This is a set of 16 colors common to many of the graphics video modes (and to the color text modes). The colors in the standard color set are listed in the following table.

                     number     color    number     color
                        0       black       8     dark gray
                        1       blue        9    light blue
                        2       green      10    light green
                        3       cyan       11    light cyan
                        4        red       12     light red
                        5      magenta     13   light magenta
                        6       brown      14      yellow
                        7       gray       15       white
    At this point we must understand the difference between the terms color

number and color value. Color number refers to the number that defines a color in the standard color set (for example, green is color number 2). Color value refers to the actual value of a pixel in video memory, which ultimately determines the color in which that pixel is displayed. The color value is sometimes just called the color.

    In each graphics mode, video memory is cleared when the fg_setmode

routine is called. This means all pixels are initially set to color value 0, which by default is black. For this reason, color value 0 is often called the background color in graphics video modes.

    Fastgraph's fg_setcolor routine defines the color in which subsequent

graphics operations are performed. This color is called the current color. Depending on the video mode, the current color can reference a color value (in CGA and Hercules graphics modes), a palette register (in Tandy, EGA, and VGA graphics modes), or a video DAC register (in 256-color modes). The fg_setcolor routine takes a single integer argument that specifies the color. When fg_setmode is called, it sets the current color to 0. The Fastgraph routine fg_getcolor returns the current color, as defined in the most recent call to fg_setcolor. The fg_getcolor routine has no arguments and returns the current color as its function value.


CGA Color Modes

    The CGA color modes (modes 4 and 5) have six sets of available colors,

called palettes, numbered 0 to 5. Each palette consists of four colors, �

                                            Chapter 5:  The Use of Color   71


numbered 0 to 3. In each palette, the background color (color value 0) can be selected from the standard color set, but the other 3 colors are fixed. The following table shows the fixed colors assigned to each palette.


                     palette 0       palette 1       palette 2
           color 1   light green     light cyan      light cyan
           color 2   light red       light magenta   light red
           color 3   yellow          white           white
                     palette 3       palette 4       palette 5
           color 1   green           cyan            cyan
           color 2   red             magenta         red
           color 3   brown           gray            gray


Palette 1, with a black background, is the default palette when you select mode 4. Palette 2, with a black background, is the default palette when you select mode 5.

    The CGA color modes have a border area called the overscan between the

addressable pixel space and the physical edges of the screen. The overscan area is always displayed in the background color, regardless of which CGA palette is used.

    In CGA color modes, fg_setcolor defines the current color by referencing

one of the four color values. The fg_palette routine selects one of the six palettes and defines the background color for that palette. The first argument of fg_palette is an integer between 0 and 5 that specifies the palette number. The second argument is an integer between 0 and 15 that defines the background color, using the color numbers in the standard color set.

    Example 5-1 demonstrates the use of fg_palette and fg_setcolor in mode 4.

After establishing the video mode, the program selects palette 0 and makes the background color blue (color number 1). It then makes color 3 in palette 0 (yellow) the current color and displays the word "Hello". Finally, it restores the original video mode and screen attributes before returning to DOS.

                                Example 5-1.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {
                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(4);
                              fg_palette(0,1);
                              fg_setcolor(3);
                              fg_text("Hello",5);                             �

72 Fastgraph User's Guide


                              fg_waitkey();
                              fg_setmode(mode);
                              fg_reset();
                           }


CGA Two-Color Mode

    The CGA two-color mode (mode 6) has a fixed background color (color value

0) and a user-definable foreground color (color value 1). The background color is always black. The foreground color is white by default but can be changed to any of the colors in the standard color set. We should mention that changing the foreground color works on true CGA adapters, but there are very few EGA, VGA, and SVGA adapters that correctly implement changing the foreground color in their mode 6 emulation.

    In mode 6, fg_setcolor defines the current color by referencing one of

the two color values. The fg_palette routine defines the actual foreground color (that is, the color of pixels whose color value is 1). For consistency with other graphics modes, fg_palette has two arguments, but the first one is not used. The second argument is an integer between 0 and 15 that defines the foreground color, using the color numbers in the standard color set.

    Example 5-2 demonstrates the use of fg_palette and fg_setcolor in mode 6.

After establishing the video mode, the program makes the foreground color yellow (color number 14). It then makes color 1 the current color and displays the word "Hello". Finally, it restores the original video mode and screen attributes before returning to DOS.

                                Example 5-2.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {
                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(6);
                              fg_palette(0,14);
                              fg_setcolor(1);
                              fg_text("Hello",5);
                              fg_waitkey();
                              fg_setmode(mode);
                              fg_reset();
                           }                                                  �
                                            Chapter 5:  The Use of Color   73


Tandy and PCjr Modes

    The supported Tandy 1000 or PCjr graphics mode (mode 9) has 16 color

values, numbered 0 to 15. Each color value references one of 16 user-definable palette registers, often simply called palettes, also numbered 0 to 15. The values assigned to the palette registers determine the colors in which pixels are displayed. For example, if you assign palette register 2 the value for red, then pixels whose color value is 2 will be red.

    Each palette can assume one of the 16 colors in the standard color set.

By default, the values assigned to the 16 palettes correspond to the identically numbered colors in the standard color set. In other words, palette 0 is assigned the value for black, palette 1 is assigned the value for blue, and so forth.

    In mode 9, fg_setcolor defines the current color by referencing one of

the 16 palette registers. The fg_palette routine defines the actual color assigned to a specific palette register. The first argument of fg_palette is an integer between 0 and 15 that specifies the palette number. The second argument is an integer between 0 and 15 that defines the palette value (the color assigned to the palette), using the IRGB color numbers in the standard color set.

    You also can use the Fastgraph routine fg_setrgb to define the color

assigned to a specific palette register. While fg_palette does this using a color number from the standard color set, fg_setrgb defines a palette register using red, green, and blue color components plus an intensity component. The first argument of fg_setrgb is an integer between 0 and 15 that specifies the palette register number. The remaining three arguments are each integer values between -1 and 1 that respectively specify the red, green, and blue color components for that palette register. The meanings of the color components are:

    -1 = color bit and intensity bit are set
     0 = color bit is reset
     1 = color bit is set

Since there is only one intensity bit in mode 9 color values, specifying -1 for any of the RGB color components produces an intense color. For example, the color light cyan is color number 11 in the standard color set, and it is produced by combining green and blue and setting the intensity bit. This means any of these four statements


                            fg_palette(1,11);
                            fg_setrgb(1,0,-1,1);
                            fg_setrgb(1,0,1,-1);
                            fg_setrgb(1,0,-1,-1);


could be used to define palette register 1 as light cyan in mode 9.

    Example 5-3 demonstrates the use of fg_palette and fg_setcolor in mode 9.

After establishing the video mode, the program defines palette 0 to be blue (1) and palette 1 to be yellow (14). Note that defining palette 0 changes the � 74 Fastgraph User's Guide


background color. It then makes color 1 the current color and displays the word "Hello". After waiting for a keystroke, the program changes the color of "Hello" by changing palette 1 to white (15). Finally, it restores the original video mode and screen attributes before returning to DOS.

                                Example 5-3.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {
                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(9);
                              fg_palette(0,1);
                              fg_palette(1,14);
                              fg_setcolor(1);
                              fg_text("Hello",5);
                              fg_waitkey();
                              fg_palette(1,15);
                              fg_waitkey();
                              fg_setmode(mode);
                              fg_reset();
                           }


Hercules Mode

    The Hercules graphics mode (mode 11) has a fixed background color (color

value 0) and a fixed foreground color (color value 1). The background color is always black, and the foreground color is dependent on the monochrome display being used (typically it is green, amber, or white).

    The fg_setcolor routine defines the current color value by referencing

one of the two color values. The fg_palette routine has no effect in mode 11.

    Example 5-4 demonstrates the use of fg_setcolor in mode 11. After

establishing the video mode, the program makes color 1 the current color and displays the word "Hello". It then restores the original video mode and screen attributes before returning to DOS.

                                Example 5-4.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {                                                  �
                                            Chapter 5:  The Use of Color   75


                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(11);
                              fg_setcolor(1);
                              fg_text("Hello",5);
                              fg_waitkey();
                              fg_setmode(mode);
                              fg_reset();
                           }


Hercules Low-Resolution Mode

    The Hercules low-resolution graphics mode (mode 12) has four color

values, numbered 0 to 3. The background color is always black, colors 1 and 2 are normal intensity, and color 3 is full intensity. Colors 1 and 2 both produce normal intensity colors, but they do so with different pixel patterns -- color 1 turns on the odd-numbered physical pixels, while color 2 turns on the even-numbered physical pixels. The appearance of colors 1 to 3 is dependent on the monochrome display being used (typically it is green, amber, or white).

    The fg_setcolor routine defines the current color value by referencing

one of the four color values. The fg_palette routine has no effect in mode 12.

    Example 5-5 demonstrates the use of fg_setcolor in mode 12. After

establishing the video mode, the program makes color 3 the current color and displays the word "Hello". It then restores the original video mode and screen attributes before returning to DOS.

                                Example 5-5.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {
                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(12);
                              fg_setcolor(3);
                              fg_text("Hello",5);
                              fg_waitkey();
                              fg_setmode(mode);
                              fg_reset();
                           }                                                  �

76 Fastgraph User's Guide



EGA 200-Line Modes

    The 200-line EGA graphics modes (modes 13 and 14) have 16 color values,

numbered 0 to 15. Each color value references one of 16 user-definable palette registers, often simply called palettes, also numbered 0 to 15. The values assigned to the palette registers determine the colors in which pixels are displayed. For example, if you assign palette register 2 the value for red, then pixels whose color value is 2 will be red.

    Each palette can assume one of the 16 colors in the standard color set.

By default, the values assigned to the 16 palettes correspond to the identically numbered colors in the standard color set. In other words, palette 0 is assigned the value for black, palette 1 is assigned the value for blue, and so forth.

    In modes 13 and 14, fg_setcolor defines the current color by referencing

one of 16 available palette registers. The fg_palette routine defines the actual color assigned to a specific palette register. The first argument of fg_palette is an integer between 0 and 15 that specifies the palette number. The second argument is an integer that defines the palette value (the color assigned to the palette). Although the actual colors are taken from the standard color set, the binary structure of a palette value is different from the IRGB format used in the standard color set. In modes 13 and 14, the binary structure of a palette value is IxRGB; bit 3 is ignored. The mode 13 and mode 14 palette values that correspond to the standard color set are thus:

                      value     color     value     color
                        0       black      16     dark gray
                        1       blue       17    light blue
                        2       green      18    light green
                        3       cyan       19    light cyan
                        4        red       20     light red
                        5      magenta     21   light magenta
                        6       brown      22      yellow
                        7       gray       23       white
    You also can use the Fastgraph routine fg_setrgb to define the color

assigned to a specific palette register. While fg_palette does this using a color number from the standard color set, fg_setrgb defines a palette register using red, green, and blue color components, plus an intensity component. The first argument of fg_setrgb is an integer between 0 and 15 that specifies the palette register number. The remaining three arguments are each integer values between -1 and 1 that respectively specify the red, green, and blue color components for that palette register. The meanings of the color components are:

    -1 = color bit and intensity bit are set
     0 = color bit is reset
     1 = color bit is set

Since there is only one intensity bit in mode 13 and 14 color values, specifying -1 for any of the RGB color components produces an intense color. For example, light cyan is represented by the color value 19, and it is �

                                            Chapter 5:  The Use of Color   77


produced by combining green and blue and setting the intensity bit. This means any of these four statements


                            fg_palette(1,19);
                            fg_setrgb(1,0,-1,1);
                            fg_setrgb(1,0,1,-1);
                            fg_setrgb(1,0,-1,-1);


could be used to define palette register 1 as light cyan in modes 13 and 14.

    The Fastgraph routine fg_setcolor defines the color value (that is, the

palette number) in which subsequent graphics operations are performed. The fg_setcolor routine takes a single integer argument that specifies this color. When fg_setmode is called, it sets the color value to 0. The Fastgraph routine fg_getcolor returns the current color value, as defined in the most recent call to fg_setcolor. The fg_getcolor routine has no arguments and returns the current color as the function value.

    Example 5-6 demonstrates the use of fg_palette and fg_setcolor in mode

13. After establishing the video mode, the program defines palette 0 to be blue (1) and palette 1 to be yellow (22). Note that defining palette 0 changes the background color. It then makes color 1 the current color and displays the word "Hello". After waiting for a keystroke, the program changes the color of "Hello" by changing palette 1 to white (23). Finally, it restores the original video mode and screen attributes before returning to DOS.

                                Example 5-6.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {
                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(13);
                              fg_palette(0,1);
                              fg_palette(1,22);
                              fg_setcolor(1);
                              fg_text("Hello",5);
                              fg_waitkey();
                              fg_palette(1,23);
                              fg_waitkey();
                              fg_setmode(mode);
                              fg_reset();
                           }                                                  �

78 Fastgraph User's Guide


EGA Monochrome Mode

    The EGA monochrome graphics mode (mode 15) assigns display attributes to

its four color values, numbered 0 to 3. Each color value references one of four user-definable palette registers, often simply called palettes, numbered 0, 1, 4, and 5. This strange numbering results from the disabling of two of the four video memory bit planes in mode 15. The values assigned to the palette registers determine the pixel display attribute. For example, if you assign palette register 1 the value for bold, then pixels whose value is 1 will be bold.

    In mode 15, fg_setcolor defines the current color (actually, a display

attribute) by referencing one of the four palette registers. The fg_palette routine defines the actual display attribute assigned to a specific palette register. The first argument of fg_palette is an integer that specifies the palette number. The second argument is an integer that defines the palette value (the display attribute assigned to the palette). For each palette register, the following table shows the default palette value and its associated display attribute.

                          palette   palette   display
                          number     value   attribute
                             0         0     invisible
                             1         8      normal
                             4        24       bold
                             5        24       bold
    Example 5-7 demonstrates the use of fg_palette and fg_setcolor in mode

15. After establishing the video mode, the program makes color 4 (actually, palette 4, which is bold by default) the current color and displays the word "Hello". After waiting for a keystroke, the program changes the display attribute of "Hello" by changing palette 4 to normal intensity (palette value 8). Finally, it restores the original video mode and screen attributes before returning to DOS.

                                Example 5-7.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {
                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(15);
                              fg_setcolor(4);
                              fg_text("Hello",5);
                              fg_waitkey();
                              fg_palette(4,8);
                              fg_waitkey();                                   �
                                            Chapter 5:  The Use of Color   79


                              fg_setmode(mode);
                              fg_reset();
                           }


EGA Enhanced Mode

    The EGA enhanced graphics mode (mode 16) has 16 color values, numbered 0

to 15. Each color value references one of 16 user-definable palette registers, often simply called palettes, also numbered 0 to 15. The values assigned to the palette registers determine the colors in which pixels are displayed. For example, if you assign palette register 2 the value for red, then pixels whose color value is 2 will be red.

    Each palette can assume one of 64 available colors. By default, the

values assigned to the 16 palettes correspond to the identically numbered colors in the standard color set. In other words, palette 0 is assigned the value for black, palette 1 is assigned the value for blue, and so forth. There are a few EGA-compatible adapters that do not properly assign the default colors to the 16 palette registers, so it is a good practice to do this explicitly in mode 16.

    In mode 16, fg_setcolor defines the current color value by referencing

one of the 16 palette registers. The fg_palette routine defines the actual color assigned to a specific palette register. The first argument of fg_palette is an integer between 0 and 15 that specifies the palette number. The second argument is an integer that defines the palette value (the color assigned to the palette). The binary structure of a palette value is different from the IRGB format used in the standard color set. In mode 16, the binary structure of a palette value is a 6-bit quantity of the form rgbRGB, where the lower case letters represent the low intensity (1/3 intensity) color components, and the upper case letters represent the normal intensity (2/3 intensity) color components. The mode 16 palette values that correspond to the standard color set are:

            value        color          value        color
              0          black           56          dark gray
              1          blue            57          light blue
              2          green           58          light green
              3          cyan            59          light cyan
              4          red             60          light red
              5          magenta         61          light magenta
             20          brown           62          yellow
              7          gray            63          white
    The normal intensity components in mode 16 produce the same normal

intensity colors as in other 16-color graphics modes. Similarly, combining the low and normal intensities in mode 16 produces the high intensity colors of the other modes. The only exception to this is for the default brown, formed from the bit pattern 010100 (20 decimal). This value produces a more true brown than the value 6 decimal, which is really an olive green. � 80 Fastgraph User's Guide


    The palette values used in mode 16 are 6-bit quantities, which means

there are 64 different colors available in mode 16. This group of 64 colors consists of the 16 colors in the standard color set plus 48 additional colors that are not available in any other EGA modes. However, because the EGA palette registers hold 4-bit quantities, only 16 of these colors can be displayed at the same time. In other words, the EGA enhanced mode provides the capability of displaying 16 simultaneous colors from a group of 64.

    You also can use the Fastgraph routine fg_setrgb to define the color

assigned to a specific palette register. While fg_palette does this using a value between 0 and 63, fg_setrgb defines a palette register using red, green, and blue color components. The first argument of fg_setrgb is an integer between 0 and 15 that specifies the palette register number. The remaining three arguments are each integer values between 0 and 3 that respectively specify the intensities in thirds of the red, green, and blue color components for that palette register. For example, the color cyan is represented by the value 3 in the above table, and it is produced by combining normal intensity (2/3 intensity) green and blue. This means either of the statements


                             fg_palette(1,3);
                             fg_setrgb(1,0,2,2);


could be used to define palette register 1 as cyan.

    Example 5-8 demonstrates the use of fg_palette and fg_setcolor in mode

16. It uses the Fastgraph routine fg_rect (discussed in the next chapter) to draw rectangles of a specified size. After establishing the video mode, the program uses a for loop to draw 16 equal-size rectangles, one in each of the 16 color values. In the same loop, the program uses fg_palette to change each palette to black. The while loop that follows performs four iterations. The first iteration changes palette 0 to 0, palette 1 to 1, and so forth. Hence, the 16 rectangles appear in the palette values 0 to 15. The rectangles remain in these colors until is key is pressed to begin the next iteration. The second iteration changes palette 0 to 16, palette 1 to 17, and so forth. This makes the 16 rectangles appear in the palette values 16 to 31. Iterations three and four are similar, so the overall effect of the program is to display all 64 colors, 16 at a time. Finally, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 5-8.
               #include <fastgraf.h>
               void main(void);
               #define COLORS 16
               #define WIDTH  40
               void main()
               {
                  int base;
                  int color;
                  int minx, maxx;
                  int mode;                                                   �
                                            Chapter 5:  The Use of Color   81


                  fg_initpm();
                  mode = fg_getmode();
                  fg_setmode(16);
                  base = 0;
                  minx = 0;
                  maxx = WIDTH - 1;
                  for (color = 0; color < COLORS; color++) {
                     fg_palette(color,0);
                     fg_setcolor(color);
                     fg_rect(minx,maxx,0,349);
                     minx = maxx + 1;
                     maxx = maxx + WIDTH;
                     }
                  while (base < COLORS*4) {
                     for (color = 0; color < COLORS; color++)
                        fg_palette(color,base+color);
                     base += COLORS;
                     fg_waitkey();
                     }
                  fg_setmode(mode);
                  fg_reset();
               }


VGA and MCGA Two-Color Mode

    The VGA and MCGA two-color mode (mode 17) has a background color (color

value 0) and a foreground color (color value 1). Each color value references one of two user-definable palette registers, often simply called palettes, also numbered 0 and 1. Each palette register in turn references one of 16 user-definable 18-bit video DAC registers, numbered 0 to 15. The values assigned to the palette registers and video DAC registers determine the colors in which pixels are displayed. For example, if palette register 1 contains the value 3, and video DAC register 3 contains the color value for red, then pixels whose color value is 1 (that is, the foreground pixels) will be red.

    By default, palette register 0 references video DAC register 0, and

palette register 1 references video DAC register 1. In addition, video DAC register 0 initially contains the color value for black, while the other 15 video DAC registers (1 through 15) contain the color value for white. This means background pixels (color value 0) are black by default, while foreground pixels (color value 1) are white.

    The 18-bit video DAC values consist of three 6-bit red, green, and blue

color components. Hence, each color component is an integer between 0 and 63; increasing values produce more intense colors. The default color components for DAC register 0 are red=0, blue=0, and green=0, which produces black. The default values for the other DAC registers are red=63, blue=63, and green=63, which produces white. Because the video DAC registers are 18 bits long, each DAC can specify one of 262,144 (2**18) colors. However, because the palette registers hold 1-bit quantities, only two of these colors can be displayed at � 82 Fastgraph User's Guide


the same time. In other words, mode 17 provides the capability of displaying two simultaneous colors from a group of 262,144.

    In mode 17, fg_setcolor defines the current color by referencing one of

the two palette registers. The fg_palette routine defines the value of a palette register by referencing one of the 16 video DAC registers. That is, fg_palette specifies the video DAC register that a palette register references. The first argument of fg_palette is either 0 or 1 and specifies the palette number. The second argument is an integer between 0 and 15 that specifies the video DAC register for that palette.

    The Fastgraph routine fg_setrgb defines the value of a video DAC register

in mode 17. The first argument of fg_setrgb is an integer between 0 and 15 that specifies the DAC register number. The remaining three arguments are each integer values between 0 and 63 that respectively specify the red, green, and blue color components for that DAC register.

    Example 5-9 demonstrates the use of fg_palette, fg_setrgb, and

fg_setcolor in mode 17. After establishing the video mode, the program defines DAC register 0 to be blue (red=0, green=0, blue=42) and DAC register 1 to be yellow (red=63, green=63, blue=21). Note that defining DAC register 0 changes the background color because palette 0 references DAC register 0. The program then makes color 1 the current color (palette 1 still references DAC register 1) and displays the word "Hello" in yellow. After waiting for a keystroke, the program changes the color of "Hello" by making palette 1 reference DAC register 15 (which still contains its default value, white). Finally, it restores the original video mode and screen attributes before returning to DOS.

                                Example 5-9.
                          #include <fastgraf.h>
                          void main(void);
                          void main()
                          {
                             int mode;
                             fg_initpm();
                             mode = fg_getmode();
                             fg_setmode(17);
                             fg_setrgb(0,0,0,42);
                             fg_setrgb(1,63,63,21);
                             fg_setcolor(1);
                             fg_text("Hello",5);
                             fg_waitkey();
                             fg_palette(1,15);
                             fg_waitkey();
                             fg_setmode(mode);
                             fg_reset();
                          }                                                   �
                                            Chapter 5:  The Use of Color   83



VGA/SVGA 16-Color Modes

    The VGA and SVGA 16-color modes (modes 18, 28, and 29) have 16 color

values, numbered 0 to 15. Each color value references one of 16 user-definable palette registers, often simply called palettes, also numbered 0 to 15. Each palette register in turn references one of 16 user-definable 18-bit video DAC registers, also numbered 0 to 15. The values assigned to the palette registers and video DAC registers determine the colors in which pixels are displayed. For example, if palette register 1 contains the value 3, and video DAC register 3 contains the color value for red, then pixels whose color value is 1 will be red.

    By default, each of the 16 palette registers references the video DAC

register of the same number. In addition, the 16 video DAC registers respectively contain the color values for the 16 colors in the standard color set.

    The 18-bit video DAC values consist of three 6-bit red, green, and blue

color components. Hence, each color component is an integer between 0 and 63; increasing values produce more intense colors. The default RGB color components for the 16 video DAC registers are:

        DAC  R  G   B    color      DAC  R  G   B      color
         0   0  0   0    black       8  21  21 21    dark gray
         1   0  0  42    blue        9  21  21 63   light blue
         2   0  42  0    green      10  21  63 21   light green
         3   0  42 42    cyan       11  21  63 63   light cyan
         4  42  0   0     red       12  63  21 21    light red
         5  42  0  42   magenta     13  63  21 63  light magenta
         6  42  21  0    brown      14  63  63 21     yellow
         7  42  42 42    gray       15  63  63 63      white

Because the video DAC registers are 18 bits long, each DAC can specify one of 262,144 (2**18) colors. However, because the palette registers hold 4-bit quantities, only 16 of these colors can be displayed at the same time. In other words, mode 18 provides the capability of displaying 16 simultaneous colors from a group of 262,144.

    In the 16-color VGA and SVGA modes, fg_setcolor, fg_palette, and

fg_setrgb behave exactly as in mode 17 with one exception: there are 16 palette registers instead of just two. Example 5-9 demonstrates the use of these routines in mode 17, but it also would work in mode 18, 28, or 29 if the call to fg_setmode were changed accordingly.


256-Color Modes

    The 256-color modes (modes 19 through 27) have 256 color values, numbered

0 to 255. Each color value directly references one of 256 user-definable 18- bit video DAC registers, also numbered 0 to 255. The values assigned to the video DAC registers determine the colors in which pixels are displayed. For example, if video DAC register 3 contains the color value for red, then pixels whose color value is 3 will be red. � 84 Fastgraph User's Guide


    By default, the first 16 video DAC registers (0 to 15) contain the color

values for the standard color set. The next 16 DAC registers (16 to 31) contain the color values for a gray scale of gradually increasing intensity. The next 216 DAC registers (32 to 247) contain three groups of 72 colors each, with the first group (32 to 103) at high intensity, the second group (104 to 175) at moderate intensity, and the third group (176 to 247) at low intensity. Each group consists of three ranges of decreasing saturation (increasing whiteness), with each range varying in hue from blue to red to green. Finally, the last 8 DAC registers (248 to 255) alternate between black and white. This information is summarized in the following table.

    DACs         default color values
    0 to 15      standard color set
    16 to 31     gray scale of gradually increasing intensity
    32 to 55     high saturation, high intensity colors
    56 to 79     moderate saturation, high intensity colors
    80 to 103    low saturation, high intensity colors
    104 to 127   high saturation, moderate intensity colors
    128 to 151   moderate saturation, moderate intensity colors
    152 to 175   low saturation, moderate intensity colors
    176 to 199   high saturation, low intensity colors
    200 to 223   moderate saturation, low intensity colors
    224 to 247   low saturation, low intensity colors
    248 to 255   alternate between black and white
    The 18-bit video DAC values consist of three 6-bit red, green, and blue

color components. Hence, each color component is an integer between 0 and 63; increasing values produce more intense colors. Because the video DAC registers are 18 bits long, each DAC can specify one of 262,144 (2**18) colors. However, because the color values are 8-bit quantities, only 256 of these colors can be displayed at the same time. In other words, modes 19 through 27 provide the capability of displaying 256 simultaneous colors from a group of 262,144.

    In the 256-color graphics modes, fg_setcolor defines the current color by

referencing one of the 256 video DAC registers. The fg_setrgb routine defines the actual color of a video DAC register. The first argument of fg_setrgb is an integer between 0 and 255 that specifies the DAC register number. The remaining three arguments are each integer values between 0 and 63 that respectively specify the red, green, and blue color components for that DAC register. Another Fastgraph routine, fg_getrgb, returns the color components for a specified DAC register. Its arguments are the same as for fg_setrgb, except the last three arguments (the return values) are passed by reference rather than by value.

    You also can use the Fastgraph routine fg_palette to define the value of

a video DAC register in modes 19 through 27. The first argument of fg_palette is an integer between 0 and 255 that specifies the DAC register number. The second argument is an integer between 0 and 63 that specifies the color value for that video DAC register, using the same 64 values as in the EGA enhanced mode (mode 16).

    Example 5-10 demonstrates the use of fg_setcolor in mode 19. The program

uses the Fastgraph routine fg_rect to draw vertical lines. After establishing the video mode, the program uses a for loop to draw 256 vertical lines, one in �

                                            Chapter 5:  The Use of Color   85


each of the 256 colors (using the default DAC values). Finally, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 5-10.
                #include <fastgraf.h>
                void main(void);
                #define COLORS 256
                void main()
                {
                   int base;
                   int color;
                   int mode;
                   int x;
                   fg_initpm();
                   mode = fg_getmode();
                   fg_setmode(19);
                   x = 0;
                   for (color = 0; color < COLORS; color++) {
                      fg_setcolor(color);
                      fg_rect(x,x,0,199);
                      x++;
                      }
                   fg_waitkey();
                   fg_setmode(mode);
                   fg_reset();
                }


    Example 5-11 shows an interesting effect available in video modes that

support DAC registers. The program uses the Fastgraph routine fg_waitfor (discussed in Chapter 16) to delay the program's execution. After establishing the video mode, the program displays the word "Hello" in color 103, which by default is a pastel blue. It then uses fg_getrgb to retrieve the color components for this color. The while loop gradually decreases the color components until all three components are zero, which makes the word "Hello" smoothly fade to black. Finally, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 5-11.
                    #include <fastgraf.h>
                    void main(void);
                    void main()
                    {
                       int old_mode;
                       int red, green, blue;                                  �

86 Fastgraph User's Guide


                       fg_initpm();
                       old_mode = fg_getmode();
                       fg_setmode(19);
                       fg_setcolor(103);
                       fg_text("Hello",5);
                       fg_waitfor(18);
                       fg_getrgb(103,&red,&green,&blue);
                       while (red+green+blue > 0) {
                          if (red > 0) red--;
                          if (green > 0) green--;
                          if (blue > 0) blue--;
                          fg_setrgb(103,red,green,blue);
                          fg_waitfor(1);
                          }
                       fg_setmode(old_mode);
                       fg_reset();
                    }


    The fg_setrgb and fg_getrgb routines work with individual DAC registers.

If you want to define or retrieve a block of consecutive DAC registers, fg_setdacs and fg_getdacs are more efficient. The fg_setdacs routine defines the values of a block of consecutive DAC registers. Its first argument is the index of the first DAC register to define (between 0 and 255), and its second argument is the number of DAC registers to define (between 1 and 256). The third argument is a byte array containing the RGB color components for the DAC registers being defined. The array's first three bytes contain the red, green, and blue components for the first DAC, the next three for the second DAC, and so forth. The size of this array must be at least three times the value of the second argument. The fg_getdacs arguments are the same as those for fg_setdacs, but the RGB array instead receives the current values of the specified DAC registers. Both routines treat the DAC register numbers in a circular fashion (for example, defining four DACs starting with number 254 will define DACs 254, 255, 0, and 1).

    Example 5-12 is similar to example 5-11, but it fades many colors

simultaneously. The program displays seven asterisks, one each in colors 9 through 15. It uses fg_getdacs to obtain the current settings of the corresponding DAC registers; these values are stored in the array RGBvalues. The while loop gradually fades the RGB components to zero, using fg_setdacs to update their values, similar to the method of example 5-11. This illustrates an attractive way of turning an image into a blank screen.

                                Example 5-12.
                      #include <fastgraf.h>
                      void main(void);
                      void main()
                      {
                         int decreasing;
                         int i;                                               �
                                            Chapter 5:  The Use of Color   87


                         int old_mode;
                         char RGBvalues[21];
                         fg_initpm();
                         old_mode = fg_getmode();
                         fg_setmode(19);
                         for (i = 9; i <= 15; i++) {
                            fg_setcolor(i);
                            fg_text("*",1);
                            }
                         fg_getdacs(9,7,RGBvalues);
                         fg_waitfor(18);
                         do {
                            decreasing = 0;
                            for (i = 0; i < 21; i++)
                               if (RGBvalues[i] > 0) {
                                  RGBvalues[i]--;
                                  decreasing = 1;
                                  }
                            fg_setdacs(9,7,RGBvalues);
                            fg_waitfor(1);
                            }
                         while (decreasing);
                         fg_setmode(old_mode);
                         fg_reset();
                      }


Note that examples 5-11 and 5-12 also would work in 16-color VGA and SVGA video modes as long as you just use the first 16 video DAC registers.


Using Video DAC Registers in EGA Modes

    The fg_getdacs and fg_setdacs routines also work in modes 13, 14, and 16

when used on a VGA or SVGA system. This lets you choose 16 colors from a palette of 262,144 colors, as in mode 18. If you try to use these routines on an EGA system, the results are unpredictable. Applications that use these routines should therefore first insure they are running on a VGA or SVGA system by checking if fg_testmode(18,0) returns a nonzero value.

    Before trying to use fg_getdacs and fg_setdacs in modes 13, 14, and 16,

you should first be aware of the relationship between VGA palettes and DAC registers. On the EGA, palette values directly determine the color displayed. On the VGA and SVGA, however, there is an added level of indirection. VGA and SVGA palette registers can be thought of as pointers to video DAC registers whose RGB components determine the displayed color.

    Each palette register in the VGA 640x480 16-color graphics mode (mode 18)

initially points to the DAC register of the same number. We can thus pretend the indirection does not exist because changing DAC register n affects those pixels whose color value is n (unless, of course, we've changed the value of � 88 Fastgraph User's Guide


palette register n). In modes 13, 14, and 16, we can't ignore the indirection because the palette registers contain different values. In mode 13, for instance, palette register 8 contains the value 16 by default, not the value 8 as in mode 18.

    The easiest way around this inconsistency is to set the palette and DAC

registers explicitly so they correspond to the default values of mode 18. There are two cases to consider -- one for modes 13 and 14, and the other for mode 16.

    In modes 13 and 14, palettes 0 to 7 contain the values 0 to 7, but

palettes 8 to 15 contain the values 16 to 23. Hence, if you want to use fg_getdacs and fg_setdacs in these modes, you should include the following code after calling fg_setmode.


                       char RGBvalues[3];
                       int i;
                       for (i = 8; i < 16; i++) {
                          fg_getdacs(i+8,1,RGBvalues);
                          fg_setdacs(i,1,RGBvalues);
                          fg_palette(i,i);
                       }


This code will set the values of DACs 8 to 15 to the values of DACs 16 to 23. It also sets palettes 8 to 15 to point to DACs 8 to 15. You can then ignore the palette-DAC indirection because setting DAC register n affects pixels of color n.

    In mode 16, palette 6 is initially assigned the value 20, and palettes 8

to 15 are assigned the values 56 to 63. All other palettes point to the DAC of the same number. Hence, if you want to use fg_getdacs and fg_setdacs in mode 16, you should include the following code after calling fg_setmode.


                       char RGBvalues[3];
                       int i;
                       fg_getdacs(20,1,RGBvalues);
                       fg_setdacs(6,1,RGBvalues);
                       fg_palette(6,6);
                       for (i = 8; i < 16; i++) {
                          fg_getdacs(i+48,1,RGBvalues);
                          fg_setdacs(i,1,RGBvalues);
                          fg_palette(i,i);
                       }


This code will set the values of DAC 6 to the values of DAC 20, and also DACs 8 to 15 to the values of DACs 56 to 63. It also sets palettes 6 and 8-15 to point to the identically-numbered DACs. You can then ignore the palette-DAC indirection because setting DAC register n affects pixels of color n. �

                                            Chapter 5:  The Use of Color   89


    While this might all seem complicated at first, it really isn't once you

understand the relationship between palettes and DACs. The ability to select colors from a palette of 256K colors instead of 16 or 64 is usually well worth the extra effort.


RGB Color Mapping

    If you're developing an application that runs in 256-color and 16-color

graphics modes, you've probably noticed the inherent differences in defining color values. In fact, the palette register values even use different structures within the various 16-color modes. The Fastgraph routine fg_maprgb helps simplify these differences. It maps three RGB color components (each between 0 and 63) into a 16-color palette value suitable for the current video mode. Of course, the range of available colors is much more restricted in the 16-color modes than in the 256-color modes, so fg_maprgb must map the RGB components to the closest available color.

    Example 5-13 runs in any 16-color or 256-color graphics mode and

demonstrates the use of the fg_maprgb routine. In 256-color modes, the program simply uses fg_setrgb to define DAC register 1 to a pastel blue (red=45, green=49, blue=63). In 16-color modes, however, the program calls fg_maprgb to convert the color components into a palette value in IRGB, IxRGB, or rgbRGB format (depending on the current video mode). The fg_maprgb return value is passed to fg_palette to set palette register 1 to the closest available color defined by the specified RGB components.

                                Example 5-13.
          #include <fastgraf.h>
          #include <stdio.h>
          #include <stdlib.h>
          void main(void);
          void main()
          {
             int new_mode, old_mode;
             fg_initpm();
             new_mode = fg_bestmode(320,200,1);
             if (new_mode < 0 || new_mode == 4 || new_mode == 12) {
                printf("This program requires a 320 x 200 ");
                printf("16-color or 256-color graphics mode.\n");
                exit(1);
                }
             old_mode = fg_getmode();
             fg_setmode(new_mode);
             fg_setcolor(1);
             if (new_mode <= 16)
                fg_palette(1,fg_maprgb(45,49,63));
             else
                fg_setrgb(1,45,49,63);
             fg_text("Hello",5);
             fg_waitkey();                                                    �

90 Fastgraph User's Guide


             fg_setmode(old_mode);
             fg_reset();
          }


Defining All Palette Registers

    Fastgraph includes a routine fg_palettes that defines all 16 palette

registers in 16-color graphics modes. You also can use fg_palettes to define the first 16 video DAC registers in 256-color modes. It has no effect in other video modes.

    Using fg_palettes is much faster than calling fg_palette 16 times. The

argument to fg_palettes is a 16-element integer array that contains the color values assigned respectively to palette registers (or video DAC registers) 0 to 15. Example 5-14 demonstrates how to zero the palette registers (that is, change them all to black) in mode 13.

                                Example 5-14.
              #include <fastgraf.h>
              void main(void);
              int zeroes[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
              void main()
              {
                 int mode;
                 fg_initpm();
                 mode = fg_getmode();
                 fg_setmode(13);
                 fg_palettes(zeroes);
                 fg_setmode(mode);
                 fg_reset();
              }


Of course, as this example is written, it appears to do nothing more than blank the screen. Its purpose is to show an example of the fg_palettes routine.


Virtual Colors

    By this time it should be clear the use of color is rather specific to

each graphics video mode. One of the most obvious differences is the number of available colors in each mode; it ranges from 2 to 256. By available colors, we mean the number of colors that can be displayed simultaneously.

    To simplify programming in graphics modes, Fastgraph provides 256 virtual

colors. The virtual colors are used in the graphics video modes having fewer than 256 available colors. Virtual colors allow you to use 256 color indices �

                                            Chapter 5:  The Use of Color   91


in all graphics modes, even if a particular mode does not have 256 available colors.

    When you establish a video mode with fg_setmode, Fastgraph initializes

all the virtual color indices. It does this by replicating the video mode's color values through the 256 virtual color indices. For example, the CGA color modes (4 and 5) have four color values, numbered 0 through 3. In these modes, fg_setmode initializes color indices 0, 4, 8, ... , 252 to 0; color indices 1, 5, 9, ... , 253 to 1; color indices 2, 6, 10, ... , 254 to 2; and color indices 3, 7, 11, ... , 255 to 3. Similarly, in 16-color graphics modes the color indices 0, 16, 32, ... , 240 are set to 0, and so forth. In the monochrome EGA graphics video mode (mode 15), the color values are numbered 0, 1, 4, and 5, so fg_setmode replicates the color indices in groups of eight, even though there are only four available colors. An analysis of the color value sequences reveals an often useful feature: by default, virtual color 0 is black and virtual colors 15 and 255 are white in all graphics video modes.

    It is thus possible to write a multiple-mode program using the same color

indices for each graphics mode. For example, a program that contains the statement fg_setcolor(5) would produce subsequent graphics in color 5 (magenta by default) when running in a 16-color graphics mode. It would produce subsequent graphics in color 1 (light cyan by default) when running in a CGA color mode. This is because 1 is the default value assigned to virtual color index 5 in the CGA color modes.

    The fg_setmode routine establishes default values for the 256 virtual

color indices, but it might be desirable to assign other available colors to them. Going back to the discussion in the previous paragraph, color number 2 is light magenta in the default CGA mode 4 palette. It might make more sense if the color value 2 were assigned to virtual color index 5, as this would make the graphics drawn in color 5 the same color in mode 4 as in other color modes. The Fastgraph routine fg_defcolor is provided for this purpose.

    The fg_defcolor routine assigns a color value to a virtual color index.

It has two arguments: the first specifies the virtual color index (between 0 and 255), and the second specifies the color value (between 0 and one less than the number of available colors in the current video mode). For example, the statement

                              fg_defcolor(5,2);

would assign the color value 2 to the color index 5. Another Fastgraph routine, fg_getindex, returns the current value assigned to a specified color index. After executing the above call to fg_defcolor, the statement

                           color = fg_getindex(5);

would store the value 2 (the current value of color index 5) in the integer variable color.

    We must be sure to understand the difference between virtual colors and

palette registers. Modifying the value of a palette register changes the color of all pixels already drawn using that palette. Modifying a virtual color index does not do this; it only specifies any graphics drawn in that color from this point on will appear in the new color. � 92 Fastgraph User's Guide


    Example 5-15 demonstrates virtual colors in mode 4. After establishing

the video mode, the program uses fg_defcolor to define virtual color indices 0 and 255 to be 1, which by default is light cyan in mode 4. It then draws characters using color indices 0, 1, and 255, and in each case the characters appear in light cyan. Finally, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 5-15.
                           #include <fastgraf.h>
                           void main(void);
                           void main()
                           {
                              int mode;
                              fg_initpm();
                              mode = fg_getmode();
                              fg_setmode(4);
                              fg_defcolor(0,1);
                              fg_defcolor(255,1);
                              fg_setcolor(0);
                              fg_text("0",1);
                              fg_setcolor(1);
                              fg_text(" 1",2);
                              fg_setcolor(255);
                              fg_text(" 255",4);
                              fg_waitkey();
                              fg_setmode(mode);
                              fg_reset();
                           }


A Multiple-Mode Example

    Although the color capabilities differ between the supported video modes,

Fastgraph makes it easy to write a program that runs in many video modes. This section will present an example of such a program.

    Example 5-16 illustrates a program that will run in any of Fastgraph's

supported video modes. The program first asks for the video mode number, checks if the mode number is valid, and then checks if the requested mode is available on the user's system. After doing this, the program establishes the video mode and performs its mode-specific code. It then displays a brief message that includes the video mode number in which the program is running. This information remains on the screen until a key is pressed, at which time the program restores the original video mode and screen attributes before returning to DOS.

                                Example 5-16.
      #include <fastgraf.h>                                                   �
                                            Chapter 5:  The Use of Color   93


      #include <stdio.h>
      #include <stdlib.h>
      void main(void);
      void main()
      {
         int mode, old_mode;
         char string[5];
      /* Ask for the video mode number */
         printf("Which video mode? ");
         scanf("%d",&mode);
      /* Make sure the entered value is valid */
         if (mode < 0 || mode > 29) {
            printf("%d is not a valid video mode number.\n",mode);
            exit(1);
            }
      /* Make sure the requested video mode is available */
         fg_initpm();
         if (mode > 23) fg_svgainit(0);
         if (fg_testmode(mode,1) == 0) {
            printf("Mode %d is not available on this system.\n",mode);
            exit(1);
            }
      /* Establish the video mode */
         old_mode = fg_getmode();
         fg_setmode(mode);
      /* Perform mode-specific initializations */
         if (mode <= 3 || mode == 7)   /* text modes */
            fg_cursor(0);
         else if (mode == 4 || mode == 5) { /* CGA color modes */
            fg_palette(0,0);
            fg_defcolor(14,3);
            }
         else if (mode == 6) {         /* CGA two-color mode */
            fg_palette(0,14);
            fg_defcolor(14,1);
            }
         else if (mode == 11)          /* Hercules mode */
            fg_defcolor(14,1);
         else if (mode == 12)          /* Hercules low-res mode */
            fg_defcolor(14,3);
         else if (mode == 17) {        /* VGA two-color mode */
            fg_palette(1,14);
            fg_setrgb(14,63,63,21);
            fg_defcolor(14,1);
            }                                                                 �

94 Fastgraph User's Guide


      /* Display a message that includes the video mode number */
         fg_setcolor(14);
         fg_text("I'm running in mode ",20);
         sprintf(string,"%d. ",mode);
         fg_text(string,3);
      /* Wait for a keystroke */
         fg_waitkey();
      /* Restore the original video mode and screen attributes */
         fg_setmode(old_mode);
         fg_reset();
      }


    Example 5-16 displays its message in yellow for those video modes that

offer color. In monochrome video modes, it displays the message in normal intensity. The program uses virtual color 14, which by default is yellow in many video modes; the mode-specific code in example 5-16 makes color 14 yellow in other video modes. In text video modes (modes 0 to 3 and 7), the program uses fg_cursor to make the cursor invisible. In CGA color modes (modes 4 and 5), the program uses fg_palette to select a CGA palette that contains yellow as color 3 and then uses fg_defcolor to assign color 3 to virtual color 14. In CGA two-color mode (mode 6), the program uses fg_palette to make color 1 yellow and then uses fg_defcolor to assign color 1 to virtual color 14. In the Hercules modes (modes 11 and 12), the program uses fg_defcolor to assign the value for normal intensity pixels to color 14. In VGA two-color mode (mode 17), the program uses fg_palette to assign video DAC register 14 to palette register 1. It then defines video DAC register 14 to be yellow with fg_setrgb and finally uses fg_defcolor to assign color 1 (that is, palette register 1) to virtual color 14. In all other video modes, no color manipulation is needed because color 14 is yellow by default.


Summary of Color-Related Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_COLORS returns the number of simultaneously available colors in the

current video mode. In text video modes, fg_colors returns zero.

    FG_DEFCOLOR assigns a color value to a virtual color index. This routine

is only meaningful in graphics video modes that have fewer than 256 available colors.

    FG_GETCOLOR returns the current text attribute (in text modes) or color

index (in graphics modes), as specified in the most recent call to fg_setattr or fg_setcolor.

    FG_GETDACS retrieves the red, green, and blue color components for a

block of consecutively numbered video DAC registers. This routine is only meaningful modes that use DAC registers. �

                                            Chapter 5:  The Use of Color   95


    FG_GETINDEX returns the color value assigned to a specified virtual color

index. In text modes and in graphics modes that have 256 available colors, this routine returns the value passed to it.

    FG_GETRGB returns the red, green, and blue color components for a

specified video DAC register. This routine is only meaningful in modes that use DAC registers.

     FG_MAPRGB maps six-bit red, green, and blue color components into a

suitable palette value for the current video mode. You can then pass this value to fg_palette. This routine is meaningful only in 16-color graphics video modes.

    FG_PALETTE has different functions depending on the current graphics

video mode. For the CGA four-color modes, it establishes the current palette (of six available) and defines the background color for that palette. In the CGA two-color mode, it defines the foreground color. For the Tandy/PCjr, EGA, and VGA graphics modes, it defines the value of a single palette register. For 256-color graphics modes, it defines the value of a single video DAC register. The fg_palette routine has no effect in text modes or Hercules graphics modes.

    FG_PALETTES defines all 16 palette registers (in 16-color graphics

modes), or the first 16 video DAC registers (in 256-color graphics modes). The fg_palettes routine has no effect in text modes, CGA graphics modes, or Hercules graphics modes.

    FG_SETATTR establishes the current text attribute in text video modes.

This routine has no effect in graphics modes.

    FG_SETCOLOR establishes the current color index (which may be a virtual

color index in graphics modes). In text modes, fg_setcolor provides an alternate method of establishing the current text attribute.

    FG_SETDACS defines the values of a block of consecutively numbered video

DAC registers by specifying their red, green, and blue color components. This routine is only meaningful in modes that use DAC registers.

    FG_SETRGB defines the value of a single palette register (in Tandy/PCjr

and EGA graphics modes) or video DAC register (in VGA, MCGA, and SVGA modes) by specifying its red, green, and blue color components. The fg_setrgb routine has no effect in text modes, CGA graphics modes, or Hercules graphics modes. � 96 Fastgraph User's Guide




Chapter 6



Graphics Fundamentals � 98 Fastgraph User's Guide


Overview

    This chapter describes Fastgraph's fundamental graphics routines,

sometimes called graphics primitives. These routines perform such functions as clearing the screen, drawing points, drawing solid and dashed lines, drawing closed shapes (polygons, circles, and ellipses), drawing rectangles (solid, hollow, and dithered), and filling arbitrary regions. Most of these routines have no effect in text video modes, but there are a few exceptions, and they will be noted in the descriptions of those routines.


Clearing the Screen

    The Fastgraph routine fg_erase clears the entire screen in any video

mode. In text modes, fg_erase stores a space character (ASCII 32) with a gray foreground attribute in each character cell. In graphics modes, fg_erase sets each pixel to zero. This of course causes each pixel to be displayed its background color. The fg_erase routine has no arguments.

    The fg_erase routine always sets the entire screen to the background

color. Another routine, fg_fillpage, fills the screen with the current color. In text modes, fg_fillpage stores a solid block character (ASCII 219) with the current display attribute (as defined in the most recent call to fg_setcolor or fg_setattr). In graphics modes, fg_fillpage sets each pixel to the current color (as defined in the most recent call to fg_setcolor). Like fg_erase, fg_fillpage has no arguments.


Clipping

    The suppression of graphics outside a pre-defined area is called

clipping. Many of Fastgraph's graphics-oriented routines provide clipping, either automatically or through a special version of the routine.

    Fastgraph includes two routines, fg_setclip and fg_setclipw, to define a

rectangular clipping region. The fg_setclip routine defines the clipping region in screen space, while fg_setclipw performs the same function in world space. Each routine takes four arguments: the minimum x, the maximum x, the minimum y, and the maximum y coordinate of the clipping region. The arguments are integer quantities for fg_setclip and floating point quantities for fg_setclipw. For example, the statement

                           fg_setclip(0,159,0,99);

would define the upper left quadrant of the screen as the clipping region in a 320x200 graphics mode. Fastgraph's fg_getclip routine returns the current clipping limits, as defined in the most recent call to fg_setclip.

    An implicit clipping region equal to the entire screen is defined as part

of the fg_setmode routine's initializations. Clipping is not supported for text modes. �

                                       Chapter 6:  Graphics Fundamentals   99


Points

    The Fastgraph routine fg_point provides the most basic graphics

operation -- setting a pixel to a specified color. The fg_point routine has two integer arguments. The first specifies the pixel's x coordinate, and the second its y coordinate. The pixel is drawn using the current color value, as specified in the most recent call to fg_setcolor. There is also a world space version of this routine, fg_pointw, that uses floating point arguments. Both routines display the pixel only if it falls within the current clipping region.

    Another Fastgraph routine is available for reading a pixel's color value.

The fg_getpixel routine has two integer arguments that specify the (x,y) coordinates for the pixel of interest. If the (x,y) coordinates lie outside the clipping region, fg_getpixel returns -1. There is no world space version of fg_getpixel, but you can read a pixel's color value in world space by applying the fg_xscreen and fg_yscreen functions to the world space coordinates and passing the resulting values to fg_getpixel.

    Example 6-1 uses fg_point to draw 100 random points in random colors. It

also uses fg_getpixel to insure no two points are adjacent. The program establishes a graphics video mode with fg_automode and fg_setmode. Next, it calls fg_colors to determine the maximum color value for the selected video mode, and then calls fg_getmaxx and fg_getmaxy to obtain the horizontal and vertical resolution. The main part of the program is a while loop that first generates a random pair of (x,y) screen coordinates. It then calls fg_getpixel to check the pixels at (x,y) and the eight adjacent positions. If none of these pixels are set, the program generates a random color value and draws a point in that color. After doing this 100 times, the program waits for a keystroke, restores the original video mode and screen attributes, and then returns to DOS.

                                Example 6-1.
          #include <fastgraf.h>
          #include <stdlib.h>
          void main(void);
          void main()
          {
             int area;
             int color, colors;
             int left;
             int new_mode, old_mode;
             int x_range, y_range;
             int x, y;
             fg_initpm();
             old_mode = fg_getmode();
             new_mode = fg_automode();
             fg_setmode(new_mode);
             colors = fg_colors();
             x_range = fg_getmaxx() - 1;
             y_range = fg_getmaxy() - 1;
             left = 100;                                                      �

100 Fastgraph User's Guide


             while (left > 0)
             {
                x = (rand() % x_range) + 1;
                y = (rand() % y_range) + 1;
                area = fg_getpixel(x-1,y-1) + fg_getpixel(x,y-1) +
                       fg_getpixel(x+1,y-1) + fg_getpixel(x-1,y) +
                       fg_getpixel(x,y) + fg_getpixel(x+1,y) +
                       fg_getpixel(x-1,y+1) + fg_getpixel(x,y+1) +
                       fg_getpixel(x+1,y+1);
                if (area == 0)
                {
                   color = rand() % colors;
                   fg_setcolor(color);
                   fg_point(x,y);
                   left--;
                }
             }
             fg_waitkey();
             fg_setmode(old_mode);
             fg_reset();
          }


    Sometimes you may want to display a pixel using an "exclusive or"

operation (usually called XOR) to guarantee its visibility. The color of a pixel drawn in XOR mode will be c xor p, where c is the current color and p is the color of the pixel already at that position. This means the pixel's new color will be different from the background as long as the current color is not zero. The Fastgraph routine fg_pointx displays a screen space pixel in XOR mode, while fg_pointxw does the same thing in world space. Their respective parameters are the same as for fg_point and fg_pointw.


The Graphics Cursor

    Many of Fastgraph's graphics routines depend on the position of the

graphics cursor as a reference point. For example, Fastgraph includes routines to draw lines from the graphics cursor position to a specified position, and the bitmapped image display routines discussed in Chapter 10 display or retrieve an image relative to the graphics cursor position. The graphics cursor is not a cursor in the true sense; it is simply a pair of (x,y) coordinates with a special meaning. The fg_setmode routine sets the graphics cursor position to the screen space coordinates (0,0), and fg_initw sets it to the world space coordinates (0.0,0.0).

    Fastgraph includes four routines for changing the graphics cursor

position. The fg_move routine sets it to an absolute screen space position, while fg_movew sets it to an absolute world space position. The fg_moverel routine sets the graphics cursor position to a screen space position relative to its current position. The fg_moverw routine does the same in world space. Each of these routines has two arguments that specify the (x,y) coordinates of the new position. For the screen space routines, the arguments are integer �

                                      Chapter 6:  Graphics Fundamentals   101


quantities. For the world space routines, the arguments are floating point quantities.

    You can obtain the screen space coordinates of the graphics cursor

position with the fg_getxpos and fg_getypos routines. These routines have no arguments and respectively return the x and y coordinates of the graphics cursor position as the function value. To obtain the world space coordinates of the graphics cursor position, apply the fg_xworld and fg_yworld functions to the return values of fg_getxpos and fg_getypos.


Solid Lines

    Fastgraph includes eight routines for drawing solid lines. All of them

draw lines in the current color value and observe the clipping limits. The fg_draw routine draws a line from the current graphics cursor position to an absolute screen space position, while fg_draww draws a line to an absolute world space position. The fg_drawrel routine draws a line from the current graphics cursor position to a screen space position relative to it. The fg_drawrw routine does the same in world space. You can draw absolute lines in XOR mode with fg_drawx and relative XOR lines with fg_drawrelx, or with their world space counterparts fg_drawxw and fg_drawrxw. XOR lines are often used when drawing cursors (such as cross hairs) or rubberband boxes to insure they are visible against colored backgrounds. Another useful property of XOR lines is that drawing the same line twice restores what was originally beneath the line.

    Each of these routines has two arguments that specify the (x,y)

coordinates of the destination position. For the screen space routines, the arguments are integer quantities. For the world space routines, the arguments are floating point quantities. In either case the destination position becomes the new graphics cursor position. This makes it possible to draw connected lines without calling a graphics cursor movement routine between successive calls to a line drawing routine.

    Examples 6-2 and 6-3 each draw a pair of crossed lines that divide the

screen into quadrants. Example 6-2 does this using fg_move and fg_draw, while example 6-3 uses fg_moverel and fg_drawrel. Both examples draw the lines in white, the default for color 15 in all graphics video modes.

              Example 6-2.                          Example 6-3.
     #include <fastgraf.h>                 #include <fastgraf.h>
     void main(void);                      void main(void);
     void main()                           void main()
     {                                     {
        int max_x, max_y;                     int max_x, max_y;
        int mid_x, mid_y;                     int mid_x, mid_y;
        int new_mode, old_mode;               int new_mode, old_mode;
        fg_initpm();                          fg_initpm();
        old_mode = fg_getmode();              old_mode = fg_getmode();
        new_mode = fg_automode();             new_mode = fg_automode();
        fg_setmode(new_mode);                 fg_setmode(new_mode);           �

102 Fastgraph User's Guide


        max_x = fg_getmaxx();                 max_x = fg_getmaxx();
        max_y = fg_getmaxy();                 max_y = fg_getmaxy();
        mid_x = max_x / 2;                    mid_x = max_x / 2;
        mid_y = max_y / 2;                    mid_y = max_y / 2;
        fg_setcolor(15);                      fg_setcolor(15);
        fg_move(mid_x,0);                     fg_move(mid_x,0);
        fg_draw(mid_x,max_y);                 fg_drawrel(0,max_y);
        fg_move(0,mid_y);                     fg_moverel(-mid_x,-mid_y);
        fg_draw(max_x,mid_y);                 fg_drawrel(max_x,0);
        fg_waitkey();                         fg_waitkey();
        fg_setmode(old_mode);                 fg_setmode(old_mode);
        fg_reset();                           fg_reset();
     }                                     }


    Examples 6-4 and 6-5 are variations of example 6-2. Example 6-4 uses

world space rather than screen space to draw the crossed lines. Example 6-5 is the same as example 6-2 except it defines a clipping area to restrict drawing to the upper left quadrant of the screen. The clipping suppresses the right half of the horizontal line and the lower half of the vertical line.

               Example 6-4.                           Example 6-5.
  #include <fastgraf.h>                    #include <fastgraf.h>
  void main(void);                         void main(void);
  void main()                              void main()
  {                                         {
     int new_mode, old_mode;                   int max_x, max_y;
                                               int mid_x, mid_y;
     fg_initpm();                              int new_mode, old_mode;
     old_mode = fg_getmode();
     new_mode = fg_automode();                 fg_initpm();
     fg_setmode(new_mode);                     old_mode = fg_getmode();
     fg_initw();                               new_mode = fg_automode();
     fg_setworld(-10.0,10.0,-10.0,10.0);       fg_setmode(new_mode);
     fg_setcolor(15);                          max_x = fg_getmaxx();
     fg_movew(0.0,10.0);                       max_y = fg_getmaxy();
     fg_draww(0.0,-10.0);                      mid_x = max_x / 2;
     fg_movew(-10.0,0.0);                      mid_y = max_y / 2;
     fg_draww(10.0,0.0);
     fg_waitkey();                             fg_setclip(0,mid_x,0,mid_y);
     fg_setmode(old_mode);                     fg_setcolor(15);
     fg_reset();                               fg_move(mid_x,0);
  }                                            fg_draw(mid_x,max_y);
                                               fg_move(0,mid_y);
                                               fg_draw(max_x,mid_y);
                                               fg_waitkey();
                                               fg_setmode(old_mode);
                                               fg_reset();
                                            }                                 �
                                      Chapter 6:  Graphics Fundamentals   103



Dashed Lines

    Fastgraph includes four routines for drawing dashed lines. All of them

draw lines in the current color value and observe the clipping limits. The fg_dash routine draws a dashed line from the current graphics cursor position to an absolute screen space position, while fg_dashw draws a dashed line to an absolute world space position. The fg_dashrel routine draws a dashed line from the current graphics cursor position to a screen space position relative to it. The fg_dashrw routine does the same in world space.

    Each of these routines has three arguments. The first two specify the

(x,y) coordinates of the destination position. For the screen space routines, these arguments are integer quantities. For the world space routines, these arguments are floating point quantities. The third argument is a 16-bit pattern that defines the appearance of the dashed line. Bits that are set in the pattern produce the visible part of the line, while bits that are zero produce the invisible part. This pattern is repeated as necessary to draw the entire line. For example, the pattern value 3333 hex would produce a dashed line with the first two pixels off, the next two on, the next two off, and so forth. Similarly, the pattern value FFFF hex would produce a solid line.

    The destination position passed to any of the dashed line routines

becomes the new graphics cursor position. This makes it possible to draw connected dashed lines without calling a graphics cursor movement routine between successive calls to a line drawing routine.

    Example 6-6 draws a pair of crossed dashed lines that divide the screen

into quadrants. It does this using fg_move and fg_dash and draws the lines in white, the default for color 15 in all graphics video modes. The dash pattern for each line is 3333 hex, which alternates two pixels off and on.

                                Example 6-6.
                       #include <fastgraf.h>
                       void main(void);
                       void main()
                       {
                          int max_x, max_y;
                          int mid_x, mid_y;
                          int new_mode, old_mode;
                          fg_initpm();
                          old_mode = fg_getmode();
                          new_mode = fg_automode();
                          fg_setmode(new_mode);
                          max_x = fg_getmaxx();
                          max_y = fg_getmaxy();
                          mid_x = max_x / 2;
                          mid_y = max_y / 2;
                          fg_setcolor(15);                                    �

104 Fastgraph User's Guide


                          fg_move(mid_x,0);
                          fg_dash(mid_x,max_y,0x3333);
                          fg_move(0,mid_y);
                          fg_dash(max_x,mid_y,0x3333);
                          fg_waitkey();
                          fg_setmode(old_mode);
                          fg_reset();
                       }


Polygons

    Fastgraph includes routines for drawing filled and unfilled polygons, as

well as a routine for determining if a given point is inside a convex polygon. All the polygon routines observe the clipping limits.

    The fg_polygon routine draws an unfilled polygon in screen space. It

requires an array of integer x coordinates as its first argument, and an array of integer y coordinates as its second argument. Each (x,y) coordinate pair from the two arrays is treated as a polygon vertex. In other words, the x coordinate of the first polygon vertex is the first element of the x coordinate array, and the y coordinate of the first vertex is the first element of the y coordinate array. Similarly, the second elements of each array define the second vertex, and so forth. The third argument for fg_polygon is an integer quantity that specifies the number of elements in the two coordinate arrays (that is, the number of polygon vertices).

    Another routine, fg_polygonw, draws an unfilled polygon in world space.

The fg_polygonw routine is the same as the fg_polygon routine, except its x and y coordinate arrays must contain floating point values instead of integers.

    Polygon drawing begins at the first vertex specified in the coordinate

arrays. The polygon routines then draw a solid line to the second vertex, then to the third vertex, and continue in this manner through the last vertex. If necessary, they then close the polygon by drawing a line connecting the last vertex and the first vertex. Example 6-7 illustrates unfilled polygon drawing using fg_polygon in the EGA monochrome or enhanced modes (modes 15 and 16). The program exits if neither of these video modes are available.

                                Example 6-7.
            #include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
            void main(void);
            #define VERTICES 10
            int x[] = {200,300,400,400,300,240,160,160,200,210};
            int y[] = {100, 80,100,220,320,320,240,200,160,150};
            void main()
            {                                                                 �
                                      Chapter 6:  Graphics Fundamentals   105


               int old_mode;
               fg_initpm();
               old_mode = fg_getmode();
               if (fg_testmode(16,1))
                  fg_setmode(16);
               else if (fg_testmode(15,1))
                  fg_setmode(15);
               else {
                  printf("This program requires a 640 x 350 ");
                  printf("EGA graphics mode.\n");
                  exit(1);
                  }
               fg_setcolor(1);
               fg_polygon(x,y,VERTICES);
               fg_waitkey();
               fg_setmode(old_mode);
               fg_reset();
            }


    As shown in this example, fg_polygon expects the x and y components

defining the polygon vertices to be in separate arrays. Another routine, fg_polyline, draws an unfilled polygon from polygon vertices in one integer array. With fg_polyline, the first array element is the x component of the first vertex, the second element is the y component of the first vertex, the third element is the x component of the second vertex, and so forth. The first fg_polyline argument is the vertex coordinate array of alternating x and y components, and the second argument specifies the number of vertices. In other respects, fg_polyline is identical to fg_polygon.

    An additional feature available with fg_polyline but not fg_polygon is

the ability to specify vertex offsets. The fg_polyoff routine's two integer arguments respectively define offset values that are added to each fg_polyline vertex. This makes it possible to define polygon vertices as relative values, that when combined with the offsets, determine the polygon's absolute position.

    Perhaps the most important polygon display routine is fg_polyfill, which

displays a filled convex polygon in screen space (the polygon is filled with pixels of the current color). Its first argument is a vertex array in the same format used by fg_polyline. The next argument is a work array used internally. The size in bytes of the work array must be at least four times the polygon height. The final argument specifies the number of polygon vertices.

    Example 6-8 illustrates the use of fg_polyline, fg_polyoff, and

fg_polyfill. The program first draws an unfilled polygon, centered within the left half of the screen. It then draws a filled version of the same polygon, centered within the right half of the screen. In each case, the centering is accomplished by passing appropriate values to fg_polyoff. After waiting for a keystroke, the program establishes a clipping region in the lower right corner and redraws the filled polygon at the same position but in a different color. This of course results in only a portion of the filled polygon being drawn. Like example 6-7, this example requires a 640x350 graphics mode. � 106 Fastgraph User's Guide


                                Example 6-8.
          #include <fastgraf.h>
          #include <stdio.h>
          #include <stdlib.h>
          void main(void);
          #define VERTICES 10
          int xy[] = {200,100, 300, 80, 400,100, 400,220, 300,320,
                      240,320, 160,240, 160,200, 200,160, 210,150};
          int work_array[700];
          void main()
          {
             int old_mode;
             fg_initpm();
             old_mode = fg_getmode();
             if (fg_testmode(16,1))
                fg_setmode(16);
             else if (fg_testmode(15,1))
                fg_setmode(15);
             else {
                printf("This program requires a 640 x 350 ");
                printf("EGA graphics mode.\n");
                exit(1);
                }
             fg_setcolor(1);
             fg_polyoff(-120,-25);
             fg_polyline(xy,VERTICES);
             fg_polyoff(200,-25);
             fg_polyfill(xy,work_array,VERTICES);
             fg_waitkey();
             fg_setcolor(2);
             fg_setclip(480,639,175,349);
             fg_polyfill(xy,work_array,VERTICES);
             fg_waitkey();
             fg_setmode(old_mode);
             fg_reset();
          }


    The fg_polyfill routine fills convex polygons. From Fastgraph's

perspective, a polygon is convex if any horizontal line drawn through the polygon crosses the left edge exactly once and the right edge exactly once (excluding horizontal and zero-length edge segments). Note that this definition includes shapes that are not convex in the traditional sense. In addition, any non-convex polygon can be decomposed into two or more convex polygons. All triangles (that is, three-vertex polygons) are by their nature convex. �

                                      Chapter 6:  Graphics Fundamentals   107


    The filled convex polygon is a basic tool of three-dimensional computer

graphics. A common practice is to build an image or object from several adjacent or connecting polygons. Such polygons typically overlap at one or more edges. For instance, the coordinates defining the right edge of one polygon may also define the left edge of another polygon immediately to its right. For an overall image to appear correct, its component polygons must fit together correctly. By default, fg_polyfill applies the following rules to handle overlapping polygon edges:

          *   Points located exactly on non-horizontal edges
              are drawn only if the polygon's interior is
              directly to the right.
          *   Points located exactly on horizontal edges are
              drawn only if the polygon's interior is directly
              below them.
          *   A vertex is drawn only if all lines ending at
              that point meet the above two conditions.

These three rules insure that no pixel is drawn more than once when filling adjacent polygons. However, this behavior may not be suitable for displaying polygons that are not adjacent, because some or all of the pixels on the polygon's right and bottom edges will be excluded. If this is an issue, you can use fg_polyedge to force fg_polyfill to include all edge pixels. The fg_polyedge routine expects a single integer parameter. If it is zero, fg_polyfill will include all edge pixels when drawing convex polygons. Passing any other value to fg_polyedge restores the default behavior of excluding pixels that meet the criteria described above.

    The final Fastgraph routine relating to polygons is fg_inside, which

checks if a specified point lies inside a convex polygon. Its first argument is a vertex array in the same format used by fg_polyline and fg_polyfill. The second argument is the number of vertices in the polygon, while the last two arguments specify the screen space x and y coordinates of the point being tested. The fg_inside routine returns 1 if the point lies inside the polygon and 0 if not. If the vertex array does not define a convex polygon, the return value is undefined. The fg_polyoff offsets are applied to the fg_inside vertex array, but not to the test point.


Circles and Ellipses

    Fastgraph includes routines for drawing filled and unfilled circles and

ellipses. Both screen space and world space versions of these routines are available, and all of them observe the clipping limits.

    The fg_circle routine draws an unfilled circle in screen space, centered

at the graphics cursor position, using the current color. Its only argument specifies the circle's radius in horizontal screen space units. Another routine, fg_circlew, draws an unfilled circle where the radius is measured in horizontal world space units. The analogous routines for drawing filled circles are fg_circlef and fg_circlefw. All four circle drawing routines leave the graphics cursor position unchanged. � 108 Fastgraph User's Guide


    The fg_ellipse routine draws an unfilled ellipse in screen space,

centered at the graphics cursor position, using the current color. The routine requires two arguments that respectively specify the length of its horizontal and vertical semi-axes. In other words, the first argument is the absolute distance from the center of the ellipse to its horizontal extremity, and the second argument is the absolute distance from the center to the vertical extremity. Another routine, fg_ellipsew, draws an unfilled ellipse in world space. The analogous routines for drawing filled ellipses are fg_ellipsef and fg_ellipsfw. All four ellipse drawing routines leave the graphics cursor position unchanged.

    Example 6-9 illustrates the use of the fg_circlew and fg_ellipsew

routines. The program first uses fg_automode to propose a graphics video mode and then uses fg_setmode to select that video mode. It then makes color 15 the current color, which by default is white in all color graphics modes and "on" in the monochrome graphics modes. Next, it establishes a 200x200 world space coordinate system. The program then uses fg_ellipsew to draw an ellipse and fg_circlew to draw a circle, both centered at the middle of the screen (which is the origin of our world space coordinate system). The circle has a radius of 1/16 the width of the screen (12.5 horizontal world space units), and the ellipse is horizontally inscribed within the circle.

    Example 6-10 illustrates the use of the fg_circle and fg_ellipse

routines. It is functionally identical to example 6-9, but it uses screen space rather than world space coordinates to draw the circle and ellipse. Note the arguments to fg_circle and fg_ellipse are dependent on the maximum x and y coordinates of the selected video mode. If we didn't compute these arguments in this manner, the actual size of the circle and ellipse would be proportional to the pixel resolution of the video mode. No such dependency exists when using world space, but we pay a price for this feature in slightly slower execution speed.

               Example 6-9.                        Example 6-10.
      #include <fastgraf.h>               #include <fastgraf.h>
      void main(void);                    void main(void);
      void main()                         void main()
      {                                   {
         int old_mode;                       int mid_x, mid_y;
                                             int old_mode;
         fg_initpm();                        int x, y;
         old_mode = fg_getmode();
         fg_setmode(fg_automode());          fg_initpm();
         fg_setcolor(15);                    old_mode = fg_getmode();
                                             fg_setmode(fg_automode());
         fg_initw();                         fg_setcolor(15);
         fg_setworld(-100.0,100.0,
                     -100.0,100.0);          mid_x = fg_getmaxx() / 2;
                                             mid_y = fg_getmaxy() / 2;
         fg_movew(0.0,0.0);                  x = mid_x / 8;
         fg_ellipsew(12.5,12.5);             y = mid_y / 8;
         fg_circlew(12.5);
         fg_waitkey();                       fg_move(mid_x,mid_y);
                                             fg_ellipse(x,y);
         fg_setmode(old_mode);               fg_circle(x);                    �
                                      Chapter 6:  Graphics Fundamentals   109


         fg_reset();                         fg_waitkey();
      }
                                             fg_setmode(old_mode);
                                             fg_reset();
                                          }


Solid Rectangles

    Fastgraph includes four routines for drawing solid rectangles, two for

screen space and two for world space, with and without clipping. None of these routines affect the graphics cursor position.

    The fg_rect routine draws a solid rectangle in screen space, without

regard to the clipping limits, using the current color. It requires four integer arguments that respectively define the minimum x, maximum x, minimum y, and maximum y screen space coordinates of the rectangle. The minimum coordinates must be less than or equal to the maximum coordinates, or else the results are unpredictable. The fg_clprect routine is identical in all respects to fg_rect, except it observes the clipping limits.

    The world space versions of the solid rectangle drawing routines are

fg_rectw and fg_clprectw. Like fg_rect and fg_clprect, they require four arguments that define the extremes of the rectangle, but the arguments are floating point world space coordinates.

    You also can use fg_rect in text modes. When used in a text mode, fg_rect

expects its four arguments to be expressed in character space (that is, rows and columns) rather than screen space. This means the four arguments respectively specify the minimum column, maximum column, minimum row, and maximum row of the rectangle. Fastgraph constructs the rectangle by storing the solid block character (ASCII decimal value 219) in each character cell comprising the rectangle. The rectangle is drawn using the current character attribute, but because the solid block character occupies the entire character cell, the background component of the attribute is essentially meaningless.

    Example 6-11 demonstrates the use of fg_rect by drawing 200 random-size

rectangles in random colors. The program first uses fg_automode to propose a graphics video mode and then uses the fg_setmode routine to select that video mode. Next, it determines the horizontal and vertical screen resolution for the selected video mode, using fg_getmaxx and fg_getmaxy. The main part of the program is a for loop that generates a random rectangle in each iteration. Inside the loop, the C library function rand is used to generate the extremes of the rectangle. If necessary, the program then exchanges the coordinates to make the minimum coordinates less than or equal to the maximum coordinates. Finally, it again uses rand to generate a random color number between 0 and 15, and then draws the rectangle in that color. After drawing all 200 rectangles, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 6-11.
            #include <fastgraf.h>
            void main(void);                                                  �

110 Fastgraph User's Guide


            #define RECTANGLES 200
            #define SWAP(a,b,temp) { temp = a; a = b; b = temp; }
            void main()
            {
               int i;
               int minx, maxx, miny, maxy;
               int old_mode;
               int temp;
               int xres, yres;
               fg_initpm();
               old_mode = fg_getmode();
               fg_setmode(fg_automode());
               xres = fg_getmaxx() + 1;
               yres = fg_getmaxy() + 1;
               for (i = 0; i < RECTANGLES; i++) {
                  minx = rand() % xres;
                  maxx = rand() % xres;
                  miny = rand() % yres;
                  maxy = rand() % yres;
                  if (minx > maxx)
                     SWAP(minx,maxx,temp);
                  if (miny > maxy)
                     SWAP(miny,maxy,temp);
                  fg_setcolor(rand()%16);
                  fg_rect(minx,maxx,miny,maxy);
                  }
               fg_setmode(old_mode);
               fg_reset();
            }


Unfilled Rectangles

    Fastgraph includes four routines for drawing unfilled rectangles. The

fg_box routine draws an unfilled rectangle in screen space, with regard to the clipping limits, using the current color. The arguments to fg_box are the same as those for fg_rect. The depth of the rectangle's edges is one pixel by default, but you can change the depth by calling fg_boxdepth. The fg_boxdepth routine expects two arguments. The first argument is the width of the rectangle's left and right sides, while the second is the height of its top and bottom sides. Once you call fg_boxdepth, fg_box draws all unfilled rectangles using the depth values specified in the most recent call to fg_boxdepth. The fg_getxbox and fg_getybox functions respectively return the horizontal and vertical box depth settings, as defined in the most recent call to fg_boxdepth. Unlike fg_rect, fg_box has no effect in text video modes. The analogous world space routine is fg_boxw.

    Example 6-12 is the same as example 6-11, but it draws unfilled instead

of solid rectangles. The program uses fg_box to draw the each rectangle and fg_boxdepth to define the rectangle depth at three pixels in each direction. �

                                      Chapter 6:  Graphics Fundamentals   111


Note that you don't need to call fg_boxdepth for each rectangle if you want all of them to have the same depth.

                                Example 6-12.
            #include <fastgraf.h>
            void main(void);
            #define RECTANGLES 200
            #define SWAP(a,b,temp) { temp = a; a = b; b = temp; }
            void main()
            {
               int i;
               int minx, maxx, miny, maxy;
               int old_mode;
               int temp;
               int xres, yres;
               fg_initpm();
               old_mode = fg_getmode();
               fg_setmode(fg_automode());
               fg_boxdepth(3,3);
               xres = fg_getmaxx() + 1;
               yres = fg_getmaxy() + 1;
               for (i = 0; i < RECTANGLES; i++) {
                  minx = rand() % xres;
                  maxx = rand() % xres;
                  miny = rand() % yres;
                  maxy = rand() % yres;
                  if (minx > maxx)
                     SWAP(minx,maxx,temp);
                  if (miny > maxy)
                     SWAP(miny,maxy,temp);
                  fg_setcolor(rand()%16);
                  fg_box(minx,maxx,miny,maxy);
                  }
               fg_setmode(old_mode);
               fg_reset();
            }


    The fg_boxx and fg_boxxw routines are screen space and world space

"exclusive or" versions of the box drawing routines. They simplify displaying rubberband boxes (hollow rectangles that move in response to keystrokes or mouse movement) because drawing an object in XOR mode makes it appear, but drawing it again in the same position and in the same color restores what was under the object originally. Given this useful property, here is an outline of what's necessary to draw a rubberband box:

        1.    Draw the box in its initial position with
              fg_boxx or fg_boxxw.                                            �

112 Fastgraph User's Guide


        2.    Wait for a user response that signifies box
              movement.
        3.    Use fg_boxx or fg_boxxw to redraw the box in the
              same position as in step 1. This restores what
              was there originally.
        4.    Draw the box in its new position with fg_boxx or
              fg_boxxw.
        5.    Repeat steps 2, 3, and 4 until the box is no
              longer needed.
    Example 6-13 shows a simple use of fg_boxx in the 320x200 MCGA/VGA 256-

color mode (mode 19). The program fills the left and right halves of the screen with different colors and then displays an XOR box that overlaps each half. Even though the box is drawn in the same color as the right half, it is still visible because drawing something in an XOR mode (except in color 0) guarantees that it will be visible against its background. After a keystroke, the program redraws the same box, which of course restores what was there in the first place.

                                Example 6-13.
                         #include <fastgraf.h>
                         void main(void);
                         void main()
                         {
                            int old_mode;
                            fg_initpm();
                            old_mode = fg_getmode();
                            fg_setmode(19);
                            fg_setcolor(9);
                            fg_rect(0,159,0,199);
                            fg_setcolor(15);
                            fg_rect(160,319,0,199);
                            fg_waitkey();
                            fg_boxx(80,239,50,149);
                            fg_waitkey();
                            fg_boxx(80,239,50,149);
                            fg_waitkey();
                            fg_setmode(old_mode);
                            fg_reset();
                         }


Dithered Rectangles

    The process of alternating different color pixels across a region of the

display area is called dithering. This technique is especially useful in the graphics modes with few colors, such as CGA and Hercules modes, because you can simulate additional colors through effective uses of dithering. Fastgraph includes two routines for drawing dithered rectangles, one for screen space �

                                      Chapter 6:  Graphics Fundamentals   113


and one for world space. Neither routine observes the clipping limits, nor do they affect the graphics cursor position.

    The fg_drect routine draws a dithered rectangle in screen space. Like the

fg_rect routine, fg_drect requires four integer arguments that respectively define the minimum x, maximum x, minimum y, and maximum y screen space coordinates of the rectangle. The minimum coordinates must be less than or equal to the maximum coordinates, or else the results are unpredictable. However, fg_drect also requires a fifth argument that defines the dithering matrix, which in turn determines the pixel pattern used to build the dithered rectangle. The size and format of the dithering matrix are dependent on the video mode.

    The world space version of the dithered rectangle drawing routine is

fg_drectw. Like fg_drect, it requires four arguments that define the extremes of the rectangle, and a fifth argument that defines the dithering matrix.

    As mentioned earlier, the size and format of the dithering matrix are

dependent on the video mode. The dithering matrix is a four-byte array in all video modes except the 256 color graphics modes (modes 19 through 27), where it is an eight-byte array. This array contains a pixel pattern that fg_drect or fg_drectw replicates across the rectangle's area. The structure of the dithering matrix closely mimics the structure of video memory in each graphics mode.

    The remainder of this section will present some simple mode-specific

examples to illustrate the structure of the dithering matrix in the different graphics modes. Suppose we would like to produce a "checkerboard" of light blue and white pixels. That is, in a given row of a rectangle, consecutive pixels will alternate between these two colors. Additionally, the pattern for adjacent rows will be shifted so there will always be a white pixel above and below a light blue pixel, and vice versa. Hence this pixel pattern would look something like

                                   B W B W
                                   W B W B
                                   B W B W
                                   W B W B

where each B represents a light blue pixel, and each W represents a white pixel. The following examples describe the dithering matrix that could be used to produce such a pixel pattern in each graphics mode.

CGA Four-Color Graphics Modes

    The CGA four-color graphics modes (modes 4 and 5) use a four-byte

dithering matrix that Fastgraph treats as a four-row by one-column array. Since each pixel in these modes requires two bits of video memory, each byte of the dithering matrix holds four pixels. Thus, the pixel representation of the dithering matrix would appear as shown on the left; its translation to numeric values appears on the right.


                   [3]   B W B W       [3]   01 11 01 11
                   [2]   W B W B       [2]   11 01 11 01                      �

114 Fastgraph User's Guide


                   [1]   B W B W       [1]   01 11 01 11
                   [0]   W B W B       [0]   11 01 11 01


Because these modes do not offer a light blue color, we've used light cyan (color value 1 in palette 1) to approximate light blue. The B pixels thus translate to color value 1, or 01 binary. White is available as color value 3 in palette 1, so the W pixels translate to color value 3, or 11 binary. The hexadecimal equivalent of the binary value 11011101 (for array elements [0] and [2]) is DD, and the hexadecimal equivalent of the binary value 01110111 (for array elements [1] and [3]) is 77. As shown in example 6-12, these are precisely the values assigned to the elements of the dithering matrix.

    Example 6-14 uses mode 4 to display a 50-pixel by 50-pixel dithered

rectangle in the upper left corner of the screen. The dithering matrix represents the blue and white checkerboard pattern discussed in the preceding paragraph.

                                Example 6-14.
                      #include <fastgraf.h>
                      void main(void);
                      void main()
                      {
                         char matrix[4];
                         int old_mode;
                         fg_initpm();
                         old_mode = fg_getmode();
                         fg_setmode(4);
                         matrix[0] = matrix[2] = 0xDD;
                         matrix[1] = matrix[3] = 0x77;
                         fg_drect(0,49,0,49,matrix);
                         fg_waitkey();
                         fg_setmode(old_mode);
                         fg_reset();
                      }


CGA Two-Color Graphics Mode

    The CGA two-color graphics mode (mode 6) uses a four-byte dithering

matrix that Fastgraph treats as a four-row by one-column array, as in the other four-color CGA modes. However, each pixel in this mode only requires one bit of video memory, so each byte of the dithering matrix holds eight pixels. Thus, the pixel representation of the dithering matrix would appear as shown on the left; its translation to numeric values appears on the right.


             [3]   B W B W B W B W       [3]   0 1 0 1 0 1 0 1                �
                                      Chapter 6:  Graphics Fundamentals   115


             [2]   W B W B W B W B       [2]   1 0 1 0 1 0 1 0
             [1]   B W B W B W B W       [1]   0 1 0 1 0 1 0 1
             [0]   W B W B W B W B       [0]   1 0 1 0 1 0 1 0


Mode 6 obviously does not offer a light blue color, so we've used black (color value 0) in its place. The B pixels thus translate to color value 0. White is available as color value 1, so the W pixels translate to color value 1. The hexadecimal equivalent of the binary value 10101010 (for array elements [0] and [2]) is AA, and the hexadecimal equivalent of the binary value 01010101 (for array elements [1] and [3]) is 55. Thus, to make example 6-14 run in mode 6, we only need to change the fg_setmode argument from 4 to 6 and change the dithering matrix values as shown here:


                        matrix[0] = matrix[2] = 0xAA;
                        matrix[1] = matrix[3] = 0x55;


Tandy/PCjr 16-Color Graphics Mode

    The Tandy/PCjr 16-color graphics mode (mode 9) also uses a four-byte

dithering matrix that Fastgraph treats as a four-row by one-column array. Each pixel in this mode requires four bits of video memory, so each byte of the dithering matrix only holds two pixels. Thus, the pixel representation of the dithering matrix would appear as shown on the left; its translation to numeric values appears on the right.


                      [3]   B W       [3]   1001 1111
                      [2]   W B       [2]   1111 1001
                      [1]   B W       [1]   1001 1111
                      [0]   W B       [0]   1111 1001


The B pixels translate to color value 9 (light blue), or 1001 binary, and the W pixels translate to color value 15 (white), or 1111 binary. The hexadecimal equivalent of the binary value 11111001 (for array elements [0] and [2]) is F9, and the hexadecimal equivalent of the binary value 10011111 (for array elements [1] and [3]) is 9F. Thus, to make example 6-14 run in mode 9, we only need to change the fg_setmode argument from 4 to 9 and change the dithering matrix values as shown here:


                        matrix[0] = matrix[2] = 0xF9;
                        matrix[1] = matrix[3] = 0x9F;                         �

116 Fastgraph User's Guide


Hercules Graphics Mode

    The size and format of the dithering matrix in the Hercules graphics mode

(mode 11) are the same as in the CGA two-color mode (mode 6).

Hercules Low-Resolution Graphics Mode

    The size and format of the dithering matrix in the Hercules low-

resolution graphics mode (mode 12) are the same as in the CGA four-color modes (modes 4 and 5). As far as our checkerboard example goes, we'll use black (color value 0) in place of light blue, and bold (color value 3) instead of white. Thus, the B pixels translate to 00 binary, while the W pixels translate to 11 binary. The hexadecimal equivalent of the binary value 11001100 (for array elements [0] and [2]) is CC, and the hexadecimal equivalent of the binary value 00110011 (for array elements [1] and [3]) is 33. Thus, to make example 6-14 run in mode 12, we only need to change the fg_setmode argument from 4 to 12 and change the dithering matrix values as shown here:


                        matrix[0] = matrix[2] = 0xCC;
                        matrix[1] = matrix[3] = 0x33;


EGA/VGA/SVGA 16-Color Graphics Modes

    The EGA/VGA/SVGA 16-color graphics modes (modes 13 through 18, 28, and

29) use a four-byte dithering matrix that Fastgraph treats as a four-row by one-column array. Unlike the other graphics modes, which allow you to store pixels of several colors in the dithering matrix, these modes treat the dithering matrix as a bitmap for a specific color. Since each color in the dither pattern must be stored in a separate bitmap (that is, in a separate dithering matrix), you must call fg_drect once for each color. Furthermore, you must use fg_setcolor before each call to fg_drect to define the color used with the dithering matrix.

    In all EGA/VGA/SVGA graphics modes, each byte of the dithering matrix is

a bitmap that represents eight pixels. Using our familiar checkerboard example, the pixel representation of the dithering matrix would appear as shown here:


                           [3]   B W B W B W B W
                           [2]   W B W B W B W B
                           [1]   B W B W B W B W
                           [0]   W B W B W B W B


Translating this pattern to numeric values is simple. Just construct one dithering matrix for each color in the pattern (there are two colors in this example), where pixels of the current color translate to 1, and other pixels translate to 0. Following our example, the translation for the B pixels appears below on the left, while the translation for the W pixels appears on the right. �

                                      Chapter 6:  Graphics Fundamentals   117



             [3]   1 0 1 0 1 0 1 0       [3]   0 1 0 1 0 1 0 1
             [2]   0 1 0 1 0 1 0 1       [2]   1 0 1 0 1 0 1 0
             [1]   1 0 1 0 1 0 1 0       [1]   0 1 0 1 0 1 0 1
             [0]   0 1 0 1 0 1 0 1       [0]   1 0 1 0 1 0 1 0


The hexadecimal equivalent of the binary value 01010101 is 55, and the hexadecimal equivalent of the binary value 10101010 is AA. As shown in example 6-15, these are precisely the values assigned to the elements of the dithering matrices.

    Example 6-15 uses mode 13 to display our light blue and white

checkerboard pattern. Note you must call fg_drect twice -- once for the light blue pixels (color value 9), and again for the white pixels (color value 15). Note also how fg_setcolor is used before each call to fg_drect to define the color of the pixels fg_drect will display.

                                Example 6-15.
                      #include <fastgraf.h>
                      void main(void);
                      void main()
                      {
                         char matrix[4];
                         int old_mode;
                         fg_initpm();
                         old_mode = fg_getmode();
                         fg_setmode(13);
                         matrix[0] = matrix[2] = 0x55;
                         matrix[1] = matrix[3] = 0xAA;
                         fg_setcolor(9);
                         fg_drect(0,49,0,49,matrix);
                         matrix[0] = matrix[2] = 0xAA;
                         matrix[1] = matrix[3] = 0x55;
                         fg_setcolor(15);
                         fg_drect(0,49,0,49,matrix);
                         fg_waitkey();
                         fg_setmode(old_mode);
                         fg_reset();
                      }                                                       �

118 Fastgraph User's Guide


256-Color Graphics Modes

    The 256-color graphics modes (modes 19 through 27) use an eight-byte

dithering matrix that Fastgraph treats as a four-row by two-column array. Each pixel in these modes requires eight bits of video memory, so each byte of the dithering matrix only holds a single pixel. We therefore need the two column dithering matrix to produce a meaningful dither pattern. The pixel representation of the dithering matrix would appear as shown on the left; its translation to numeric values appears on the right.


                    [6]   B   W   [7]     [6]    9   15   [7]
                    [4]   W   B   [5]     [4]   15    9   [5]
                    [2]   B   W   [3]     [2]    9   15   [3]
                    [0]   W   B   [1]     [0]   15    9   [1]


The B pixels translate to color value 9 (light blue), and the W pixels translate to color value 15 (white). Example 6-16 uses mode 19 to draw our light blue and white checkerboard pattern.

                                Example 6-16.
           #include <fastgraf.h>
           void main(void);
           void main()
           {
              char matrix[8];
              int old_mode;
              fg_initpm();
              old_mode = fg_getmode();
              fg_setmode(19);
              matrix[0] = matrix[3] = matrix[4] = matrix[7] = 15;
              matrix[1] = matrix[2] = matrix[5] = matrix[6] =  9;
              fg_drect(0,49,0,49,matrix);
              fg_waitkey();
              fg_setmode(old_mode);
              fg_reset();
           }


Closing Remarks

    There are two other important items pertaining to fg_drect and fg_drectw.

These items apply regardless of which graphics video mode is being used.

    First, the dithering matrix may not contain virtual color values. That

is, the pixel color values stored in the dithering matrix must be between 0 and the maximum color value for the current video mode. If any color value is �

                                      Chapter 6:  Graphics Fundamentals   119


redefined using fg_defcolor, Fastgraph always ignores the redefinition and instead uses the actual color value. Note this does not apply to palette registers or video DAC registers, because in these cases we're redefining the color associated with a color value and not the color value itself.

    Second, Fastgraph aligns the dithering matrix to specific pixel rows.

Fastgraph draws the dithered rectangle starting with the pixel row specified by the rectangle's lower limit (the maximum y coordinate for fg_drect, or the minimum y coordinate for fg_drectw) and proceeds upward until reaching the rectangle's upper limit. In all cases the dithering matrix used by fg_drect and fg_drectw contains four rows. If we let r represent the pixel row corresponding to the rectangle's lower limit, then the first row used in the dithering matrix is r modulo 4 (assuming the dithering matrix rows are numbered 0 to 3). This alignment enables you to use the same dithering matrix in multiple calls to fg_drect and fg_drectw for building an object of adjacent dithered rectangles (for example, an L-shaped area) and still have the dither pattern match where the rectangles intersect.


Region Fill

    Fastgraph includes routines for filling arbitrary regions. The fg_flood

and fg_paint routines fill a region with the current color value by specifying a screen space point in the region's interior. The fg_floodw and fg_paintw routine also fill a region, but they require the interior point to be expressed in world space. All region fill routines have two arguments that specify the (x,y) coordinates of the interior point. For fg_flood and fg_paint, the arguments are integer quantities. For fg_floodw and fg_paintw, they are floating point quantities. None of them change the graphics cursor position. The difference between the "flood" and "paint" versions of these routines is simple: fg_flood and fg_floodw will not extend the region fill beyond the clipping limits, while fg_paint and fg_paintw ignore the clipping limits. As a result, fg_paint and fg_paintw are significantly faster.

    The region being filled must be a closed polygon whose boundary color is

different from that of the specified interior point. The region may contain holes (interior areas that will not be filled). Fastgraph fills the region by changing every interior pixel whose color is the same as the specified interior point, to the current color. If the interior point is already the current color, the region fill routines do nothing. It is important to note fg_paint and fg_paintw do not treat the screen edges as polygon boundaries. Filling an open polygon will cause these routines to behave unpredictably. This is not the case with fg_flood and fg_floodw as long as the clipping limits are not beyond the screen edges.

    Example 6-17 illustrates a simple use of fg_paint in a 320x200 graphics

mode. The program uses fg_bestmode to select an available video mode (if no 320x200 graphics mode is available, the program exits). After establishing the selected video mode, the program uses fg_move and fg_drawrel to draw a hollow rectangle in color 10 and a hollow diamond in color 9. The diamond is drawn in the middle of the rectangle, thus making it a hole with respect to the rectangle. The program leaves these shapes on the screen until a key is pressed. It then calls fg_paint to fill that part of the rectangle outside the diamond with color 10. After waiting for another keystroke, the program again uses fg_paint to fill the interior of the diamond with color 15. Finally, the � 120 Fastgraph User's Guide


program waits for another keystroke, restores the original video mode and screen attributes, and returns to DOS.

                                Example 6-17.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             void main()
             {
                int old_mode, new_mode;
                fg_initpm();
                new_mode = fg_bestmode(320,200,1);
                if (new_mode < 0) {
                   printf("This program requires a 320 x 200 ");
                   printf("graphics mode.\n");
                   exit(1);
                   }
                old_mode = fg_getmode();
                fg_setmode(new_mode);
                fg_setcolor(10);
                fg_move(100,50);
                fg_drawrel(120,0);
                fg_drawrel(0,100);
                fg_drawrel(-120,0);
                fg_drawrel(0,-100);
                fg_setcolor(9);
                fg_move(160,80);
                fg_drawrel(30,20);
                fg_drawrel(-30,20);
                fg_drawrel(-30,-20);
                fg_drawrel(30,-20);
                fg_waitkey();
                fg_setcolor(10);
                fg_paint(160,70);
                fg_waitkey();
                fg_setcolor(15);
                fg_paint(160,100);
                fg_waitkey();
                fg_setmode(old_mode);
                fg_reset();
             }                                                                �
                                      Chapter 6:  Graphics Fundamentals   121


Summary of Fundamental Graphics Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_BOX draws an unfilled rectangle in screen space, with respect to the

clipping region. The width of the rectangle's edges is one pixel unless changed with the fg_boxdepth routine.

    FG_BOXDEPTH defines the depth of rectangles drawn with the box display

routines. The fg_setmode routine initializes the box depth to one pixel.

    FG_BOXW draws an unfilled rectangle in world space, with respect to the

clipping region. The width of the rectangle's edges is one pixel unless changed with the fg_boxdepth routine.

    FG_BOXX draws an unfilled rectangle in screen space, with respect to the

clipping region, in "exclusive or" mode. The width of the rectangle's edges is one pixel unless changed with the fg_boxdepth routine.

    FG_BOXXW draws an unfilled rectangle in world space, with respect to the

clipping region, in "exclusive or" mode. The width of the rectangle's edges is one pixel unless changed with the fg_boxdepth routine.

    FG_CIRCLE draws an unfilled circle in screen space. The circle is

centered at the graphics cursor position.

    FG_CIRCLEF draws a filled circle in screen space. The circle is centered

at the graphics cursor position.

    FG_CIRCLEFW draws a filled circle in world space. The circle is centered

at the graphics cursor position.

    FG_CIRCLEW draws an unfilled circle in world space. The circle is

centered at the graphics cursor position.

    FG_CLPRECT draws a solid (filled) rectangle in screen space, with respect

to the clipping region.

    FG_CLPRECTW draws a solid (filled) rectangle in world space, with respect

to the clipping region.

    FG_DASH draws a dashed line from the graphics cursor position to an

absolute screen space position. It also makes the destination position the new graphics cursor position.

    FG_DASHREL draws a dashed line from the graphics cursor position to a

screen space position relative to it. It also makes the destination position the new graphics cursor position.

    FG_DASHRW draws a dashed line from the graphics cursor position to a

world space position relative to it. It also makes the destination position the new graphics cursor position. � 122 Fastgraph User's Guide


    FG_DASHW draws a dashed line from the graphics cursor position to an

absolute world space position. It also makes the destination position the new graphics cursor position.

    FG_DRAW draws a solid line from the graphics cursor position to an

absolute screen space position. It also makes the destination position the new graphics cursor position.

    FG_DRAWREL draws a solid line from the graphics cursor position to a

screen space position relative to it. It also makes the destination position the new graphics cursor position.

    FG_DRAWRELX draws a solid line in "exclusive or" mode from the graphics

cursor position to a screen space position relative to it. It also makes the destination position the new graphics cursor position.

    FG_DRAWRW draws a solid line from the graphics cursor position to a world

space position relative to it. It also makes the destination position the new graphics cursor position.

    FG_DRAWRXW draws a solid line in "exclusive or" mode from the graphics

cursor position to a world space position relative to it. It also makes the destination position the new graphics cursor position.

    FG_DRAWW draws a solid line from the graphics cursor position to an

absolute world space position. It also makes the destination position the new graphics cursor position.

    FG_DRAWX draws a solid line in "exclusive or" mode from the graphics

cursor position to an absolute screen space position. It also makes the destination position the new graphics cursor position.

    FG_DRAWXW draws a solid line in "exclusive or" mode from the graphics

cursor position to an absolute world space position. It also makes the destination position the new graphics cursor position.

    FG_DRECT draws a dithered rectangle in screen space, without regard to

the clipping region. The rectangle's dither pattern is defined through a dithering matrix whose format is dependent on the video mode being used.

    FG_DRECTW draws a dithered rectangle in world space, without regard to

the clipping region. The rectangle's dither pattern is defined through a dithering matrix whose format is dependent on the video mode being used.

    FG_ELLIPSE draws an unfilled ellipse in screen space. The ellipse is

centered at the graphics cursor position, and its size is determined by the specified lengths of the semi-axes.

    FG_ELLIPSEF draws a filled ellipse in screen space. The ellipse is

centered at the graphics cursor position, and its size is determined by the specified lengths of the semi-axes.

    FG_ELLIPSEW draws an unfilled ellipse in world space. The ellipse is

centered at the graphics cursor position, and its size is determined by the specified lengths of the semi-axes. �

                                      Chapter 6:  Graphics Fundamentals   123


    FG_ELLIPSFW draws a filled ellipse in world space. The ellipse is

centered at the graphics cursor position, and its size is determined by the specified lengths of the semi-axes.

    FG_ERASE clears the screen in either text or graphics modes.
    FG_FILLPAGE fills the screen with the current color in either text or

graphics modes.

    FG_FLOOD fills an arbitrary closed region with the current color value,

with respect to the clipping limits. The region is defined by specifying a screen space point within its interior.

    FG_FLOODW fills an arbitrary closed region with the current color value,

with respect to the clipping limits. The region is defined by specifying a world space point within its interior.

    FG_GETCLIP returns the current clipping limits, as defined in the most

recent call to fg_setclip.

    FG_GETPIXEL returns the color value of a specified pixel.
    FG_GETXBOX returns the width in pixels for the left and right edges of

hollow rectangles drawn with Fastgraph's box display routines.

    FG_GETXPOS returns the screen space x coordinate of the graphics cursor

position.

    FG_GETYBOX returns the width in pixels for the top and bottom edges of

hollow rectangles drawn with Fastgraph's box display routines.

    FG_GETYPOS returns the screen space y coordinate of the graphics cursor

position.

    FG_INSIDE determines if the specified point is inside a given convex

polygon.

    FG_MOVE establishes the graphics cursor position at an absolute screen

space point.

    FG_MOVEREL establishes the graphics cursor position at a screen space

point relative to the current position.

    FG_MOVERW establishes the graphics cursor position at a world space point

relative to the current position.

    FG_MOVEW establishes the graphics cursor position at an absolute world

space point.

    FG_PAINT fills an arbitrary closed region with the current color value,

without respect to the clipping limits. The region is defined by specifying a screen space point within its interior. � 124 Fastgraph User's Guide


    FG_PAINTW fills an arbitrary closed region with the current color value,

without respect to the clipping limits. The region is defined by specifying a world space point within its interior.

    FG_POINT draws a point (that is, displays a pixel) in screen space.
    FG_POINTW draws a point in world space.
    FG_POINTX draws a point in "exclusive or" mode in screen space.
    FG_POINTXW draws a point in "exclusive or" mode in world space.
    FG_POLYEDGE defines whether or not fg_polyfill includes all pixels lying

on a polygon's right and bottom edges when drawing filled convex polygons.

    FG_POLYFILL draws a filled convex polygon in screen space. The polygon is

closed if necessary. By default, pixels lying on the polygon's right and bottom edges are not included when drawing the polygon. This behavior can be changed with fg_polyedge.

    FG_POLYGON draws an unfilled polygon in screen space, using two

coordinate arrays to define the polygon vertices. The polygon is closed if necessary.

    FG_POLYGONW draws an unfilled polygon in world space. It is the same as

fg_polygon, except the coordinate arrays contain world space values.

    FG_POLYLINE draws an unfilled polygon in screen space, using a single

coordinate array to define the polygon vertices. The polygon is closed if necessary.

    FG_POLYOFF defines the screen space offset applied to each vertex for

polygons drawn with fg_polyfill or fg_polyline.

    FG_RECT draws a solid (filled) rectangle in screen space or character

space, without regard to the clipping region.

    FG_RECTW draws a solid (filled) rectangle in world space, without regard

to the clipping region.

    FG_SETCLIP defines the clipping region in screen space. The clipping

region is a rectangular area outside of which certain graphics are suppressed.

    FG_SETCLIPW defines the clipping region in world space.




Chapter 7



Character Display Routines � 126 Fastgraph User's Guide


Overview

    An important part of any program is the capability to display text or

other characters on the screen. Fastgraph supports two character sets: the hardware or BIOS character set available with each video mode, and Fastgraph's own software character set for graphics video modes. Fastgraph/Light does not support the software character set.

    We'll begin this chapter with a review of character space, and then

discuss the specifics about hardware and software characters. At the end of the chapter, we'll briefly explain how to implement bitmapped characters into a program. To simplify matters, the example programs presented in this chapter are mode-specific examples, and no testing is done to check if the video mode is available on the user's system.


Character Space

    The coordinate system used for displaying hardware characters is called

character space. It is the only coordinate system available in text video modes, but it is a supplementary coordinate system you can use with either screen space or world space in graphics video modes. Character space can be thought of as a grid of rows and columns, with each cell in the grid holding one character. Each cell is identified by its unique (row,column) integer coordinates. The rows and columns are numbered starting at zero; the origin is always the upper left corner of the screen. For example, in the 80-column by 25-row video modes, the (row,column) coordinates of the screen corners are shown in the following diagram.


                           (0,0)           (0,79)


                           (24,0)         (24,79)


The default number of rows and columns depends on the video mode, as shown in the following table. For graphics modes, the table also includes the default width and height in pixels of a character cell.

                          Mode   No. of No. of Char. Char.
                         Number  Columns Rows  WidthHeight
                            0      40     25
                            1      40     25
                            2      80     25
                            3      80     25
                            4      40     25     8     8
                            5      40     25     8     8
                            6      80     25     8     8
                            7      80     25
                            9      40     25     8     8
                           11      80     25     9    14
                           12      40     25     8     8                      �
                                 Chapter 7:  Character Display Routines   127


                           13      40     25     8     8
                           14      80     25     8     8
                           15      80     25     8    14
                           16      80     25     8    14
                           17      80     30     8    16
                           18      80     30     8    16
                           19      40     25     8     8
                           20      40     25     8     8
                           21      40     50     8     8
                           22      40     30     8     8
                           23      40     60     8     8
                           24      80     25     8    16
                           25      80     30     8    16
                           26      100    37     8    16
                           27      128    48     8    16
                           28      100    37     8    16
                           29      128    48     8    16


Hardware Characters

    Hardware characters are available in all supported video modes. As

explained in Chapter 5, text mode characters have a display attribute that defines their foreground color, their background color, and whether or not they blink. Graphics mode characters appear in a single color, as determined by the current color index. Chapter 5 also explained how Fastgraph's fg_setattr and fg_setcolor routines define the attribute or color index in which subsequent hardware characters appear.

    It is obviously important to define the color or attribute for hardware

characters, but it is equally important to define their location on the screen. Fastgraph draws hardware characters at the position defined by the text cursor. Like the graphics cursor, the text cursor is not a cursor in the true sense, but is simply a pair of character space (row,column) coordinates with a special meaning. The fg_setmode routine sets the text cursor position to the character space coordinates (0,0), which of course is the upper left corner of the screen.2

    The Fastgraph routine fg_locate changes the text cursor position. It has

two integer arguments that specify the (row,column) character space coordinates of the new position. The row values must be between 0 and one less than the number of character rows available. The column values must be between 0 and one less than the number of character columns available.

    The fg_text routine is Fastgraph's basic character display routine. It

displays a string of hardware characters, starting at the text cursor position, using the current color attribute (for text modes) or color index (for graphics modes). If the string reaches the last column in a row, fg_text will wrap the string to the first column of the next row. Additionally, fg_text leaves the cursor one column to the right of the last character displayed (or the first column of the next row if the last character appears ____________________

  (2) In reality there are eight text cursors, one for each video page. The

fg_setmode routine initializes each text cursor position to (0,0). The next chapter describes this in more detail. � 128 Fastgraph User's Guide


at the end of a row). This feature makes it possible for successive calls to fg_text to display adjacent strings. The first argument for the fg_text routine is a character string of arbitrary length, and the second argument is an integer value that specifies the number of characters to display from that string.

    Example 7-1 illustrates the use of fg_locate and fg_text in the 80x25

color text mode (mode 3). After establishing the video mode and making the BIOS cursor invisible, the program displays four strings with different attributes. The attributes are selected using fg_setattr, and the strings are displayed by fg_text. The first string appears in yellow (attributes 14,0,0) in the upper left corner of the screen; fg_locate is not necessary because (0,0) is the default text cursor position established by fg_setmode. The second string appears in light green (10,0,0) one space to the right of the first string. Its position relies on the fact fg_text leaves the text cursor positioned one space to the right of the last character displayed (following the "w" of "yellow" in this case). The leading space in " green" leaves a space between the first and second strings. Similarly, the third string appears in blinking light red (12,0,1) one space to the right of the second string.

    The program then uses fg_locate to move the text cursor to the lower left

corner of the screen and displays the "Press any key" string. This string is displayed with a light red foreground against a gray background (12,7,0). The extra spaces surrounding the string extend the background color one character position to the left and right and make the string more visually appealing. Finally, once you press any key, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 7-1.
                     #include <fastgraf.h>
                     void main(void);
                     void main()
                     {
                        int old_mode;
                        fg_initpm();
                        old_mode = fg_getmode();
                        fg_setmode(3);
                        fg_cursor(0);
                        fg_setattr(14,0,0);
                        fg_text("yellow",6);
                        fg_setattr(10,0,0);
                        fg_text(" green",6);
                        fg_setattr(12,0,1);
                        fg_text(" blinking",9);
                        fg_setattr(12,7,0);
                        fg_locate(24,0);
                        fg_text(" Press any key. ",16);
                        fg_waitkey();                                         �
                                 Chapter 7:  Character Display Routines   129


                        fg_setmode(old_mode);
                        fg_reset();
                     }


    The fg_where routine retrieves the text cursor position in its two

integer arguments. This routine is not used as frequently as fg_locate and fg_text because more often than not your program will know the text cursor position implicitly, or you'll know in advance the locations at which text will be displayed. The fg_where routine takes two integer arguments passed by reference, and these two arguments respectively receive the text cursor's current row and column position.

    Example 7-2 produces the same results as example 7-1, but it does so a

bit differently. It uses its own routine, put_string, to display a string at a specified row and column. The put_string routine simply calls fg_locate to establish the text cursor position and then calls fg_text to display the string. Note the use of the C library function strlen to determine the string length passed to fg_text. Example 7-2 also uses fg_where to retrieve the new text cursor positions, which are then passed to put_string.

                                Example 7-2.
                   #include <fastgraf.h>
                   #include <string.h>
                   void main(void);
                   void put_string(char*,int,int);
                   void main()
                   {
                      int old_mode;
                      int row, column;
                      fg_initpm();
                      old_mode = fg_getmode();
                      fg_setmode(3);
                      fg_cursor(0);
                      fg_setattr(14,0,0);
                      put_string("yellow",0,0);
                      fg_setattr(10,0,0);
                      fg_where(&row,&column);
                      put_string("green",row,column+1);
                      fg_setattr(12,0,1);
                      fg_where(&row,&column);
                      put_string("blinking",row,column+1);
                      fg_setattr(12,7,0);
                      put_string(" Press any key. ",24,0);
                      fg_waitkey();
                      fg_setmode(old_mode);
                      fg_reset();                                             �

130 Fastgraph User's Guide


                   }
                   void put_string(string,row,column)
                   char *string;
                   int row, column;
                   {
                      fg_locate(row,column);
                      fg_text(string,strlen(string));
                   }


    Sometimes you may wish to change the display attribute of existing text,

such as when creating a shadow around the edges of a pop-up window. The Fastgraph routine fg_chgattr performs this function. It applies the current text display attribute (as defined in the most recent call to fg_setattr or fg_setcolor) to a given number of characters, starting at the text cursor position. It leaves the text cursor one column to the right of the last character changed (or the first column of the next row if the last character is at the end of a row). The fg_chgattr routine's argument specifies the number of characters to change. This routine has no effect in graphics video modes.

    The Fastgraph routine fg_chgtext performs somewhat the opposite function

of fg_chgattr. It displays new text but uses the display attributes already assigned to the character cells where the text will appear. The fg_chgtext routine takes the same two arguments as fg_text, displays the characters starting at the text cursor position, and leaves the cursor one column to the right of the last character displayed. Like fg_chgattr, fg_chgtext has no effect in graphics video modes.

    Example 7-3 illustrates the fg_chgattr and fg_chgtext routines. It runs

in the 80-column color text mode (mode 3), but if we change the fg_setmode argument it also would run in the monochrome text mode (mode 7). The program first displays the word "hello" in the upper left corner of the screen, using a gray foreground and black background attribute. After waiting for a keystroke, the program calls fg_chgattr to make the word "hello" appear in reverse video (that is, a black foreground and gray background attribute). After a second keystroke, the program uses fg_chgtext to change the "h" of "hello" to upper case. Following this, the program returns to DOS.

                                Example 7-3.
                         #include <fastgraf.h>
                         void main(void);
                         void main()
                         {
                            int old_mode;
                            fg_initpm();
                            old_mode = fg_getmode();
                            fg_setmode(3);
                            fg_cursor(0);
                            fg_setattr(7,0,0);
                            fg_text("hello",5);                               �
                                 Chapter 7:  Character Display Routines   131


                            fg_waitkey();
                            fg_locate(0,0);
                            fg_setattr(0,7,0);
                            fg_chgattr(5);
                            fg_waitkey();
                            fg_locate(0,0);
                            fg_chgtext("H",1);
                            fg_waitkey();
                            fg_setmode(old_mode);
                            fg_reset();
                         }


    You also can retrieve the character or attribute stored in a specific

character cell. The Fastgraph routine fg_getchar retrieves character values, while fg_getattr retrieves character attributes. Both routines have two integer arguments that specify the (row,column) coordinates for the character cell of interest. Example 7-4 uses fg_getchar and fg_getattr to read the character and attribute stored at row 24, column 0. Just before the program exits, it displays these values.

                                Example 7-4.
                     #include <fastgraf.h>
                     #include <stdio.h>
                     void main(void);
                     void main()
                     {
                        int attr, value;
                        int old_mode;
                        fg_initpm();
                        old_mode = fg_getmode();
                        fg_setmode(3);
                        fg_cursor(0);
                        fg_setattr(9,7,0);
                        fg_locate(24,0);
                        fg_text("Test",4);
                        value = fg_getchar(24,0);
                        attr  = fg_getattr(24,0);
                        fg_waitkey();
                        fg_setmode(old_mode);
                        fg_reset();
                        printf("%c %2.2X\n",value,attr);
                     }


    If you need to retrieve characters and attributes from a rectangular

area, it's more efficient to use the fg_getimage routine (described in Chapter 10) than to call fg_getchar and fg_getattr repeatedly. � 132 Fastgraph User's Guide


    Displaying hardware characters in graphics video modes is different from

doing so in text modes. Like text modes, we can still use fg_text to display strings in character space, which of course restricts the places where strings can appear. Graphics modes offer the ability to display strings relative to any pixel, not just character cells. The fg_print and fg_justify routines are provided for this purpose. To compare the two methods of displaying strings in graphics modes, let's begin with an example of doing so with fg_text.

    Example 7-5 is similar to example 7-1, but it runs in the EGA enhanced

graphics mode (mode 16) instead of a text mode. In graphics modes, fg_cursor has no effect, so we have omitted it from the program. Furthermore, characters cannot be displayed with a blinking attribute, so we have omitted the blinking characters (we could simulate blinking by repetitively displaying and erasing them, but that is beyond the scope of this example). Because graphics mode characters only have a foreground color, we had to simulate the gray background of the "Press any key" string by first drawing a rectangle where that string appears. The differences between examples 7-5 and 7-1 hold for any graphics video mode, not just mode 16.

                                Example 7-5.
                     #include <fastgraf.h>
                     void main(void);
                     void main()
                     {
                        int old_mode;
                        fg_initpm();
                        old_mode = fg_getmode();
                        fg_setmode(16);
                        fg_setcolor(14);
                        fg_text("yellow",6);
                        fg_setcolor(10);
                        fg_text(" green",6);
                        fg_setcolor(7);
                        fg_rect(0,127,336,349);
                        fg_setcolor(12);
                        fg_locate(24,0);
                        fg_text(" Press any key. ",16);
                        fg_waitkey();
                        fg_setmode(old_mode);
                        fg_reset();
                     }


    Now let's show how to display graphics mode strings using the more

flexible screen space coordinate system. The fg_print routine is identical to fg_text, but it displays a string relative to the graphics cursor position (that is, in screen space) rather than the character space position established with fg_locate. By default, fg_print displays strings so their �

                                 Chapter 7:  Character Display Routines   133


lower left corner is at the graphics cursor position. The fg_justify routine lets you change this default justification. Its two parameters, xjust and yjust, control the string positioning about the current graphics position, as summarized in the following table:

               value of     value of   horizontal      vertical
                 xjust       yjust    justification  justification
                  -1           -1         left           lower
                  -1           0          left          center
                  -1           1          left           upper
                   0           -1        center          lower
                   0           0         center         center
                   0           1         center          upper
                   1           -1         right          lower
                   1           0          right         center
                   1           1          right          upper

Any other justification values produce undefined results. In the context of vertical justification, lower justification means the bottom of each character will be at the current graphics y position. Upper justification means the top of each character will be at the graphics y position, while center justification means characters will be centered about the graphics y position. The default justification settings (established by fg_setmode) are xjust = -1 and yjust = -1, and you can retrieve the current justification settings with Fastgraph's fg_getxjust and fg_getyjust functions. Like fg_text, fg_print leaves the graphics cursor positioned just beyond the bottom right corner of the last character displayed.

    Neither fg_print nor fg_text performs clipping. There may be times,

however, when displaying clipped strings is desirable, such as when displaying text inside a fixed window. When clipping is needed, use fg_printc or fg_textc for displaying strings. These two routines are identical in all respects to fg_print and fg_text, but they do not display characters lying outside the clipping region established by fg_setclip or fg_setclipw. Further, if part of a character is outside the clipping region, fg_printc and fg_textc display only that part of the character that falls within the clipping region. Because clipping is supported only in graphics video modes, fg_textc is equivalent to fg_text when used in text video modes.

    Example 7-6 illustrates the use of fg_print and fg_justify to display

justified text in the VGA 640x480 16-color graphics mode (mode 18). The first series of calls to fg_move, fg_justify, and fg_print display the string "Fastgraph" left justified, centered, and right justified against the top row of the screen. The second series of such calls also displays the string in these positions, but each is centered vertically in the middle of the screen. The final series displays the strings against the bottom row of the screen. The nine calls to fg_justify in example 7-6 represent all possible justification settings for strings displayed with fg_print.

                                Example 7-6.
                         #include <fastgraf.h>
                         void main(void);
                         void main()                                          �

134 Fastgraph User's Guide


                         {
                            int old_mode;
                            fg_initpm();
                            old_mode = fg_getmode();
                            fg_setmode(18);
                            fg_setcolor(9);
                            fg_fillpage();
                            fg_setcolor(14);
                            fg_move(0,0);
                            fg_justify(-1,1);
                            fg_print("Fastgraph",9);
                            fg_move(320,0);
                            fg_justify(0,1);
                            fg_print("Fastgraph",9);
                            fg_move(639,0);
                            fg_justify(1,1);
                            fg_print("Fastgraph",9);
                            fg_move(0,240);
                            fg_justify(-1,0);
                            fg_print("Fastgraph",9);
                            fg_move(320,240);
                            fg_justify(0,0);
                            fg_print("Fastgraph",9);
                            fg_move(639,240);
                            fg_justify(1,0);
                            fg_print("Fastgraph",9);
                            fg_move(0,479);
                            fg_justify(-1,-1);
                            fg_print("Fastgraph",9);
                            fg_move(320,479);
                            fg_justify(0,-1);
                            fg_print("Fastgraph",9);
                            fg_move(639,479);
                            fg_justify(1,-1);
                            fg_print("Fastgraph",9);
                            fg_waitkey();
                            fg_setmode(old_mode);
                            fg_reset();
                         }


    Example 7-7 demonstrates a side effect that occurs when displaying

characters in graphics modes. This example uses the MCGA graphics mode (mode 19) and displays two character strings at the same location. If we were to do this in a text mode, the first string would disappear once we displayed the second string (assuming the second string isn't shorter than the first). In graphics modes, however, the portions of the first string not covered by characters from the second string are still visible. The reason for this may not be clear at first, but remember when we display characters in graphics modes, we aren't really displaying characters but merely a pixel representation of the characters. Fastgraph has no way to distinguish such �

                                 Chapter 7:  Character Display Routines   135


pixels from any other pixels, no matter what routine we use for string display.

                                Example 7-7.
                         #include <fastgraf.h>
                         void main(void);
                         void main()
                         {
                            int old_mode;
                            fg_initpm();
                            old_mode = fg_getmode();
                            fg_setmode(19);
                            fg_setcolor(14);
                            fg_text("yellow",6);
                            fg_locate(0,0);
                            fg_setcolor(10);
                            fg_text(" green",6);
                            fg_waitkey();
                            fg_setmode(old_mode);
                            fg_reset();
                         }


    To avoid this problem, the recommended procedure for displaying

characters in graphics modes is to first erase the area where the text will appear. The easiest way to do this is to use fg_rect to draw a rectangle in the background color. In example 7-7, we could do this by inserting the statements


                             fg_setcolor(0);
                             fg_rect(0,47,0,7);


immediately before the call to fg_locate. The parameters passed to the fg_rect routine represent the 48 by 8 pixel region that corresponds to the first six character cells of row 0 in the 320x200 graphics modes.


Character Height

    In VGA and SVGA graphics modes (modes 17 to 29), it's possible to change

the height of characters displayed with fg_print, fg_printc, fg_text, and fg_textc. By default, characters are 16 pixels high in the VGA and SVGA graphics modes (17, 18, 24 to 29) and 8 pixels high in the MCGA and XVGA graphics modes (19 to 23). The fg_fontsize routine lets you display characters from the BIOS 8x8, 8x14, or 8x16 fonts in any of these modes. Its only parameter specifies the character height in pixels; it must be 8, 14, or 16. If the character height is some other value, or if fg_fontsize is used in a video mode numbered 16 or less (that is, in a non-VGA mode), nothing happens. � 136 Fastgraph User's Guide


    When we change the character height with fg_fontsize, the number of text

rows on the screen changes accordingly. The following table shows the number of text rows available in each supported video mode when using the different character sizes. The values in boldface represent the default character size and number of rows for that video mode.

                                Mode No. of rows with
                               Number 8x8  8x14 8x16
                                 17    60   34   30
                                 18    60   34   30
                                 19    25   14   12
                                 20    25   14   12
                                 21    50   28   25
                                 22    30   17   15
                                 23    60   34   30
                                 24    50   28   25
                                 25    60   34   30
                                 26    75   42   37
                                 27    96   54   48
                                 28    75   42   37
                                 29    96   54   48
    Example 7-8 shows how to use fg_fontsize to activate the 8x8 character

font in the 16-color 640x480 VGA graphics mode (mode 18). In this mode, characters are normally 16 pixels high, giving 30 character rows per screen. When we use the 8x8 font, this increases to 60 rows because the characters are now half as tall as before. The example program uses fg_text to display the string "8x8 ROM font" 60 times, once in each row.

                                Example 7-8.
                     #include <fastgraf.h>
                     void main(void);
                     void main()
                     {
                        int old_mode;
                        int row;
                        fg_initpm();
                        old_mode = fg_getmode();
                        fg_setmode(18);
                        fg_setcolor(9);
                        fg_fillpage();
                        fg_setcolor(15);
                        fg_fontsize(8);
                        for (row = 0; row < 60; row++) {
                           fg_locate(row,34);
                           fg_text("8x8 ROM font",12);
                           }
                        fg_waitkey();
                        fg_setmode(old_mode);                                 �
                                 Chapter 7:  Character Display Routines   137


                        fg_reset();
                     }


Conversion Routines

    In Chapter 4 we introduced Fastgraph's routines for converting

coordinates between character space and screen space. In this section we'll review these routines and then present an example that uses some of them.

    The fg_xalpha and fg_yalpha routines convert screen space coordinates to

character space. The fg_xalpha routine converts a screen space x coordinate to the character space column that contains the coordinate. Similarly, fg_yalpha converts a screen space y coordinate to the character space row that contains the coordinate.

    The fg_xconvert and fg_yconvert routines convert character space

coordinates to screen space. The fg_xconvert routine converts a character space column to the screen space coordinate of its leftmost pixel. Similarly, fg_yconvert converts a character space row to the screen space coordinate of its top (lowest-numbered) pixel.

    Example 7-5 demonstrated how to display characters in a graphics mode.

Because characters do not have a background color in graphics modes, that example used fg_rect to simulate a background color by drawing a gray rectangle before displaying the text. It was necessary to determine the screen coordinates of the character cells so we could pass the correct parameters to fg_rect. By using fg_xconvert and fg_yconvert, we can let Fastgraph calculate the required screen coordinates. This method has the additional benefit of working in any graphics mode, while the coordinates passed to fg_rect in example 7-5 would only work properly in a 640x350 graphics mode. Example 7-9 shows how we could extend example 7-5 using fg_xconvert and fg_yconvert.

                                Example 7-9.
                     #include <fastgraf.h>
                     void main(void);
                     void main()
                     {
                        int old_mode;
                        int minx, maxx, miny, maxy;
                        fg_initpm();
                        fg_old_mode = fg_getmode();
                        fg_setmode(16);
                        fg_setcolor(14);
                        fg_text("yellow",6);
                        fg_setcolor(10);
                        fg_text(" green",6);
                        fg_setcolor(7);
                        minx = fg_xconvert(0);                                �

138 Fastgraph User's Guide


                        maxx = fg_xconvert(16) - 1;
                        miny = fg_yconvert(24);
                        maxy = fg_yconvert(25) - 1;
                        fg_rect(minx,maxx,miny,maxy);
                        fg_setcolor(12);
                        fg_locate(24,0);
                        fg_text(" Press any key. ",16);
                        fg_waitkey();
                        fg_setmode(old_mode);
                        fg_reset();
                     }


Software Characters

    Software characters, also called stroke characters or vector characters

in other literature, are only are available in graphics video modes. Unlike the fixed-size hardware characters, you can display software characters in any size, at any angle, and at any position. In addition, software characters are proportionally spaced. However, software characters take longer to draw than hardware characters do.

    Fastgraph includes two software character fonts, called the primary font

and the alternate font. The primary font contains upper and lower case letters, numbers, punctuation, and most other printable ASCII characters. The alternate font contains upper and lower case Greek letters and other mathematical and scientific symbols.

    The Fastgraph routine fg_swchar displays a string of software characters

in the current color index (as defined by the most recent call to fg_setcolor). The string may contain any characters from the primary font, the alternate font, or both. You can display the characters left justified, centered, or right justified relative to the graphics cursor position. Just as fg_text updates the text cursor position, fg_swchar sets the graphics cursor position just to the right of the last character drawn. The characters are clipped according to the current clipping region. In addition to the characters, the string passed to fg_swchar also may contain operators for switching fonts, underlining, subscripting, or superscripting characters. Because fg_swchar internally uses world space coordinates, you must call the fg_initw routine at some point in your program before the first call to fg_swchar. You also must establish a world space coordinate system with the fg_setworld routine.

    The fg_swchar routine has three arguments. The first argument is the

character string to display. The second argument is an integer value that specifies the number of characters in the string, including any characters used as special operators. The third argument is an integer value that determines the position of the string relative to the graphics cursor position. If this value is negative, the lower left corner of the first character will be at the graphics cursor position. If it is positive, the lower right corner of the last character will be at the graphics cursor position. If it is zero, the string will be horizontally centered at the graphics cursor position. �

                                 Chapter 7:  Character Display Routines   139


    The size of software characters is determined by the values passed to

fg_setsize, fg_setsizew, and fg_setratio. The fg_setsize routine has a single integer argument that defines the height of software characters in screen space units, while fg_setsizew has a single floating point argument that defines the height in world space units. If neither of these routines is called, Fastgraph will use its default character height of one world space unit. The fg_setratio routine has a single floating point argument that defines the aspect ratio for software characters. The aspect ratio is the ratio of character width to character height. For example, an aspect ratio of 2.0 means characters are twice as wide as they are high. If fg_setratio is not called, Fastgraph uses its default aspect ratio of 1.

    Example 7-10 displays all characters in both software character fonts.

The program uses the enhanced EGA graphics mode (mode 16), but it could run in any graphics mode by changing the fg_setmode argument. After establishing the video mode, the program calls fg_initw to initialize Fastgraph's world space parameters; this is required since the software character drawing routines internally use world space coordinates. The next statement is a call to fg_setworld that establishes a world space coordinate system with 0.01 world space units per pixel. Following this is a call to fg_setsizew that defines the character height as 0.21 world space units, or 21 pixels. Note we could have instead used fg_setsize here with an integer argument of 21.

    The next part of the program draws the characters in the primary font on

the upper half of the screen. After doing this, the program draws the alternate font characters on the lower half. In each case it does this with fg_swchar. By default, the string passed to fg_swchar will produce characters from the primary font. However, you can insert a back slash character (\) in the string to toggle between the two fonts. Don't forget C and C++ apply a special meaning to the back slash character within strings, so you must use two consecutive back slashes to insert a single back slash in the string.

                                Example 7-10.
            #include <fastgraf.h>
            void main(void);
            void main()
            {
               int old_mode;
               fg_initpm();
               old_mode = fg_getmode();
               fg_setmode(16);
               fg_initw();
               fg_setworld(0.0,6.39,0.0,3.49);
               fg_setsizew(0.21);
               fg_setcolor(15);
               fg_locate(0,26);
               fg_text("Software characters - font 1",28);
               fg_setcolor(10);
               fg_movew(0.0,3.1);
               fg_swchar("ABCDEFGHIJKLMNOPQRSTUVWXYZ",26,-1);
               fg_movew(0.0,2.8);                                             �

140 Fastgraph User's Guide


               fg_swchar("abcdefghijklmnopqrstuvwxyz",26,-1);
               fg_movew(0.0,2.5);
               fg_swchar("0123456789",10,-1);
               fg_movew(0.0,2.2);
               fg_swchar("!\"#$%&'()*+,-./:;<=>?[]^`{|}~",29,-1);
               fg_setcolor(15);
               fg_locate(12,26);
               fg_text("Software characters - font 2",28);
               fg_setcolor(10);
               fg_movew(0.0,1.4);
               fg_swchar("\\ABCDEFGHIJKLMNOPRSTUWXYZ",25,-1);
               fg_movew(0.0,1.1);
               fg_swchar("\\abcdefghijklmnoprstuwxyz",25,-1);
               fg_movew(0.0,0.4);
               fg_swchar("\\012345678#$%&()*+/<=>?[]{}",27,-1);
               fg_waitkey();
               fg_setmode(old_mode);
               fg_reset();
            }


If you compare the primary font strings with the alternate font strings, you'll see the alternate font contains fewer characters. For example, the letters Q and V (either upper or lower case) have no corresponding character in the alternate font. You might have also noticed the primary font does not support the full printable ASCII character set. Any character in a string passed to fg_swchar that does not have a corresponding character in the current font will display a blank character.

    In addition to the font change operator (the back slash character),

fg_swchar recognizes three other operators. The superscript operator is a back slash followed by a caret (\^). It causes the next character to appear as a superscript. Similarly, the subscript operator is a back slash followed by a lower case v (\v); it causes the next character to appear as a subscript. The size of superscripted and subscripted characters is one half the height of the other characters. The underline operator is the underscore character (_). It causes all subsequent characters in the string to be underlined until another underscore character is found, or until the end of the string. When using these operators, be sure to include them as part of the string length count passed to fg_swchar.

    Example 7-11 illustrates the use of the font selection, superscript,

subscript, and underline operators with fg_swchar. Again, because the back slash character has a special meaning in C and C++, we must use two consecutive back slashes to represent a single back slash within the string. The program displays four strings:

                              cos2  + sin2  = 1
                                     H2O
                                    U232
                           One word is underlined.                            �
                                 Chapter 7:  Character Display Routines   141


The theta symbol in the first string is produced by displaying the character "h" in the alternate font. Note another font selection operator (\) appears immediately after the "h" to revert to the primary font. The first string also includes superscript operators (\^) to display the exponents in the equation. The second string includes a single subscripted character, while the third string shows how to display three consecutive subscripted characters. Finally, the fourth string illustrates how to underline characters.

    Note example 7-11 also uses fg_setratio. The first three strings are

drawn with an aspect ratio of 2, making them twice as wide as they are high. The fourth string is drawn with an aspect ratio of 1 (Fastgraph's default aspect ratio for software characters), so the character height is the same as the character width. Also, the strings are centered instead of left justified as in the previous example.

                                Example 7-11.
            #include <fastgraf.h>
            void main(void);
            void main()
            {
               int old_mode;
               fg_initpm();
               old_mode = fg_getmode();
               fg_setmode(16);
               fg_setcolor(10);
               fg_initw();
               fg_setworld(0.0,6.39,0.0,3.49);
               fg_setratio(2.0);
               fg_setsizew(0.21);
               fg_movew(3.2,3.0);
               fg_swchar("cos\\^2\\h\\ + sin\\^2\\h\\ = 1",25,0);
               fg_movew(3.2,2.0);
               fg_swchar("H\\v2O   U\\v2\\v3\\v2",18,0);
               fg_movew(3.2,1.0);
               fg_setratio(1.0);
               fg_swchar("One _word_ is underlined.",25,0);
               fg_waitkey();
               fg_setmode(old_mode);
               fg_reset();
            }


    The fg_setangle routine defines the angle of rotation at which software

characters are displayed. Its only argument is a floating point value that specifies the angle, measured in degrees counterclockwise from the positive x axis. If a program draws software characters before calling fg_setangle, Fastgraph will use its default angle of zero degrees (that is, the characters will be oriented horizontally). � 142 Fastgraph User's Guide


    In most programs, the alternate font is not needed. However, if you use

the fg_swchar routine, Fastgraph will include the definitions of these characters in your program's data segment. To prevent wasting this space, Fastgraph includes the fg_swtext routine. The fg_swtext routine is same as fg_swchar, except it does not include the alternate font. Since the font selection operator does not apply when using fg_swtext, the routine simply ignores it. You should only use fg_swtext if do not use fg_swchar. If you use both routines, your program will still work correctly, but its data segment will contain an extra copy of the primary font definitions.

    Example 7-12 demonstrates the use of fg_setangle and fg_swtext. The

program draws a series of strings of the form "nnn degrees", where nnn is a multiple of 15, radiating from the screen center. Each string appears at the specified angle. For example, the string "15 degrees" is drawn at an angle of 15 degrees.

                                Example 7-12.
               #include <fastgraf.h>
               #include <stdio.h>
               void main(void);
               void main()
               {
                  char string[24];
                  int angle;
                  int old_mode;
                  fg_initpm();
                  old_mode = fg_getmode();
                  fg_setmode(16);
                  fg_setcolor(10);
                  fg_initw();
                  fg_setworld(0.0,6.39,0.0,3.49);
                  fg_setsizew(0.21);
                  for (angle = 0; angle < 360; angle += 15) {
                     fg_movew(3.2,1.75);
                     fg_setangle((double)angle);
                     sprintf(string,"     %3d degrees",angle);
                     fg_swtext(string,16,-1);
                     }
                  fg_waitkey();
                  fg_setmode(old_mode);
                  fg_reset();
               }


    The final routine pertaining to software characters is fg_swlength, which

returns the length of a specified string of software characters in world space units. The length is returned as the routine's floating point function value. The fg_swlength routine has two arguments -- a string of software characters, and an integer value specifying the number of characters in the string. As with fg_swchar and fg_swtext, the count includes any of the special operator characters. �

                                 Chapter 7:  Character Display Routines   143


    Example 7-13 demonstrates a typical use of the fg_swlength routine. The

program displays the string "hello there." in light green against a gray background in the middle of the screen. As in our previous software character examples, the program uses mode 16 and first performs the necessary initializations to use software characters. Following this, the program uses fg_swlength to compute the length in world space units of the string. Note we have added blank characters to each end of the string passed to fg_swlength; this increases the length of the actual string and will effectively give the gray rectangle an extended border on its left and right sides. The string length returned by fg_swlength is multiplied by 0.5, giving the distance from the middle of the screen to either side of the rectangle. The program then uses this value to compute the minimum and maximum x coordinates passed to fg_rectw. After drawing the gray rectangle, the program uses fg_swtext to draw the string of software characters in the middle of the screen. It then waits for a keystroke before restoring the original video mode and screen attributes and returning to DOS.

                                Example 7-13.
              #include <fastgraf.h>
              void main(void);
              void main()
              {
                 int old_mode;
                 double half;
                 fg_initpm();
                 old_mode = fg_getmode();
                 fg_setmode(16);
                 fg_initw();
                 fg_setworld(0.0,6.39,0.0,3.49);
                 fg_setsizew(0.21);
                 fg_setcolor(7);
                 half = fg_swlength(" Hello there. ",14) * 0.5;
                 fg_rectw(3.2-half,3.2+half,1.6,1.9);
                 fg_setcolor(10);
                 fg_movew(3.2,1.65);
                 fg_swtext("Hello there.",12,0);
                 fg_waitkey();
                 fg_setmode(old_mode);
                 fg_reset();
              }


Bitmapped Characters

    Bitmapped characters combine the properties of hardware and software

characters. Like hardware characters, they are a fixed size, but they are almost always more visually appealing. Because they are not scalable, they do � 144 Fastgraph User's Guide


not require floating point arithmetic, and therefore they are much faster than software characters.

    Fastgraph makes no special provision for bitmapped characters because it

treats them as if they were any other bitmapped image. For example, to use a five-pixel by five-pixel bitmapped font, you can construct characters as shown here and then store these representations in an image array.

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

The image display routines fg_drawmap and fg_drwimage, discussed in Chapter 10, could then be used to display specific characters from the image array. Also, the Fastgraph/Fonts add-on product greatly simplifies adding bitmapped font support to Fastgraph applications.


Summary of Character Display Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_CHGATTR applies the current text display attribute to a given number

of characters, starting at the text cursor position. This routine leaves the text cursor one column to the right of the last character changed (or the first column of the next row if the last character is at the end of a row). It has no effect in graphics video modes.

    FG_CHGTEXT displays a string of hardware characters, starting at the text

cursor position, using the existing text display attributes. This routine leaves the text cursor one column to the right of the last character displayed (or the first column of the next row if the last character is at the end of a row). It has no effect in graphics video modes.

    FG_FONTSIZE enables the 8x8, 8x14, or 8x16 ROM BIOS character font for

strings displayed with fg_print and fg_text. This routine is meaningful only in VGA and SVGA graphics video modes.

    FG_GETATTR returns the character attribute stored at the specified

position on the active video page. It has no effect in graphics video modes.

    FG_GETCHAR returns the character value stored at the specified position

on the active video page. It has no effect in graphics video modes.

    FG_GETXJUST returns the current horizontal justification setting for

strings displayed with fg_print or fg_printc.

    FG_GETYJUST returns the current vertical justification setting for

strings displayed with fg_print or fg_printc. �

                                 Chapter 7:  Character Display Routines   145


    FG_JUSTIFY defines the horizontal and vertical justification settings for

strings displayed with fg_print or fg_printc.

    FG_LOCATE establishes the text cursor position for the active video page.
    FG_PRINT displays a string of hardware characters, relative to the

graphics cursor position, using the current color index. By default, strings are displayed such that the bottom row of the first character is at the current graphics position. On return, the graphics cursor is positioned just to the right of the last character displayed.

    FG_PRINTC is a version of fg_print that performs clipping.
    FG_SETANGLE defines the angle or orientation at which software characters

are displayed. The angle is measured in degrees counterclockwise from the positive x axis.

    FG_SETATTR establishes the current text display attribute in text video

modes. This routine has no effect in graphics video modes.

    FG_SETCOLOR establishes the current color index (which may be a virtual

color index in graphics modes). In text modes, the fg_setcolor routine provides an alternate method of establishing the current text display attribute.

    FG_SETRATIO defines the aspect ratio for software characters. The aspect

ratio is the ratio of character width to character height.

    FG_SETSIZE defines the height of software characters in screen space

units.

    FG_SETSIZEW defines the height of software characters in world space

units.

    FG_SWCHAR displays a string of software characters using the current

color index. The string may be left justified, centered, or right justified relative to the graphics cursor position. The string passed to fg_swchar may contain special operators that allow switching between fonts, underlining, superscripting, or subscripting. This routine has no effect in text video modes.

    FG_SWLENGTH returns the length in world space units of a string of

software characters.

    FG_SWTEXT is a scaled down version of the fg_swchar routine. It does not

include the alternate font character definitions and thus requires less memory than fg_swchar.

    FG_TEXT displays a string of hardware characters, starting at the text

cursor position, using the current color attribute (for text modes) or color index (for graphics modes). This routine leaves the text cursor one column to the right of the last character displayed (or the first column of the next row if the last character is at the end of a row).

    FG_TEXTC is a version of fg_text that performs clipping when run in

graphics video modes. In text modes, fg_textc is equivalent to fg_text. � 146 Fastgraph User's Guide


    FG_WHERE retrieves the row and column numbers of the text cursor

position.

    FG_XALPHA and FG_YALPHA convert screen space coordinates to character

space.

    FG_XCONVERT and FG_YCONVERT convert character space coordinates to screen

space.




Chapter 8



Video Pages and Virtual Buffers � 148 Fastgraph User's Guide


Overview

    The amount of memory required to store one full screen of information is

called a video page (or sometimes simply a page). Fastgraph offers a variety of page types, including physical pages, virtual pages, extended pages, and logical pages. In addition, virtual buffers let you define arbitrary blocks of conventional memory and treat them as if they were video memory. This chapter will discuss video pages and virtual buffers in detail, along with the Fastgraph routines to manage them.


Physical Pages and Virtual Pages

    Pages that use the memory that resides on the video adapter are called

physical pages or true pages. The number of physical pages available depends on the video mode and the amount of memory resident on the user's video adapter. All video modes have at least one physical page. In certain video modes, Fastgraph can allocate available random-access memory (RAM) and treat this memory as a video page. Pages that use standard RAM in this sense are called virtual pages. From a programmer's perspective, virtual pages are essentially identical to physical pages.

    The following table shows the number of physical pages in each video

mode. It also indicates whether or not specific video modes support virtual pages.

     Mode                               Page Size Physical   Virtual
    Number  Description                 in Bytes    Pages     Pages
      0     40 column color text           2,000      8        no
      1     40 column color text           2,000      8        no
      2     80 column color text           4,000      4        no
      3     80 column color text           4,000      4        no
      4     320x200x4 CGA graphics        16,000      1        yes
      5     320x200x4 CGA graphics        16,000      1        yes
      6     640x200x2 CGA graphics        16,000      1        yes
      7     80 column monochrome text      4,000      1        yes
      9     320x200x16 Tandy graphics     32,000      1        yes
      11    720x348 Hercules graphics     31,320      2        yes
      12    320x200 Hercules graphics     31,320      2        yes
      13    320x200x16 EGA graphics       32,000      8        no
      14    640x200x16 EGA graphics       64,000      4        no
      15    640x350 EGA mono graphics     56,000      2        no
      16    640x350x16 EGA graphics      112,000      2        no
      17    640x480x2 MCGA/VGA graphics   38,400     1+        no
      18    640x480x16 VGA graphics      153,600     1+        no
      19    320x200x256 MCGA graphics     64,000      1        yes
      20    320x200x256 XVGA graphics     64,000      4        no
      21    320x400x256 XVGA graphics    128,000      2        no
      22    320x240x256 XVGA graphics     76,800     3+        no
      23    320x480x256 XVGA graphics    153,600     1+        no
      24    640x400x256 SVGA graphics    256,000      4        no
      25    640x480x256 SVGA graphics    307,200      2        no
      26    800x600x256 SVGA graphics    480,000      2        no
      27    1024x768x256 SVGA graphics   786,432     1+        no             �
                            Chapter 8:  Video Pages and Virtual Buffers   149


      28    800x600x16 SVGA graphics     240,000      4        no
      29    1024x768x16 SVGA graphics    393,216      2        no

This table assumes the video adapter has 256K of video memory installed for EGA and VGA modes, and 1MB of video memory for SVGA modes. For adapters with less video memory, the number of physical pages is reduced proportionately. In other words, a 64K EGA has two video pages available instead of eight in mode 13. Similarly, a 512K SVGA has one page instead of two in modes 25 and 26, and wouldn't support mode 27. The next table summarizes the number of video pages available in SVGA graphics modes for video cards with 256K, 512K, 768K, and 1MB of video memory installed.

                      Mode              Number of pages with...
                     Number  Resolution   256K 512K 768K 1MB
                       24    640x400x256   1+    2   3    4
                       25    640x480x256    0   1+   1+   2
                       26    800x600x256    0   1+   1+   2
                       27    1024x768x256   0    0   1   1+
                       28    800x600x16    1+    2   3    4
                       29    1024x768x16    0   1+   1+   2
    In the preceding two tables, note that the number of physical pages in

some video modes is followed by a plus symbol. In these modes, there is an additional partial video page available. For modes 17, 18, and 23, there is one full page (page 0) plus one partial page of 320 pixel rows (page 1). For mode 22, there are three full physical pages (numbered 0 to 2) plus one partial page of 80 pixel rows (page 3). For mode 27, there is one full page (page 0) plus one partial page of 256 pixel rows (page 1) on a 1MB SVGA card. You can safely use the partial pages as long as you don't reference pixel rows beyond their last available row. However, you cannot make a partial video page the visual page.

    In SVGA graphics modes (modes 24 to 29), video pages must begin on 256K

boundaries to maintain compatibility between different SVGA chipsets. This results in unused video memory at the end of a page. For example, pages in mode 26 require 480,000 bytes of video memory. On a 1MB SVGA card, the two pages will begin at 0 and 524,288 (512K). Thus there are 44,288 (524,288 minus 480,000) unused video memory bytes at the end of each page. With 800 pixels (and hence 800 bytes) per screen row, this means each page has an extra 55 pixel rows per page. The actual page size is therefore 800x655, with the first 600 rows displayed. Similarly, the actual page size in mode 25 is 640x819, with the first 480 rows displayed.

    Physical pages are numbered starting at zero. For example, there are four

physical video pages available in mode 3, and they are numbered 0 to 3. Virtual pages are numbered n to 63, where n is the number of physical pages in that mode. For example, there are two physical pages (numbered 0 and 1) and 62 virtual pages (numbered 2 to 63) in mode 11. Note only modes 4 through 12 and mode 19 offer virtual pages, and the amount of conventional memory in the user's system usually limits the number of virtual pages available (this is especially true in mode 19 because of the large page size). � 150 Fastgraph User's Guide


Pages With Special Meanings

    There are three video pages that have special meanings to Fastgraph. The

visual page, as one might guess, is the video page visible on the user's display. The active page is the video page to which Fastgraph writes text or graphics information. The hidden page is meaningful only to a few Fastgraph routines and will be discussed specifically within the context of those routines. The fg_setmode routine sets all three of these pages to page 0, and it does not matter if these pages are physical or virtual.

    One of the most useful features of multiple video pages (either physical

or virtual) is the ability to build a text or graphics image off screen (that is, on some video page besides the visual page). Then, once the image is ready, we can either transfer it to the visual page, or make the page on which the image resides the visual page. This feature is especially useful in animation, for it displays an image instantaneously instead of visibly updating the screen while producing the image.


Some Simple Examples

    In this section, we'll present six variations of a simple program that

uses four video pages. The program fills each video page with a rectangle and then displays text containing the video page number in the center of each page. The first two examples run in a specific text or graphics video mode and only use physical pages. The next two examples also run in a specific text or graphics video mode, but they also use virtual pages. The final two examples are more general and run in several video modes. You could of course write a program that essentially does the same thing as the examples in this section without using multiple video pages. However, to use Fastgraph's image display and animation routines effectively, you must first understand the concept of video pages.

    Before proceeding, we must introduce the Fastgraph routines fg_setpage

and fg_setvpage. The fg_setpage routine defines the active video page, which causes Fastgraph to put subsequent text and graphics output on that page. The fg_setvpage routine defines the visual video page displayed on the screen. Both routines take a single integer argument between 0 and 63 that specifies the video page number. It does not matter if the referenced video page is a physical page or a virtual page. As mentioned earlier, fg_setmode makes page 0 the active and visual video page.

    Example 8-1 uses four video pages (numbered 0 to 3) in the 40-column

color text mode (mode 1). The program first calls fg_testmode to check the availability of the requested video mode when used with four video pages. If it is available, the program calls fg_setmode to establish that video mode. The first for loop fills each of the four pages with different color rectangles and then displays black text containing the video page number in the center of each page. It does this by calling fg_setpage to define the active video page, fg_setcolor and fg_rect to draw the colored rectangles, and finally fg_setattr, fg_locate, and fg_text to display the text. The program must call fg_locate inside the loop because each video page has its own text cursor position. The second for loop successively makes each video page the visual page; the page remains displayed until you press a key. After �

                            Chapter 8:  Video Pages and Virtual Buffers   151


displaying all four video pages, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 8-1.
               #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main(void);
               #define PAGES 4
               void main()
               {
                  int color;
                  int old_mode;
                  int page;
                  char string[8];
                  fg_initpm();
                  if (fg_testmode(1,PAGES) == 0) {
                     printf("This program requires color.\n");
                     exit(1);
                     }
                  old_mode = fg_getmode();
                  fg_setmode(1);
                  for (page = 0; page < PAGES; page++) {
                     fg_setpage(page);
                     color = page + 1;
                     fg_setcolor(color);
                     fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                     fg_setattr(0,color,0);
                     fg_locate(12,17);
                     sprintf(string,"page %d",page);
                     fg_text(string,6);
                     }
                  for (page = 0; page < PAGES; page++) {
                     fg_setvpage(page);
                     fg_waitkey();
                     }
                  fg_setmode(old_mode);
                  fg_reset();
               }


    Example 8-2 is similar to example 8-1, but it uses the 320x200 EGA

graphics mode (mode 13) instead of a text mode. Note the only real difference between this program and the text mode version is the use of fg_setcolor instead of fg_setattr to make the text appear in black.

                                Example 8-2.                                  �

152 Fastgraph User's Guide


               #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main(void);
               #define PAGES 4
               void main()
               {
                  int color;
                  int old_mode;
                  int page;
                  char string[8];
                  fg_initpm();
                  if (fg_testmode(13,PAGES) == 0) {
                     printf("This program requires a ");
                     printf("320 x 200 EGA graphics mode.\n");
                     exit(1);
                     }
                  old_mode = fg_getmode();
                  fg_setmode(13);
                  for (page = 0; page < PAGES; page++) {
                     fg_setpage(page);
                     color = page + 1;
                     fg_setcolor(color);
                     fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                     fg_setcolor(0);
                     fg_locate(12,17);
                     sprintf(string,"page %d",page);
                     fg_text(string,6);
                     }
                  for (page = 0; page < PAGES; page++) {
                     fg_setvpage(page);
                     fg_waitkey();
                     }
                  fg_setmode(old_mode);
                  fg_reset();
               }


    Virtual video pages are created with Fastgraph's fg_allocate routine. The

fg_allocate routine reserves conventional random-access memory (RAM) which Fastgraph then treats as a video page. The amount of memory required depends on the current video mode. The fg_allocate routine takes a single integer argument that specifies the page number by which the virtual page will be referenced. This value must be between 1 and 63.

    If you try to create a virtual page with a page number already assigned

to a physical page, fg_allocate does nothing. For example, in the Hercules graphics modes (modes 11 and 12) there are two physical pages numbered 0 and 1. Virtual pages in the Hercules graphics modes must thus have page numbers �

                            Chapter 8:  Video Pages and Virtual Buffers   153


between 2 and 63. If you tell fg_allocate to create a Hercules virtual page numbered 0 or 1, it does nothing because those video pages exist as physical pages. Similarly, if you use fg_allocate in a video mode that does not support virtual video pages, it simply returns without doing anything.

    A possible problem with fg_allocate can occur when there is not enough

memory available for creating a virtual page in the current video mode. The fg_allocate routine returns as its function value a status code indicating whether or not it was successful. The possible values of the status code are:

       value  meaning
         0    virtual page created
         1    specified page number is a physical page
         7    virtual page created, but memory control blocks were destroyed
         8    insufficient memory to create the virtual page

If you use fg_testmode or fg_bestmode to check if the required number of video pages are available when using the requested video mode, you should not need to monitor the status code returned by fg_allocate.

    The fg_freepage routine releases the memory for a virtual page created

with fg_allocate. It requires a single integer argument that identifies the virtual page number to release. This value must be between 0 and 63. If you try to release a physical video page, or release a virtual page that was never created, fg_freepage does nothing. It is a good idea to use fg_freepage to release all virtual video pages before a program returns control to DOS, or just before a program selects a new video mode.

    Example 8-3 is also similar to example 8-1, but it uses the monochrome

text mode (mode 7). Because the monochrome text mode only has one physical video page, we must use virtual video pages for page numbers 1, 2, and 3. Note how fg_allocate and fg_freepage are used to create and release the virtual video pages in this example.

                                Example 8-3.
            #include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
            void main(void);
            #define PAGES 4
            void main()
            {
               int old_mode;
               int page;
               char string[8];
               fg_initpm();
               if (fg_testmode(7,PAGES) == 0) {
                  printf("This program requires monochrome.\n");
                  exit(1);
                  }                                                           �

154 Fastgraph User's Guide


               old_mode = fg_getmode();
               fg_setmode(7);
               fg_cursor(0);
               for (page = 0; page < PAGES; page++) {
                  fg_allocate(page);
                  fg_setpage(page);
                  fg_setcolor(7);
                  fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                  fg_setattr(0,7,0);
                  fg_locate(12,37);
                  sprintf(string,"page %d",page);
                  fg_text(string,6);
                  }
               for (page = 0; page < PAGES; page++) {
                  fg_setvpage(page);
                  fg_waitkey();
                  fg_freepage(page);
                  }
               fg_setmode(old_mode);
               fg_reset();
            }


    Example 8-4 is similar to example 8-3, but it uses the standard Hercules

graphics mode (mode 11) instead of the monochrome text mode. Because the Hercules graphics modes have two physical video pages, we must use virtual video pages for page numbers 2 and 3. Note the only real difference between this program and the text mode version is the use of fg_setcolor instead of fg_setattr to make the text appear in black.

                                Example 8-4.
              #include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
              void main(void);
              #define PAGES 4
              void main()
              {
                 int old_mode;
                 int page;
                 char string[8];
                 fg_initpm();
                 if (fg_testmode(11,PAGES) == 0) {
                    printf("This program requires Hercules ");
                    printf("monochrome graphics.\n");
                    exit(1);
                    }
                 old_mode = fg_getmode();                                     �
                            Chapter 8:  Video Pages and Virtual Buffers   155


                 fg_setmode(11);
                 for (page = 0; page < PAGES; page++) {
                    fg_allocate(page);
                    fg_setpage(page);
                    fg_setcolor(7);
                    fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                    fg_setcolor(0);
                    fg_locate(12,37);
                    sprintf(string,"page %d",page);
                    fg_text(string,6);
                    }
                 for (page = 0; page < PAGES; page++) {
                    fg_setvpage(page);
                    fg_waitkey();
                    fg_freepage(page);
                    }
                 fg_setmode(old_mode);
                 fg_reset();
              }


    Example 8-5 is a generalized version of examples 8-1 and 8-3 that runs in

any 80-column text video mode. To simplify the program, each video page is filled with rectangles of the same color. Note that fg_allocate and fg_freepage are used to manage the virtual video pages in case fg_bestmode selects the monochrome text mode (mode 7). If fg_bestmode selects one of the 80-column color text modes (which have four physical video pages), fg_allocate and fg_freepage will simply return without doing anything.

                                Example 8-5.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                #define PAGES 4
                void main()
                {
                   int old_mode, new_mode;
                   int page;
                   char string[8];
                   fg_initpm();
                   new_mode = fg_bestmode(80,25,PAGES);
                   if (new_mode < 0) {
                      printf("This program requires ");
                      printf("an 80-column display.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();                                   �

156 Fastgraph User's Guide


                   fg_setmode(new_mode);
                   fg_cursor(0);
                   for (page = 0; page < PAGES; page++) {
                      fg_allocate(page);
                      fg_setpage(page);
                      fg_setcolor(7);
                      fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                      fg_setattr(0,7,0);
                      fg_locate(12,37);
                      sprintf(string,"page %d",page);
                      fg_text(string,6);
                      }
                   for (page = 0; page < PAGES; page++) {
                      fg_setvpage(page);
                      fg_waitkey();
                      fg_freepage(page);
                      }
                   fg_setmode(old_mode);
                   fg_reset();
                }


    Example 8-6 is a generalized version of examples 8-2 and 8-4 that runs in

any 320x200 graphics video mode. To simplify the program, each video page is filled with rectangles of the same color. As in example 8-5, fg_allocate and fg_freepage are used to manage the virtual video pages in case fg_bestmode selects a video mode with fewer than four physical video pages. Note the only real difference between this program and the text mode version is the use of fg_setcolor instead of fg_setattr to make the text appear in black.

                                Example 8-6.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                #define PAGES 4
                void main()
                {
                   int old_mode, new_mode;
                   int page;
                   char string[8];
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,PAGES);
                   if (new_mode < 0) {
                      printf("This program requires a ");
                      printf("320 x 200 graphics mode.\n");
                      exit(1);
                      }                                                       �
                            Chapter 8:  Video Pages and Virtual Buffers   157


                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   for (page = 0; page < PAGES; page++) {
                      fg_allocate(page);
                      fg_setpage(page);
                      fg_setcolor(15);
                      fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                      fg_setcolor(0);
                      fg_locate(12,17);
                      sprintf(string,"page %d",page);
                      fg_text(string,6);
                      }
                   for (page = 0; page < PAGES; page++) {
                      fg_setvpage(page);
                      fg_waitkey();
                      fg_freepage(page);
                      }
                   fg_setmode(old_mode);
                   fg_reset();
                }


Text Cursors

    As mentioned in the previous chapter, Fastgraph draws hardware characters

at the position defined by the text cursor. Like the graphics cursor, the text cursor is not a cursor in the true sense, but is simply a pair of character space (row,column) coordinates with a special meaning. The first 8 video pages (that is, pages 0 through 7) each have their own text cursor. Each subsequent group of 8 video pages (pages 8 through 15, pages 16 to 23, and so forth) respectively share the same text cursor positions as the first 8 pages. This means fg_locate will update one of 8 different text cursors depending on the active video page. Similarly, fg_where returns the text cursor position for the active page. The fg_setmode routine sets all 8 text cursor positions to the character space coordinates (0,0).

    Example 8-7 demonstrates the use of different text cursors in an 80-

column color text mode (mode 3). The program first displays the text "Page " on video page 0 (the visible page) and waits for a keystroke. It then makes page 1 the active video page, changes the text cursor location for that page, and displays the text "Page 1" on video page 1. Next, it appends the character "0" to the text originally displayed on page 0. Note that we don't need to restore the text cursor position for page 0 because it is unaffected by changing the text cursor for page 1. After waiting for another keystroke, the program makes video page 1 the visual page and then waits for yet another keystroke before returning to DOS.

                                Example 8-7.
                         #include <fastgraf.h>
                         void main(void);                                     �

158 Fastgraph User's Guide


                         void main()
                         {
                            int old_mode;
                            fg_initpm();
                            old_mode = fg_getmode();
                            fg_setmode(3);
                            fg_cursor(0);
                            fg_setattr(10,0,0);
                            fg_locate(1,0);
                            fg_text("Page ",5);
                            fg_waitkey();
                            fg_setpage(1);
                            fg_locate(23,0);
                            fg_text("Page 1",6);
                            fg_setpage(0);
                            fg_text("0",1);
                            fg_waitkey();
                            fg_setvpage(1);
                            fg_waitkey();
                            fg_setmode(old_mode);
                            fg_reset();
                         }


Obtaining Video Page Information

    Fastgraph includes two routines, fg_getpage and fg_getvpage, that

respectively return the active or visual video page number. Each routine returns the video page number as its function value, and neither routine requires any arguments.

    When creating virtual or logical pages, you must choose a page number

that does not reference a physical page or a previously created virtual or logical page. While it's of course possible to keep track of which page numbers will be available in a given video mode, Fastgraph's fg_findpage function can make the job easier. It returns an unused page number, which you can then pass to any of Fastgraph's virtual or logical page allocation routines. If there are no more available (that is, all 64 entries in the internal page tables are in use), fg_findpage returns zero.

    The fg_getaddr routine is sometimes useful when using virtual pages. It

returns as its function value the segment address (in real mode) or segment selector (in protected mode) for the start of the active video page. It does not require any arguments. Although fg_getaddr is more useful when using virtual video pages, it works equally well with physical video pages.

    Example 8-9 illustrates the use of fg_getpage, fg_getvpage, fg_findpage,

and fg_getaddr in the standard VGA/MCGA 256-color graphics mode (mode 19). This video mode offers only one physical page, so the program uses fg_findpage �

                            Chapter 8:  Video Pages and Virtual Buffers   159


to find an unused page number (which will be page 1 in mode 19), and then calls fg_allocate to create a virtual video page. After creating the virtual page, the program makes it the active video page; page 0 remains the visual video page. The fg_getpage routine then returns the active page number, followed by a call to fg_getvpage to return the visual page number (0). Next, the program uses fg_getaddr to return the segment address/selector for the two video pages. Finally, it restores the original video mode and screen attributes, displays the returned values, and returns to DOS.

                                Example 8-9.
              #include <fastgraf.h>
              #include <stdio.h>
              void main(void);
              void main()
              {
                 int old_mode;
                 int active, visual;
                 int page, page0, page1;
                 fg_initpm();
                 old_mode = fg_getmode();
                 fg_setmode(19);
                 page = fg_findpage();
                 fg_allocate(page);
                 fg_setpage(page);
                 active = fg_getpage();
                 visual = fg_getvpage();
                 fg_setpage(0);
                 page0 = fg_getaddr();
                 fg_setpage(page);
                 page1 = fg_getaddr();
                 fg_freepage(page);
                 fg_setmode(old_mode);
                 fg_reset();
                 printf("Active page is %d.\n",active);
                 printf("Visual page is %d.\n",visual);
                 printf("Page 0 address is %4X\n",page0);
                 printf("Page %d address is %4X\n",page,page1);
              }


Considerations for Virtual Pages

    If you're using Power C, any supported BASIC compiler, Borland Pascal, or

Turbo Pascal and need to create virtual pages, you must reduce the size of the far heap. Normally, these compilers allocate all remaining memory for the heap, which means fg_allocate will not be able to allocate memory for the virtual page. � 160 Fastgraph User's Guide


    In BASIC programs, the SETMEM function reduces the size of the far heap.

The BASIC versions of the Fastgraph example programs include the statement

                         SetMemStatus& = SETMEM(-n)

before calling FGallocate. This reduces the size of the far heap by n bytes. For a given video mode, the actual reduction needed is the number of virtual pages multiplied by the page size in that mode. Page sizes are listed at the beginning of this chapter, or you can use fg_pagesize to determine the page size for the current video mode.

    In Borland Pascal and Turbo Pascal, the $M compiler directive defines the

maximum heap size in bytes. The Pascal versions of the Fastgraph example programs include the statement

                             {$M 16384,0,16384}

at the beginning of the examples that call fg_allocate. The third value in this list defines the maximum heap size at 16K bytes. This is suitable for most applications, but if your program uses the New or GetMem procedures to create dynamic variables that require more heap space, you'll need to increase the size beyond 16K.

    The far heap size for Power C programs is defined at link time. You must

override the default heap size by including the option [,,16K] on the PCL command when you link a Power C program that uses fg_allocate. The value 16K is suitable for most applications, but if your program calls the farcalloc or farmalloc functions (or the calloc or malloc functions when using the large memory model), you may need to increase the far heap size beyond 16K.

    When you are using virtual pages, you should avoid using the fg_setvpage

routine in sections of the program that require fast screen updates or animation sequences. This is because the PC and PS/2 video BIOS are only capable of displaying physical pages. To compensate for this restriction, Fastgraph exchanges the contents of a physical page with the requested virtual page. In other words, if page 1 is a virtual page and you make it the visual page, Fastgraph will exchange the contents of page 1 with whatever page was previously the visual page. This does not mean Fastgraph's page numbers change because Fastgraph also maintains an internal table containing video page addresses and exchanges the two corresponding table entries. As before, you would make page 1 the active video page if you wanted to write something to the visual page.

    About the only other potential problem when using virtual pages is what

happens when you try to write to a non-existent video page (for example, if you write to virtual video page 1 before creating it with fg_allocate). In this case, Fastgraph simply redirects the video output to the visual page.


Considerations for SuperVGA Pages

    If a program running in an SVGA graphics mode returns to text mode when

the visual page is not page 0, some SVGA chipsets have problems the next time you try to run an SVGA application. We therefore recommend calling fg_setvpage(0) just before restoring the original video mode if an application performs page flipping in SVGA graphics modes. For example: �

                            Chapter 8:  Video Pages and Virtual Buffers   161


         old_mode = fg_getmode();
         fg_svgainit(0);
         fg_setmode(25);
                 .
                 .
                 .
         fg_setvpage(1);
                 .
                 .
                 .
         fg_setvpage(0);         /* add this line to be safe */
         fg_setmode(old_mode);
    A few SVGA chipsets cannot set the display start address beyond the 16-

bit capability provided by the CRT Controller, rendering fg_setvpage meaningless. Please refer to the READ.ME file for details.


Logical Pages

    In addition to physical and virtual video pages, Fastgraph offers another

class of video pages, called logical pages. You can create logical pages in any video mode. They can exist in conventional memory, expanded memory (EMS), or extended memory (XMS). However, they are not as versatile as physical or virtual pages because the only operations you can perform with logical pages are:

    * Copy an entire physical or virtual page to a logical page
    * Copy an entire logical page to a physical or virtual page
    * Copy an entire logical page to another logical page

Three Fastgraph routines -- fg_alloccms, fg_allocems, and fg_allocxms -- create logical pages in conventional memory, expanded memory, and extended memory, respectively. All three routines have a single integer argument that specifies the page number by which the logical page will be referenced. The page number must be between 1 and 63 and must not reference a physical or virtual page. Their return value is 0 if the logical page is created, and negative otherwise (refer to the descriptions of these routines in the Fastgraph Reference Manual for a complete list of return values). As with virtual pages, use fg_freepage to release a logical page.

    Before you can create logical pages in expanded or extended memory, you

must initialize these resources for use with Fastgraph. The fg_initems routine initializes expanded memory. To use expanded memory, you must have an Expanded Memory Manager (EMM) that conforms to the Lotus/Intel/Microsoft Expanded Memory Specification (LIM-EMS) version 3.2 or later. On 80386 and 80486 systems, the EMM386.EXE device driver supplied with DOS 5.0 can be used to treat some or all of extended memory as expanded memory. The fg_initxms routine initializes extended memory for use with Fastgraph. To use extended memory, you must have an XMS driver that conforms to the Lotus/Intel/Microsoft/AST eXtended Memory Specification version 2.0 or later, such as HIMEM.SYS. XMS drivers require an 80286, 80386, or 80486 system. The fg_initems and fg_initxms routines have no arguments and must be called after fg_setmode. Their return value is 0 if successful, and -1 if the required driver and resources are not present. � 162 Fastgraph User's Guide


    In protected mode, the distinction between conventional, expanded, and

extended memory disappears because DOS extenders essentially treat all system memory as conventional memory. For this reason, fg_initems and fg_initxms are not meaningful and thus always return -1 in the protected mode Fastgraph libraries. This effectively disables the fg_allocems and fg_allocxms routines, so you must create logical pages with fg_alloccms in protected mode.

    Example 8-10 illustrates the use of logical pages in a 320x200 color

graphics mode. The program first tries to create a logical page in extended memory by calling fg_initxms and fg_allocxms. If the initialization or page creation fails, it then tries to create the page in expanded memory with fg_initems and fg_allocems. Should that fail, the program calls fg_alloccms to try to create the page in conventional memory. If it can't create the logical page at all, the program displays an error message and exits.

    Once the logical page is created, example 8-10 displays the word "test"

in the middle of the visual page (page 0) and then uses fg_copypage to transfer the visual page contents to the logical page. Because this program runs in one of several different graphics modes, we use fg_findpage to choose the logical page number. After waiting for a keystroke, the program erases the visual page, waits for another keystroke, and copies the logical page contents back to the visual page. It then releases the logical page and exits.

                                Example 8-10.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             void main()
             {
                int new_mode, old_mode;
                int page, status;
                fg_initpm();
                new_mode = fg_bestmode(320,200,1);
                if (new_mode < 0 || new_mode == 12) {
                   printf("This program requires a 320 ");
                   printf("x 200 color graphics mode.\n");
                   exit(1);
                   }
                old_mode = fg_getmode();
                fg_setmode(new_mode);
                page = fg_findpage();
                status = fg_initxms();
                if (status == 0) status = fg_allocxms(page);
                if (status < 0) {
                   status = fg_initems();
                   if (status == 0) status = fg_allocems(page);
                   }
                if (status < 0) status = fg_alloccms(page);
                if (status < 0) {                                             �
                            Chapter 8:  Video Pages and Virtual Buffers   163


                   fg_setmode(old_mode);
                   fg_reset();
                   printf("Unable to create logical page.\n");
                   exit(1);
                   }
                fg_setcolor(7);
                fg_rect(0,319,0,199);
                fg_setcolor(9);
                fg_locate(12,18);
                fg_text("test",4);
                fg_waitkey();
                fg_copypage(0,page);
                fg_erase();
                fg_waitkey();
                fg_copypage(page,0);
                fg_waitkey();
                fg_freepage(page);
                fg_setmode(old_mode);
                fg_reset();
             }
    As mentioned before, the only functions you can perform with logical

pages are copying physical/virtual pages to logical pages, logical pages to physical/virtual pages, or copying one logical page to another. The fg_copypage routine provides the only way to do this for logical pages. See Chapter 11 for more information about fg_copypage.


Extended Video Pages

    One of the more frequent technical support questions we receive is "I

have one megabyte of memory on my video card, why can I only use the first 256K?". The answer is simple: the standard EGA and VGA graphics modes have no way to address video memory beyond 256K. Accessing more memory requires SVGA bank switching techniques. This is analogous to the fact that you might have four megabytes of RAM on your system, but without an EMS/XMS memory manager, a DOS extender, or the like, all that memory won't do much good.

    Unfortunately, not all SVGA chipsets allow bank switching in non-SVGA

video modes. For those that do, however, Fastgraph includes a feature called extended video pages. Extended pages provide access to all video memory in modes 13 to 18 and modes 20 to 23 instead of restricting access to the first 256K. This means, for example, that a 1MB SVGA card will allow 32 physical pages in mode 13 rather than the usual 8 pages. Extended pages are available with the following SVGA chipsets:

    * Ahead B
    * Avance Logic 2000 series
    * ATI 28800/mach32/mach64
    * Avance Logic 2000 series
    * NCR 77C22/77C32
    * Oak OTI-067                                                             �

164 Fastgraph User's Guide


    * Oak OTI-077
    * Oak OTI-087
    * Paradise WD90C11/WD90C30/WD90C31/WD90C33
    * Tseng ET4000
    Although extended pages are used in non-SVGA graphics modes, the method

of accessing video memory above 256K is specific to each SVGA chipset. Thus, you must initialize Fastgraph's SVGA kernel (with fg_svgainit) before you can use extended pages. We haven't yet found a VESA implementation that supports extended pages, so you'll need to initialize the SVGA kernel for chipset- specific support.

    When writing applications that use extended video pages, you should make

sure the user's SVGA chipset supports extended pages and that there is enough video memory for the number of pages required. First, make sure fg_svgainit successfully initializes the SVGA kernel. If so, check bit 2 of the fg_svgastat return value to see if the chipset supports extended pages. Finally, use fg_memory to insure that enough video memory is available for the number of video pages needed.

    The following table shows the number of video pages available in the

graphics modes that support extended pages.

                                  Number of Pages With
                             Mode    256K 512K  1MB
                              13      8    16    32
                              14      4     8    16
                              15      2     4    8
                              16      2     4    8
                              17      2     4    8
                              18      2     4    8
                              20      4     8    16
                              21      2     4    8
                              22      4     8    16
                              23      2     4    8

Note that when extended pages are not enabled, the video mode has the number of physical video pages listed in the 256K column.

    Some video modes do not provide the listed number of full video pages.

For example, modes 17 and 18 normally have two video pages -- one full 640x480 page (page 0) and one partial 640x320 page (page 1). For extended pages, Fastgraph uses a page numbering scheme that maintains consistency with its standard page numbering. That is, when extended pages are available and mode 17 or 18 is used on a 1MB video card, the page numbers will range from 0 to 7, with the even-numbered pages being full pages and the odd-numbered pages being partial 640x320 pages. Similarly, in mode 22 pages 3, 7, 11, and 15 are partial (320x80); in mode 23 odd-numbered pages are partial (320x320).

    When you use Fastgraph's block transfer routines (fg_copypage,

fg_restore, fg_save, fg_tcxfer, and fg_transfer) with extended pages, you must pass the source and destination page numbers to fg_defpages. This is needed because the two pages may reside in different SVGA banks, and bank switching is not performed in Fastgraph's non-SVGA code. The additional overhead of having the block transfer routines determine the bank numbers would impact the �

                            Chapter 8:  Video Pages and Virtual Buffers   165


block transfer routines when extended pages are not being used. The fg_defpages routine determines the SVGA bank numbers in which the source and destination pages reside and then enables the corresponding banks for reading and writing. These banks remain in effect until you define new ones with fg_defpages or fg_setpage, so you may not need to call fg_defpages before every call to a block transfer routine. The fg_defpages routine has no effect unless extended pages are enabled. The following table shows the bank numbers for each video page in each graphics mode that supports extended pages.

                               Bank 0 Bank 1 Bank 2 Bank 3
                          Mode Pages  Pages  Pages  Pages
                           13   0-7    8-15  16-23  24-31
                           14   0-3    4-7    8-11  12-15
                           15   0-1    2-3    4-5    6-7
                           16   0-1    2-3    4-5    6-7
                           17   0-1    2-3    4-5    6-7
                           18   0-1    2-3    4-5    6-7
                           20   0-3    4-7    8-11  12-15
                           21   0-1    2-3    4-5    6-7
                           22   0-3    4-7    8-11  12-15
                           23   0-1    2-3    4-5    6-7
    Next we'll present a short code sequence that calls fg_defpages only when

needed in mode 13, where each group of 8 pages resides in its own SVGA bank. Calling fg_setmode enables bank 0 for reading and writing, so we don't need to call fg_defpages until we reference a page in one of the other banks (that is, a page numbered 8 or above).

    fg_svgainit(0);
    fg_setmode(13);     /* enables bank 0 for reading and writing */
    fg_copypage(0,1);
    fg_copypage(0,2);
    fg_defpages(0,1);   /* page 10 is in bank 1 */
    fg_copypage(2,10);
    fg_defpages(1,1);   /* page 15 is in bank 1 */
    fg_copypage(10,15);
    fg_setpage(0);      /* enables bank 0 for reading and writing */
    fg_erase();
    fg_copypage(0,3);
    fg_defpages(1,0);   /* page 15 is in bank 1 */
    fg_copypage(15,4);
    Most mouse drivers know nothing about SVGA bank switching and non-

standard video modes (that's why Fastgraph must hook its own mouse cursor control handlers into the mouse driver in XVGA and SVGA modes). As Fastgraph relies on the mouse driver for cursor control in modes 13 to 18, it's only possible to display the mouse cursor on video pages in the first SVGA bank (bank 0) in these modes. Note that this does not apply to modes 20 to 23, where Fastgraph controls the mouse cursor through its own handler.

    Some SVGA chipsets do not reset the read and write bank numbers back to

zero when establishing a non-SVGA video mode. When a mode set operation clears video memory, such chipsets will clear the first video page in the last write bank selected. While fg_setmode does set the read and write banks to zero when extended pages are available, it cannot do this before setting the video mode, � 166 Fastgraph User's Guide


which is what normally would clear the screen. This may result in artifacts on page 0 after calling fg_setmode. The easiest way around this problem is to call fg_defpages(0,0) before restoring the original video mode in programs that use extended pages. Even this, however, does not clear video memory after a mode set when using extended pages with some SVGA chipsets. We therefore recommend calling fg_erase immediately after restoring the original video mode when using extended pages.


Video Page Resizing

    Resizing is the process of changing the dimensions of a video page. It is

available only in the native EGA graphics modes (modes 13 to 16), native VGA graphics modes (17 and 18), extended VGA modes (20 to 23), and SVGA modes (24 to 29). Resizing does not change the screen resolution, but instead increases the video page size so only part of the page is visible. For now, we'll just introduce resizing with a simple example, but in Chapter 13 we'll see its real power when we perform smooth panning.

    The Fastgraph routine fg_resize changes the dimensions of a video page.

Its two integer arguments define the page width and page height, both in pixels. Example 8-11 runs in the 320x200 EGA graphics mode (mode 13). After establishing the video mode, it displays the word "resize" starting in column 38 of row 0. Because the characters extend beyond the last column of the row, they wrap to the next row. The program continues displaying this until you press a key. Then, it clears the screen and calls fg_resize to make the page size 640x200 pixels. Again the program displays the word "resize" starting in column 38 of row 0, but this time it does not wrap to the next row. This is because the resizing doubled the page width, which increased the number of character cells per row from 40 to 80. The characters that formerly wrapped to the next row now continue on an off-screen portion of the same row.

                                Example 8-11.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int old_mode;
                   fg_initpm();
                   if (fg_testmode(13,1) == 0) {
                      printf("This program requires a 320 ");
                      printf("x 200 EGA graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(13);
                   fg_setcolor(9);
                   fg_locate(0,38);
                   fg_text("resize",6);                                       �
                            Chapter 8:  Video Pages and Virtual Buffers   167


                   fg_waitkey();
                   fg_erase();
                   fg_resize(640,200);
                   fg_setcolor(10);
                   fg_locate(0,38);
                   fg_text("resize",6);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    The size of a video page is constrained only by the amount of video

memory available and the addressability of the video mode. Increasing the video page size reduces the number of physical pages available proportionally. In mode 13, for example, increasing the page size from 320x200 to 640x400 reduces the number of video pages from 8 to 2. When you call fg_resize, the visual page must be page 0. If you have created any logical video pages, you must release them with fg_freepage before calling fg_resize, and then create them again afterward. If you have initialized the mouse (with fg_mouseini), joysticks (with fg_initjoy), expanded memory (with fg_initems), or extended memory (with fg_initxms), you should re-initialize these resources after calling fg_resize. In modes 13 to 18, most mouse drivers expect a fixed video page width, so the mouse cursor may become distorted after resizing video pages in these modes. When you call fg_resize, Fastgraph sets the clipping region to the new page limits. The fg_setmode routine re-establishes the dimensions of a video page to the default screen resolution for the selected video mode. The fg_resize routine has no effect when a virtual buffer is active.

     Depending on the dimensions passed to fg_resize, you may end up with a

partial video page. Again, suppose we're using mode 13 and have changed the page size to 960x400 (this is six times the default page size). The original pages 0 to 5 now make up page 0, and original pages 6 and 7 now make up page 1. However, there is not enough video memory left on page 1 for a full 960x400 page. In this case, the number of pixel rows available on page 1 would be one- third the full page size, or 133 rows. This is because the total storage required by original pages 6 and 7 is one-third the total required for original pages 0 through 5.

    Extended video pages may be resized in modes 13-18 and 20-23, but the

resulting pages must not cross SVGA bank boundaries. In mode 20, for instance, you normally have four 320x200 pages in each bank. You could change the video page size to 640x400, thereby having four larger pages, one in each bank. You could not, however, resize video memory to two 640x800 pages, as each page would span two banks.


Preserving Video Page Contents Across Mode Switches

    Sometimes a graphics program may temporarily need to switch to another

video mode. An example of this might be a graphical user interface (GUI) menuing system that includes "shell to DOS" as one of its options. When the user selects this option, the program must revert to a text video mode so the � 168 Fastgraph User's Guide


user will see the familiar DOS prompt when the shell executes. On leaving the DOS shell, the program returns to a graphics mode and should ideally restore the screen to what it was originally.

    When you establish a video mode with fg_setmode, Fastgraph clears all

physical video pages and initializes its internal page tables as if no virtual or logical pages have been created. While it's not possible to preserve physical page contents across video mode switches, you can use Fastgraph's fg_getentry and fg_setentry routines to save virtual or logical page contents. The trick, so to speak, is using fg_getentry to save the virtual or logical page address and type before switching video modes. Then, when you return to the same video mode, you can use fg_setentry to restore the internal page tables to their previous state. This effectively makes the virtual or logical page accessible again.

    Example 8-12 illustrates this process. This program runs in video mode

18, the 640x480 16-color VGA graphics mode. After establishing this video mode, the program calls fg_alloccms to create a logical page in conventional memory. Next, it calls fg_getentry to save the address and type of the logical page just created. The first argument to fg_getentry specifies the page number (determined by fg_findpage); the next two arguments receive the page address and type. Page type codes used by fg_getentry and fg_setentry are:

    0 = unallocated page
    1 = physical page
    2 = virtual page
    3 = logical page in expanded memory (EMS)
    4 = logical page in extended memory (XMS)
    5 = logical page in conventional memory
    After this setup work, example 8-12 fills the screen with light blue

pixels, draws a white box around the edge, and then waits for a keystroke. Before switching back to the original video mode (assumed to be mode 3), the program uses fg_copypage to copy the visual page contents to the logical page. This is necessary because we can only save virtual or logical page contents across video mode changes, not physical pages. In mode 3, the program prompts for a keystroke before returning to mode 18.

    Now we're ready to restore the previous contents of the visual page.

Because the example program did not release the logical page, the memory is still allocated; Fastgraph just cannot access it. To solve this, the program calls fg_setentry to restore Fastgraph's internal page table entries for the original logical page number to what they were previously. Note how we use the same page address and type values in the call to fg_setentry that were returned earlier by fg_getentry. Now that the logical page is once again accessible, the program can use fg_copypage to copy its contents back to the visual page. With that explanation behind us, here is example 8-12.

                                Example 8-12.
                 #include <fastgraf.h>
                 void main(void);
                 void main()
                 {
                    int old_mode;                                             �
                            Chapter 8:  Video Pages and Virtual Buffers   169


                    int page, page_addr, page_type;
                    fg_initpm();
                    old_mode = fg_getmode();
                    fg_setmode(18);
                    page = fg_findpage();
                    fg_alloccms(page);
                    fg_getentry(page,&page_addr,&page_type);
                    fg_setcolor(9);
                    fg_fillpage();
                    fg_setcolor(15);
                    fg_box(0,639,0,479);
                    fg_waitkey();
                    fg_copypage(0,page);
                    fg_setmode(old_mode);
                    fg_cursor(0);
                    fg_setcolor(15);
                    fg_text("Press any key.",14);
                    fg_waitkey();
                    fg_setmode(18);
                    fg_setentry(page,page_addr,page_type);
                    fg_copypage(page,0);
                    fg_waitkey();
                    fg_freepage(page);
                    fg_setmode(old_mode);
                    fg_reset();
                 }


    To keep the example as simple as possible, it does not test for

availability of video modes, nor does it check if the logical page creation was successful. In a real application, of course, omitting these checks is not recommended. See example 8-17 for a version of this program that uses virtual buffers instead of logical pages.


Controlling Page Allocation

    When Fastgraph creates virtual or logical pages in conventional memory

with fg_allocate or fg_alloccms, it uses the DOS allocate memory service (function 48 hex of interrupt 21 hex). Some compilers allocate all or part of available conventional memory to a data structure called the heap or far heap. Memory allocation functions such as malloc handle their requests through an associated heap manager instead of through DOS services. If the heap manager controls all available memory, the DOS allocate memory service is essentially disabled because there will be no memory available to satisfy allocation requests. If the heap manager controls some but not all available memory, a conflict may arise between the heap manager and the DOS allocate memory service.

    To solve this problem, you can use the compiler's allocate far memory

function to reserve memory for the virtual or logical page and then make the � 170 Fastgraph User's Guide


page known to Fastgraph with fg_setentry. The easiest way to determine the amount of memory to allocate is through the fg_pagesize function, which returns the page size in bytes (as a long integer) for the current video mode. To release the page, use fg_setentry with a page type of zero to mark the page as unallocated before actually freeing the memory. Pages created this way are not initially cleared because the allocated memory block contents are undefined. We recommend using fg_erase to set the page contents to the background color.

    Example 8-13 shows how to create a virtual page in real mode programs

using these techniques instead of fg_allocate. It uses the farmalloc and farfree functions from the C run-time library for Borland compilers (the analogous Microsoft functions are _fmalloc and _ffree). Example 8-13 uses fg_pagesize and the Borland run-time library function farmalloc to create a virtual page in the 320x200 VGA/MCGA 256-color graphics mode. After allocating the memory, the program calls fg_setentry, passing it the page number (1), the segment portion of the memory block address (using the FP_SEG macro from the run-time library), and the code for a virtual page (2). Once the virtual page is set up, the program writes some text on the virtual page and then uses fg_copypage to display the virtual page contents on the visual page. Finally, it releases the page by calling fg_setentry (so Fastgraph knows the virtual page is gone) and the farfree run-time library function (to actually free the memory). The call to fg_setentry is not really needed in this instance because no further references are made to page 1.

                                Example 8-13.
           #include <fastgraf.h>
           #include <dos.h>
           #ifdef __TURBOC__
           #include <alloc.h>
           #else
           #include <malloc.h>
           #define  farfree(p)   _ffree(p)
           #define  farmalloc(n) _fmalloc(n)
           #endif
           void main(void);
           void main()
           {
              int old_mode;
              unsigned page_addr;
              char far *buffer;
              old_mode = fg_getmode();
              fg_setmode(19);
              buffer = farmalloc(fg_pagesize()+16);
              page_addr = FP_SEG(buffer) + (FP_OFF(buffer)+15)/16;
              fg_setentry(1,page_addr,2);
              fg_setpage(1);
              fg_erase();
              fg_setcolor(9);
              fg_text("This is page 1.",15);
              fg_waitkey();                                                   �
                            Chapter 8:  Video Pages and Virtual Buffers   171


              fg_copypage(1,0);
              fg_setentry(1,0,0);
              fg_waitkey();
              farfree(buffer);
              fg_setmode(old_mode);
              fg_reset();
           }


Virtual Buffers

    Virtual buffers are blocks of conventional memory that you can treat as

video memory. They are much more general than virtual pages, as they are supported in all graphics video modes and can be smaller or larger than the actual page size. An application may have up to 32 virtual buffers open simultaneously. Each virtual buffer has its own independent clipping limits, which default to the entire virtual buffer. Any program that uses virtual buffers must initialize the virtual buffer environment by calling fg_vbinit once, before it calls any of Fastgraph's other virtual buffer routines. The fg_vbinit routine has no arguments and no return value.

    In protected mode, and when using real mode compilers that support huge

arrays (far arrays whose size may exceed 64K), use fg_vbdefine to create virtual buffers. The fg_vbdefine routine defines a block of previously allocated memory as a virtual buffer. Usually this memory is allocated dynamically with the malloc or farmalloc functions in C or C++, the GlobalAllocPtr function in protected mode Pascal, or the ALLOCATE statement in protected mode FORTRAN. The fg_vbdefine routine returns a handle by which the virtual buffer is referenced in other Fastgraph routines. Two related virtual buffer routines are fg_vbundef, which releases a virtual buffer handle, and fg_vbhandle, which returns the active virtual buffer handle (or -1 if no virtual buffer is active).

    The number of bytes required for a virtual buffer is simply its width in

pixels multiplied by its height in pixels, regardless of the current video mode. The virtual buffer layout is equally simple. For instance, a 320x200 virtual buffer requires 64,000 bytes. The first 320 bytes represent the first row of the virtual buffer, the next 320 bytes represent the second row, and so forth. Within each of the 200 such rows, each of the 320 bytes represents one pixel. This means, for example, the (0,0) pixel in the virtual buffer would be at offset 0, the (2,0) pixel would be at offset 2, and the (2,1) pixel would be at offset 322. In general, the offset of the (x,y) pixel is given by the formula y*virtual_buffer_width + x.

    The method of dynamically allocating memory suitable for virtual buffers

is compiler and environment dependent. When using 32-bit protected mode, the virtual buffer memory resides in the program's default data segment and is referenced through a standard near pointer. In 16-bit environments, the virtual buffer memory is a huge array and is referenced through a far pointer. The following examples illustrate how to allocate memory for a 640x400 virtual buffer for each compiler that supports dynamic allocation of huge memory blocks. � 172 Fastgraph User's Guide


For Borland C++ (16-bit), Turbo C++, Turbo C:

    char huge *buffer;
    buffer = (char huge *)farmalloc(640L*400L);

For Microsoft C/C++, QuickC, Visual C++, 16-bit WATCOM C/C++:

    char huge *buffer;
    buffer = (char huge *)halloc(640L*400L,1);

For 32-bit C/C++ compilers:

    char *buffer;
    buffer = (char *)malloc(640*400);

For Borland Pascal 7 (protected mode):

    var buffer : pointer;
    buffer := GlobalAllocPtr(gmem_Fixed,Longint(640)*Longint(400));

For Microsoft FORTRAN PowerStation:

    INTEGER*1 BUFFER[ALLOCATABLE](:)
    INTEGER STATUS
    ALLOCATE(BUFFER(640*400),STAT=STATUS)
    Real mode BASIC, Pascal, and FORTRAN compilers have limited, if any,

support for huge arrays. In these environments, use fg_vballoc to create virtual buffers. The fg_vballoc routine uses the DOS allocate memory service to reserve virtual buffer memory. The supported BASIC compilers and real mode Turbo Pascal normally assign all unused conventional memory to an area called the far heap. At best, this will cause DOS memory allocation requests to fail, but more often it creates memory conflicts that manifest themselves later in your application. To solve this problem, you must tell the compiler to reduce the size of the far heap.

    Real mode Pascal programmers must use the $M directive to reduce the far

heap size by the total space needed for all virtual buffers. If you wanted to use a 640x400 virtual buffer, for example, the following $M directive would reduce the far heap size by 256,000 bytes:

                             {$M 16384,0,256000}
    BASIC programmers must use the SETMEM function to reduce the far heap

size by the total space needed for all virtual buffers, plus 16 bytes per virtual buffer. If you wanted to use a 640x400 virtual buffer in a BASIC program, the following SETMEM call would reduce the far heap size by 256,016 bytes:

                       SetMemStatus& = SETMEM(-256016)
    After you're finished with a virtual buffer, its memory may be released

using fg_vbfree. You should use fg_vbfree only with virtual buffers created with fg_vballoc and not those created with fg_vbdefine, and you cannot use it on the active virtual buffer. As fg_vballoc and fg_vbfree are needed for real mode only, they are not present in the Fastgraph protected mode libraries. For �

                            Chapter 8:  Video Pages and Virtual Buffers   173


virtual buffers created with fg_vbdefine, just use your compiler's standard method for releasing dynamic memory blocks.

    Once a virtual buffer is defined, you can activate it with fg_vbopen.

When a virtual buffer is active, most Fastgraph routines operate on that virtual buffer instead of video memory. This will continue until you call fg_vbclose, which redirects graphics operations back to the active video page. If you later want to activate the virtual buffer again, or if you want to switch to another virtual buffer previously created with fg_vbdefine, you can use fg_vbopen for this purpose.

    Two of Fastgraph's more important virtual buffer routines are fg_vbpaste

and fg_vbcut. These routines move rectangular areas between the active virtual buffer and the active video page. The fg_vbcut routine copies an area from the active video page to the active virtual buffer. Similarly, fg_vbpaste copies an area from the active virtual buffer to the active video page. An especially useful property of fg_vbcut and fg_vbpaste is that they each remember the most recent active virtual buffer and video page. This feature makes it possible to move areas back and forth between a virtual buffer and video memory without continuously opening and closing the virtual buffer.

    The fg_vbpaste routine performs a simple translation for pixel values

greater than the number of colors available in the current video mode. This could happen, for example, if you used fg_vbcut in a 256-color graphics mode and later used fg_vbpaste to display the virtual buffer contents in a 16-color graphics mode. Should this occur, fg_vbpaste will display pixels of color c in color c modulo n, where n is the number of colors available in the current video mode.

    At this point, some example programs should help clarify the use of

virtual buffers. Our first example, 8-14, runs in the standard VGA/MCGA 320x200 256-color graphics mode (mode 19) and creates a virtual buffer twice as high and twice as wide as the screen size. This means we'll create a 640x400 virtual buffer requiring 256,000 bytes of conventional memory (conditional compilation sequences show how to allocate the virtual buffer memory for different compilers). If the virtual buffer was created successfully, the program calls fg_vbopen to activate the virtual buffer and then draws four 320x200 rectangles of different colors, one in each quadrant of the virtual buffer. It then uses fg_vbpaste to copy each rectangle to the active video page, followed by another call to show the center 320x200 portion of the virtual buffer (this will display equal parts of the four rectangles).

                                Example 8-14.
      #include <fastgraf.h>
      #include <stdio.h>
      #include <stdlib.h>
      #ifdef __TURBOC__
      #include <alloc.h>
      #else
      #include <malloc.h>
      #endif
      #define WIDTH  640
      #define HEIGHT 400                                                      �

174 Fastgraph User's Guide


      void main(void);
      void main()
      {
         int handle;
         int old_mode;
      #ifdef FG32
         char *buffer;
      #else
         char huge *buffer;
      #endif
         /* initialize the video environment */
         fg_initpm();
         old_mode = fg_getmode();
         fg_setmode(19);
         fg_vbinit();
         /* set up a 640x400 virtual buffer */
      #ifdef FG32
         buffer = (char *)malloc(WIDTH*HEIGHT);
      #elif defined(__TURBOC__)
         buffer = (char huge *)farmalloc((long)WIDTH*(long)HEIGHT);
      #else
         buffer = (char huge *)halloc((long)WIDTH*(long)HEIGHT,1);
      #endif
         if (buffer == NULL) {
            fg_setmode(old_mode);
            fg_reset();
            printf("Could not create the virtual buffer.\n");
            exit(1);
            }
         handle = fg_vbdefine(buffer,WIDTH,HEIGHT);
         fg_vbopen(handle);
         /* draw a 320x200 rectangle in each virtual buffer quadrant */
         fg_setcolor(9);
         fg_rect(0,319,0,199);
         fg_setcolor(10);
         fg_rect(320,639,0,199);
         fg_setcolor(11);
         fg_rect(0,319,200,399);
         fg_setcolor(12);
         fg_rect(320,639,200,399);
         /* paste each rectangle to the 320x200 active video page */
         fg_vbpaste(0,319,0,199,0,199);
         fg_waitkey();
         fg_vbpaste(320,639,0,199,0,199);
         fg_waitkey();
         fg_vbpaste(0,319,200,399,0,199);
         fg_waitkey();                                                        �
                            Chapter 8:  Video Pages and Virtual Buffers   175


         fg_vbpaste(320,639,200,399,0,199);
         fg_waitkey();
         /* paste the center 320x200 subset of the virtual buffer */
         fg_vbpaste(160,479,100,299,0,199);
         fg_waitkey();
         /* close the virtual buffer */
         fg_vbclose();
         /* restore original video mode and exit */
         fg_setmode(old_mode);
         fg_reset();
      }


    Calling fg_vbclose before the final fg_setmode call is necessary because

fg_setmode has no effect when a virtual buffer is active. If we didn't call fg_vbclose, the program would return to DOS in mode 19 instead of the original video mode.

    If you instead wanted to allocate the virtual buffer memory with

fg_vballoc in example 8-14, the steps to create the virtual buffer would change as follows:

 /* set up a 640x400 virtual buffer */
 handle = fg_vballoc(WIDTH,HEIGHT);
 if (handle < 0) {
    fg_setmode(old_mode);
    fg_reset();
    printf("Could not create the virtual buffer.\n");
    exit(1);
    }
 fg_vbopen(handle);

If you create the virtual buffer with fg_vballoc, you also should use fg_vbfree to release the virtual buffer memory when it's no longer needed:

 /* close the virtual buffer */
 fg_vbclose();
 fg_vbfree(handle);

Again, we recommend using fg_vballoc and fg_vbfree only with 16-bit compilers that do not provide easy methods for creating huge arrays.

    Example 8-15 illustrates the use of the fg_vbcut routine, which

essentially performs the inverse operation of fg_vbpaste. That is, fg_vbcut copies a rectangular area from the active video page to the active virtual buffer. The program begins by drawing a 20x20 blue rectangle with a white border in the upper left corner of the active video page. After a keystroke, it sets up a 20x20 virtual buffer and calls fg_vbcut to copy the rectangle to � 176 Fastgraph User's Guide


the virtual buffer. The program then calls fg_vbpaste in a loop to display 16 copies of the virtual buffer contents across the bottom of the screen. Note that example 8-15 uses a virtual buffer that is just 20 pixels square, or 400 bytes total. Because it is so small, we chose to declare a 400-byte array for the virtual buffer instead of allocating its memory dynamically as in the previous example. Note also that because the virtual buffer array size is less than 64K bytes, we can declare it far instead of huge in 16-bit environments (huge arrays less than 64K are functionally equivalent to far arrays).

                                Example 8-15.
                #include <fastgraf.h>
                #define WIDTH  20
                #define HEIGHT 20
                void main(void);
                #ifdef FG32
                char buffer[WIDTH*HEIGHT];
                #else
                char far buffer[WIDTH*HEIGHT];
                #endif
                void main()
                {
                   int handle;
                   int old_mode;
                   int x;
                   fg_initpm();
                   old_mode = fg_getmode();
                   fg_setmode(19);
                   fg_vbinit();
                   fg_setcolor(15);
                   fg_rect(0,WIDTH-1,0,HEIGHT-1);
                   fg_setcolor(9);
                   fg_rect(1,WIDTH-2,1,HEIGHT-2);
                   fg_waitkey();
                   handle = fg_vbdefine(buffer,WIDTH,HEIGHT);
                   fg_vbopen(handle);
                   fg_vbcut(0,WIDTH-1,0,HEIGHT-1,0,HEIGHT-1);
                   for (x = 0; x <= 320-WIDTH; x += WIDTH)
                      fg_vbpaste(0,WIDTH-1,0,HEIGHT-1,x,199);
                   fg_waitkey();
                   fg_vbclose();
                   fg_setmode(old_mode);
                   fg_reset();
                }                                                             �
                            Chapter 8:  Video Pages and Virtual Buffers   177


    If you create a virtual buffer that is taller or wider than the page size

(or perhaps both taller and wider), it's possible to perform virtual buffer scrolling. To achieve a scrolling effect, you generally just call fg_vbpaste iteratively such that the source region in the virtual buffer increments gradually, while the destination region on the active video page stays the same. Depending on the video mode and the size of the scrolling region, you may need to include a delay factor between fg_vbpaste calls so the area being scrolled doesn't appear to jump immediately to its ultimate destination.

    Example 8-16 performs virtual buffer scrolling. This example runs in the

XVGA 320x200 256-color graphics mode (mode 20) and creates a 1000x50 virtual buffer using the method of example 8-14. The program fills the virtual buffer with a series of one-pixel wide rectangles, each 50 pixels high and in alternating colors. The actual scrolling takes place in the loop containing the two fg_vbpaste calls. We'll define a 100x50 area in the middle of the visual page, with horizontal extremes between 110 and 209, and vertical extremes between 75 and 124, as our scrolling region. We'll scroll the top half (25 pixels) of the virtual buffer from right to left while scrolling the bottom half from left to right. In other words, we'll be moving two 100x25 subsets of the virtual buffer through the scrolling region.

    The first fg_vbpaste call scrolls the top half of the virtual buffer. The

starting x coordinate defining the region to transfer from the virtual buffer ranges from 0 to 900 in one-pixel increments, and the width of the transfer region is always 100 pixels. The height of the transfer region remains constant at 25 pixels (virtual buffer rows 0 to 24). The destination position is the upper half of the scrolling region on the visual page; its lower left corner is at x=110 and y=99.

    The second fg_vbpaste call, which scrolls the bottom half of the virtual

buffer but in the opposite direction, behaves similarly. In this case, the starting x coordinate in the virtual buffer decreases from 900 to 0 in one- pixel steps, and its width is always 100 pixels. The height of the transfer region is again 25 pixels, but this time it uses rows 25 to 49 in the virtual buffer. The destination position is the lower half of the scrolling region on the visual page; its lower left corner is at x=110 and y=124.

                                Example 8-16.
     #include <fastgraf.h>
     #include <stdio.h>
     #include <stdlib.h>
     #ifdef __TURBOC__
     #include <alloc.h>
     #else
     #include <malloc.h>
     #endif
     #define WIDTH  1000
     #define HEIGHT   50
     void main(void);
     void main()
     {
        int handle;                                                           �

178 Fastgraph User's Guide


        int old_mode;
        int x;
     #ifdef FG32
        char *buffer;
     #else
        char huge *buffer;
     #endif
        /* initialize the video environment */
        fg_initpm();
        old_mode = fg_getmode();
        fg_setmode(20);
        fg_vbinit();
        /* fill the screen with light blue pixels */
        fg_setcolor(9);
        fg_fillpage();
        /* set up the virtual buffer */
     #ifdef FG32
        buffer = (char *)malloc(WIDTH*HEIGHT);
     #elif defined(__TURBOC__)
        buffer = (char huge *)farmalloc((long)WIDTH*(long)HEIGHT);
     #else
        buffer = (char huge *)halloc((long)WIDTH*(long)HEIGHT,1);
     #endif
        if (buffer == NULL) {
           fg_setmode(old_mode);
           fg_reset();
           printf("Could not create the virtual buffer.\n");
           exit(1);
           }
        handle = fg_vbdefine(buffer,WIDTH,HEIGHT);
        fg_vbopen(handle);
        /* fill the virtual buffer with a series of narrow rectangles */
        for (x = 0; x < WIDTH; x++) {
           fg_setcolor(x);
           fg_rect(x,x,0,HEIGHT-1);
           }
        /* scroll the virtual buffer through a 100x50 window on the */
        /* visual page, such that the top half scrolls left and the */
        /* bottom half scrolls right */
        for (x = 0; x < WIDTH-99; x++) {
           fg_vbpaste(x,x+99,0,24,110,99);
           fg_vbpaste(WIDTH-100-x,WIDTH-1-x,25,49,110,124);
           }
        fg_waitkey();
        /* close the virtual buffer */                                        �
                            Chapter 8:  Video Pages and Virtual Buffers   179


        fg_vbclose();
        /* restore original video mode and exit */
        fg_setmode(old_mode);
        fg_reset();
     }


    The last virtual buffer example program we'll present in this chapter is

a version of example 8-12 modified to work with virtual buffers. Example 8-12 used a logical page in conventional memory to preserve the visual page contents across video mode switches, with some help from Fastgraph's fg_getentry and fg_setentry routines. Example 8-17 illustrates how you can accomplish the same thing with a virtual buffer. It runs in the 320x240 256- color graphics mode (mode 22) and uses a virtual buffer whose size is identical to the screen resolution. After creating the virtual buffer, the program fills the visual page with blue pixels and draws a white border around it. It then uses fg_vbcut to copy the screen contents to the virtual buffer. Like example 8-12, the program temporarily switches back to the original video mode and waits for a keystroke. It then reverts to mode 22 and uses fg_vbpaste to restore the screen contents.

                                Example 8-17.
           #include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
           #ifdef __TURBOC__
           #include <alloc.h>
           #else
           #include <malloc.h>
           #endif
           void main(void);
           void main()
           {
              int handle;
              int old_mode;
           #ifdef FG32
              char *buffer;
           #else
              char huge *buffer;
           #endif
              fg_initpm();
              old_mode = fg_getmode();
              fg_setmode(22);
              fg_vbinit();
           #ifdef FG32
              buffer = (char *)malloc(320*240);
           #elif defined(__TURBOC__)
              buffer = (char huge *)farmalloc(320L*240L);                     �

180 Fastgraph User's Guide


           #else
              buffer = (char huge *)halloc(320L*240L,1);
           #endif
              if (buffer == NULL) {
                 fg_setmode(old_mode);
                 fg_reset();
                 printf("Could not create the virtual buffer.\n");
                 exit(1);
                 }
              handle = fg_vbdefine(buffer,320,240);
              fg_setcolor(9);
              fg_fillpage();
              fg_setcolor(15);
              fg_box(0,319,0,239);
              fg_vbopen(handle);
              fg_vbcut(0,319,0,239,0,239);
              fg_vbclose();
              fg_waitkey();
              fg_setmode(old_mode);
              fg_cursor(0);
              fg_setcolor(15);
              fg_text("Press any key.",14);
              fg_waitkey();
              fg_setmode(22);
              fg_vbopen(handle);
              fg_vbpaste(0,319,0,239,0,239);
              fg_waitkey();
              fg_vbclose();
              fg_setmode(old_mode);
              fg_reset();
           }


    Fastgraph includes other functions for working with virtual buffers, but

we'll defer our discussion of them until later chapters.


Summary of Video Page and Virtual Buffer Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_ALLOCATE creates a virtual video page. The amount of memory required

depends on the current video mode. This routine has no effect if it references a physical or logical video page.

    FG_ALLOCEMS creates a logical page in expanded memory (EMS). The amount

of memory required depends on the current video mode and video buffer dimensions. This routine has no effect if it references a physical or virtual �

                            Chapter 8:  Video Pages and Virtual Buffers   181


video page. In protected mode, fg_initems always fails, so fg_allocems is effectively disabled.

    FG_ALLOCXMS creates a logical page in extended memory (XMS). The amount

of memory required depends on the current video mode and video buffer dimensions. This routine has no effect if it references a physical or virtual video page. In protected mode, fg_initxms always fails, so fg_allocxms is effectively disabled.

    FG_COPYPAGE transfers the contents of one video page to another. The

pages may be physical, virtual, or logical video pages. If both pages are logical pages, they must exist in the same type of memory. This routine always applies to video pages, even when a virtual buffer is active.

    FG_DEFPAGES defines the SVGA banks for the source and destination page

numbers when using Fastgraph's block transfer routines with extended video pages.

    FG_FINDPAGE finds an available video page number for a virtual or logical

page.

    FG_FREEPAGE releases a virtual or logical video page created with

fg_allocate, fg_alloccms, fg_allocems, or fg_allocxms. This routine has no effect if it references a physical video page, or a virtual page that was never created.

    FG_GETADDR returns the real mode segment address or protected mode

segment selector for the active video page.

    FG_GETENTRY retrieves the type and address of a physical, virtual, or

logical video page. This routine is useful for saving virtual or logical page contents across video mode changes.

    FG_GETPAGE returns the active video page number.
    FG_GETVPAGE returns the visual video page number.
    FG_INITEMS initializes expanded memory for use with Fastgraph's logical

pages. In protected mode, the expanded memory initialization will always fail.

    FG_INITXMS initializes extended memory for use with Fastgraph's logical

pages. In protected mode, the extended memory initialization will always fail.

    FG_PAGESIZE returns the video page size in bytes for the current video

mode. The page size is always the video page size, even when a virtual buffer is active.

    FG_RESIZE changes the dimensions of a video page in EGA and VGA graphics

modes. This function has no effect when a virtual buffer is active.

    FG_SETENTRY specifies the type and address of a physical, virtual, or

logical video page. For logical pages, it further specifies if the page resides in conventional, expanded, or extended memory. This routine is useful for saving virtual or logical page contents across video mode changes, or for manual creation of virtual and logical pages. � 182 Fastgraph User's Guide


    FG_SETPAGE establishes the active video page. It may be a physical or

virtual page.

    FG_SETVPAGE establishes the visual video page. It may be a physical or

virtual page.

    FG_VBALLOC creates a virtual buffer of the specified size. The memory for

the virtual buffer is allocated automatically. This routine should be used instead of fg_vbdefine for real mode compilers that do not support huge memory blocks (that is, far blocks larger than 64K bytes). The fg_vballoc routine is not present in Fastgraph's protected mode libraries.

    FG_VBCLOSE closes the active virtual buffer and directs graphics output

back to the active video page.

    FG_VBCUT copies a rectangular region from the active video page to the

active virtual buffer.

    FG_VBDEFINE creates a virtual buffer of the specified size.
    FG_VBFREE releases a virtual buffer's handle and frees the memory

allocated to a virtual buffer created with fg_vballoc. The fg_vbfree routine is not present in Fastgraph's protected mode libraries.

    FG_VBHANDLE returns the handle for the active virtual buffer, or -1 if no

virtual buffer is active.

    FG_VBINIT initializes Fastgraph's virtual buffer environment. This

routine must be called once, before any other routines that reference virtual buffers.

    FG_VBOPEN makes an existing virtual buffer the active virtual buffer.
    FG_VBPASTE copies a rectangular region from the active virtual buffer to

the active video page.

    FG_VBUNDEF releases the handle associated with a virtual buffer.




Chapter 9



Image Files � 184 Fastgraph User's Guide


Overview

    Within the context of Fastgraph, an image is a rectangular area

containing some type of picture. An image might be something as simple as a pointing hand icon, or as detailed as the dashboard of a sports car. Fastgraph includes several routines to display, retrieve, and manipulate images. In this chapter we'll begin our discussion of images by looking at the PCX, GIF, FLI/FLC, and pixel run image file formats Fastgraph supports, as well as the routines available for displaying and creating image files in these formats.


PCX Files

    The PCX file format was originally developed by ZSoft Corporation for

their commercial paint program, PC Paintbrush. It has evolved into one of the more popular image file formats because so many products can read and write PCX files to at least some extent. Fastgraph includes routines for displaying and creating PCX files, as well as other PCX support functions.

    The fg_showpcx routine displays an image stored in a PCX file. It can

position the image using the coordinate information in the PCX header, or such that its upper left corner is at the graphics cursor position on the active video page. The first argument to fg_showpcx is the name of the PCX file (it may include a path name), and its second argument is a bit mask that controls how the image is displayed. The file name must be terminated with a null character, so BASIC, FORTRAN, and Pascal programmers will need to store a zero byte as the last character of the file name string. The fg_showpcx routine cannot display PCX images in virtual buffers. A separate routine, fg_loadpcx, is provided for this purpose and will be described later in this section.

    In the current version of Fastgraph, only the low-order three bits (bits

0 to 2) of the bit mask argument are meaningful. The following table summarizes the meanings of these bits.

             Bit Value  Meaning
              0    0    Use palette values stored in the PCX file
              0    1    Use the current palette settings
              1    0    Display image at position indicated in PCX header
              1    1    Display image at current graphics position
              2    0    Display image data from the PCX file
              2    1    Display image data from the fg_imagebuf buffer

All other bits are reserved and should be zero to guarantee compatibility with future releases. The fg_showpcx routine returns a value of 0 if successful, 1 if the specified file wasn't found, and 2 if the file is not a PCX file.

    The fg_makepcx routine creates a PCX file from the specified rectangular

region of the active video page or virtual buffer. Its first four arguments define the minimum x, maximum x, minimum y, and maximum y screen space coordinates of the region (the minimum x coordinate is reduced to a byte boundary if necessary). Its fifth argument is the name of the PCX file to create (it may include a path name). As with fg_showpcx, the file name must be terminated with a null character. If an identically named file exists, it is �

                                                Chapter 9:  Image Files   185


overwritten. The fg_makepcx routine returns a value of 0 if successful, and 1 if the PCX file was not created.

    Example 9-1 uses fg_showpcx and fg_makepcx to create a new PCX file from

selected rows of an existing 256-color 320x200 PCX file. As written, the program uses the file CORAL.PCX to create NEW.PCX, but it could easily be extended to work with any PCX files. The call to fg_showpcx displays the image in CORAL.PCX using the screen position and palette settings defined in the PCX file. After waiting for a keystroke, the program calls fg_makepcx to create a PCX file named NEW.PCX from pixel rows 80 through 99 of the original image. In case the program encounters any problems, it prints an error message before exiting.

                                Example 9-1.
           #include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
           void main(void);
           void main()
           {
              int old_mode;
              int read_status, write_status;
              fg_initpm();
              if (fg_testmode(19,1) == 0) {
                 printf("This program requires a 320 ");
                 printf("x 200 MCGA graphics mode.\n");
                 exit(1);
                 }
              old_mode = fg_getmode();
              fg_setmode(19);
              read_status = fg_showpcx("CORAL.PCX",0);
              fg_waitkey();
              if (read_status == 0)
                 write_status = fg_makepcx(0,319,80,99,"NEW.PCX");
              else
                 write_status = 1;
              fg_setmode(old_mode);
              fg_reset();
              if (read_status == 1)
                 printf("CORAL.PCX not found.\n");
              else if (read_status == 2)
                 printf("CORAL.PCX is not a PCX file.\n");
              if (write_status == 1)
                 printf("NEW.PCX not created.\n");
           }


    In the Tandy/PCjr 16-color graphics mode (mode 9) and the native EGA

graphics modes (modes 13 through 16), the palette registers are not readable. Hence, fg_makepcx will use the default palette settings when used in these � 186 Fastgraph User's Guide


video modes on Tandy and EGA systems. Displaying a PCX file at a lower resolution (for example, a 640x480 PCX file at 320x200) will truncate the display on the right and on the bottom. This effectively displays the upper left corner of the image. The fg_showpcx and fg_makepcx routines have no effect in text video modes or in the Hercules low-resolution graphics mode.

    If you want to display a PCX file in a virtual buffer, you must use

Fastgraph's fg_loadpcx routine instead of fg_showpcx. The fg_loadpcx parameters and return values are identical to those of fg_showpcx, but the image destination is a virtual buffer and not video memory. We found it preferable to create a separate function for loading PCX images into virtual buffers because PCX files closely resemble the structure of video memory. The fg_showpcx routine is optimized to take advantage of this, while fg_loadpcx must perform the additional task of converting the pixel data to the virtual buffer format.

    Example 9-2 shows how to display a PCX image in a virtual buffer with

fg_loadpcx. The CORAL.PCX file used in this example is a 320x200 image, so the required virtual buffer size is 64,000 bytes. After creating and opening the virtual buffer, the program calls fg_loadpcx to display the image in the virtual buffer. If successful, it makes the image visible by copying the virtual buffer contents to the visual page using fg_vbpaste.

                                Example 9-2.
           #include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
           #ifdef __TURBOC__
           #include <alloc.h>
           #else
           #include <malloc.h>
           #endif
           void main(void);
           void main()
           {
              int handle;
              int old_mode;
              int status;
           #ifdef FG32
              char *buffer;
           #else
              char huge *buffer;
           #endif
              fg_initpm();
              if (fg_testmode(19,1) == 0) {
                 printf("This program requires a 320 ");
                 printf("x 200 MCGA graphics mode.\n");
                 exit(1);
                 }
              old_mode = fg_getmode();
              fg_setmode(19);
              fg_vbinit();                                                    �
                                                Chapter 9:  Image Files   187


           #ifdef FG32
              buffer = (char *)malloc(64000);
           #elif defined(__TURBOC__)
              buffer = (char huge *)farmalloc(64000L);
           #else
              buffer = (char huge *)halloc(64000L,1);
           #endif
              if (buffer == NULL) {
                 fg_setmode(old_mode);
                 fg_reset();
                 printf("Could not create the virtual buffer.\n");
                 exit(1);
                 }
              handle = fg_vbdefine(buffer,320,200);
              fg_vbopen(handle);
              status = fg_loadpcx("CORAL.PCX",0);
              if (status == 0) {
                 fg_vbpaste(0,319,0,199,0,199);
                 fg_waitkey();
                 }
              fg_vbclose();
              fg_setmode(old_mode);
              fg_reset();
              if (status == 1)
                 printf("CORAL.PCX not found.\n");
              else if (status == 2)
                 printf("CORAL.PCX is not a PCX file.\n");
           }


    Because their structure parallels that of video memory, PCX files are

specific to certain video modes. If you try to display a PCX file in an incompatible video mode, fg_showpcx will still display something, but it will be garbled. The following table summarizes the compatible video modes for PCX files.

                   If PCX file was     You can display
                   created in mode     it in these modes
                   4, 5                4, 5
                   6, 11               6, 11, 13-18, 28, 29
                   9                   9
                   13-18               13-18, 28, 29
                   19-27               19-27
                   28-29               13-18, 28, 29
    Unlike fg_showpcx, fg_loadpcx does not display a PCX image directly to

video memory. The fg_loadpcx routine instead converts the mode-specific structure of the PCX file to the mode-independent virtual buffer format as it unpacks the image data. This overhead means fg_showpcx is faster than fg_loadpcx, but fg_loadpcx makes it possible to display any PCX file in any graphics video mode. The only problem occurs when displaying a PCX image with more colors than the current video mode supports (for example, displaying a � 188 Fastgraph User's Guide


256-color PCX in a 16-color mode). In this case, fg_vbpaste will display pixels of color c in color c modulo n, where n is the number of colors available in the current video mode.

    The fg_pcxpal routine retrieves the palette of an image stored in a PCX

file. Its first argument is a PCX file name, terminated by a zero byte as with fg_showpcx. Its second argument is the address of the array that will receive the PCX palette values. The palette values are returned as RGB color components, each between 0 and 63. The first three bytes of this array will contain the RGB values for color 0, the next three for color 1, and so forth. The array size in bytes must be at least three times the number of colors in the PCX image. If successful, the fg_pcxpal function return value is the number of colors in the PCX palette, either 16 or 256. The possible error return values are -1 (file not found) and -2 (file is not a PCX file).

    For video modes 18 and above, the fg_pcxpal palette values are suitable

for use with fg_setdacs. For the native EGA graphics modes (13 to 16), the palette values must be converted into mode-specific values (with fg_maprgb) before being used with fg_palette or fg_palettes. If the PCX file includes an extended (256-color) palette, fg_pcxpal will return the values in the extended palette. Otherwise, it will return the values from the 16-color palette in the PCX header.

    Fastgraph's fg_pcxmode function determines the optimal video mode for

displaying a PCX file. By optimal, we mean the compatible video mode having the lowest resolution larger than or equal to the image dimensions. The fg_pcxmode routine has a single argument -- the address of a buffer that contains a 128-byte PCX file header. Specific values defined in certain fields of the PCX header determine which video mode is optimal. A positive return value from fg_pcxmode represents the optimal video mode number. The possible error returns are -1 if the buffer does not contain a valid PCX header, and -2 if fg_pcxmode cannot find any compatible video mode.

    Another useful PCX support function is fg_pcxrange, which returns the

image position information from the PCX header. The first fg_pcxrange argument is the address of a buffer containing a 128-byte PCX file header. The remaining four arguments receive the minimum x, maximum x, minimum y, and maximum y values of the corresponding PCX image. You can use the image extents to determine the image dimensions -- for example, the width of a PCX image would be maximum_x - minimum_x + 1.

    How do we get the header from a PCX file into the buffer passed to

fg_pcxmode or fg_pcxrange? The easiest way is with the fg_pcxhead function. Its first argument is the name of the PCX file from which to retrieve the header (as before, the file name must be null-terminated). The second argument is the address of the buffer that will receive the PCX header. The size of this buffer must be at least 128 bytes. If successful, fg_pcxhead returns zero. Otherwise, the return value is -1 if the specified file could not be opened, or -2 if the file is not a PCX file. After successfully reading the PCX header, you can pass it to fg_pcxmode to determine the optimal video mode for the PCX file. Full information about the 128-byte PCX file header appears in Appendix H.

    Example 9-3 uses Fastgraph's fg_pcxhead, fg_pcxmode, fg_pcxpal, and

fg_pcxrange routines to obtain information about the CORAL.PCX file. It �

                                                Chapter 9:  Image Files   189


displays the optimal video mode number for displaying the image, the image dimensions, and the image's first 16 color palette values.

                                Example 9-3.
   #include <fastgraf.h>
   #include <stdio.h>
   #include <stdlib.h>
   void main(void);
   void main()
   {
      int i, j;
      int mode, status;
      int minx, maxx, miny, maxy;
      unsigned char PCXpal[768];
      unsigned char header[128];
      fg_initpm();
      status = fg_pcxhead("CORAL.PCX",header);
      if (status == -1) {
         printf("Can't open CORAL.PCX.\n");
         exit(1);
         }
      else if (status == -2) {
         printf("CORAL.PCX is not a PCX file.\n");
         exit(1);
         }
      mode = fg_pcxmode(header);
      printf("Optimal display mode is %d.\n",mode);
      fg_pcxrange(header,&minx,&maxx,&miny,&maxy);
      printf("Image size is %d by %d pixels.\n",maxx-minx+1,maxy-miny+1);
      fg_pcxpal("CORAL.PCX",PCXpal);
      printf("First 16 palette values are:\n");
      j = 0;
      for (i = 0; i < 16; i++) {
         printf("  color %2d: R=%2d G=%2d B=%2d\n",
            i,PCXpal[j],PCXpal[j+1],PCXpal[j+2]);
         j += 3;
         }
   }


GIF Files

    The GIF file format was created by CompuServe, Inc., as a transmission

format for images and graphics data across the CompuServe network. It has evolved into what is probably the most popular image file format in use today. GIF files are especially prevalent on bulletin boards and electronic data networks because their efficient image compression results in less storage space and faster transmission times than other image file formats. GIF, pronounced "jif", is an acronym for Graphics Interchange Format. The format is � 190 Fastgraph User's Guide


the copyright property of CompuServe, Inc., whose GIF specification "grants a limited, non-exclusive, royalty-free license for the use of the Graphics Interchange Format in computer software; computer software utilizing GIF must acknowledge ownership of the Graphics Interchange Format and its Service Mark by CompuServe, Inc., in user and technical documentation".

    Two GIF specifications, released in 1987 and 1989, are defined. The 1989

specification (known as "89a") is a superset of the original 1987 specification (known as "87a"). Fastgraph's GIF file display routine can handle either 87a or 89a files. For maximum portability, the GIF file creation routine always produces files conforming to the 87a specification.

    The fg_showgif routine displays an image stored in a GIF file. It can

position the image using the coordinate information in the GIF header, or such that its upper left corner is at the graphics cursor position on the active video page or virtual buffer. The fg_showgif arguments are the same as for fg_showpcx, except the file name must of course reference a GIF file rather than a PCX file. Likewise, the fg_showgif return values are analogous to those of fg_showpcx.

    The fg_makegif routine creates a GIF file from the specified rectangular

region of the active video page or virtual buffer. Its arguments and return value are analogous to those of fg_makepcx.

    Example 9-4 uses fg_showgif and fg_makegif to create a new GIF file from

selected rows of an existing 256-color 320x200 GIF file. Similar to example 9-1, the program uses the file CORAL.GIF to create NEW.GIF, but it could easily be extended to work with any GIF files. The call to fg_showgif displays the image in CORAL.GIF using the screen position and palette settings defined in the GIF file. After waiting for a keystroke, the program calls fg_makegif to create a GIF file named NEW.GIF from pixel rows 80 through 99 of the original image. In case the program encounters any problems, it prints an error message before exiting.

                                Example 9-4.
           #include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
           void main(void);
           void main()
           {
              int old_mode;
              int read_status, write_status;
              fg_initpm();
              if (fg_testmode(19,1) == 0) {
                 printf("This program requires a 320 ");
                 printf("x 200 MCGA graphics mode.\n");
                 exit(1);
                 }
              old_mode = fg_getmode();
              fg_setmode(19);
              read_status = fg_showgif("CORAL.GIF",0);                        �
                                                Chapter 9:  Image Files   191


              fg_waitkey();
              if (read_status == 0)
                 write_status = fg_makegif(0,319,80,99,"NEW.GIF");
              else
                 write_status = 1;
              fg_setmode(old_mode);
              fg_reset();
              if (read_status == 1)
                 printf("CORAL.GIF not found.\n");
              else if (read_status == 2)
                 printf("CORAL.GIF is not a GIF file.\n");
              if (write_status == 1)
                 printf("NEW.GIF not created.\n");
           }


    Like fg_makepcx, the fg_makegif routine will use the default palette

settings when running on Tandy and EGA systems. Displaying a GIF file at a lower resolution (for example, a 640x480 GIF file at 320x200) will truncate the display on the right and on the bottom. This effectively displays the upper left corner of the image. Unlike PCX files, GIF files do not exhibit compatibility problems between 16-color and 256-color graphics modes. When fg_showgif displays a 256-color GIF in a 16-color mode, it displays pixels of color c in color c modulo 16. The fg_showgif and fg_makegif routines have no effect in text video modes, or in CGA and Hercules graphics modes.

    Fastgraph includes additional GIF support routines analogous to those for

PCX files. The fg_gifpal routine retrieves the palette of an image stored in a GIF file. If the GIF file includes a local palette for the first image, fg_gifpal will return the values from the local palette. Otherwise, fg_gifpal will return the values from the GIF file's global palette. The fg_gifmode function determines the optimal video mode for displaying a GIF file. The fg_gifrange routine returns the image position information from the GIF header. The fg_gifhead routine reads a GIF file's global header and first local header into a 23-byte array (full information about the headers appears in Appendix H). The parameters and return values for these routines are the same as for their PCX counterparts.

    Example 9-5 uses Fastgraph's fg_gifhead, fg_gifmode, fg_gifpal, and

fg_gifrange routines to obtain information about the CORAL.GIF file. It displays the optimal video mode number for displaying the image, the image dimensions, and the image's first 16 palette values.

                                Example 9-5.
   #include <fastgraf.h>
   #include <stdio.h>
   #include <stdlib.h>
   void main(void);
   void main()
   {
      int i, j;
      int mode, status;                                                       �

192 Fastgraph User's Guide


      int minx, maxx, miny, maxy;
      unsigned char GIFpal[768];
      unsigned char header[23];
      fg_initpm();
      status = fg_gifhead("CORAL.GIF",header);
      if (status == -1) {
         printf("Can't open CORAL.GIF.\n");
         exit(1);
         }
      else if (status == -2) {
         printf("CORAL.GIF is not a GIF file.\n");
         exit(1);
         }
      mode = fg_gifmode(header);
      printf("Optimal display mode is %d.\n",mode);
      fg_gifrange(header,&minx,&maxx,&miny,&maxy);
      printf("Image size is %d by %d pixels.\n",maxx-minx+1,maxy-miny+1);
      fg_gifpal("CORAL.GIF",GIFpal);
      printf("First 16 palette values are:\n");
      j = 0;
      for (i = 0; i < 16; i++) {
         printf("  color %2d: R=%2d G=%2d B=%2d\n",
            i,GIFpal[j],GIFpal[j+1],GIFpal[j+2]);
         j += 3;
         }
   }


FLI and FLC files

    FLI and FLC files (collectively called flic files) contain sequences of

image frames that can be displayed in rapid succession to achieve the illusion of movement (this is called playing a flic file). FLI files are produced by Autodesk Animator and always have a 320x200 resolution, while FLC files are produced by Autodesk Animator Pro and can have any resolution. Fastgraph's flic file routines work with both FLI and FLC files, but they are restricted to 256-color graphics modes because flic files always contain 256-color images. The first frame of a flic file is usually a compressed version of the entire image, while later frames are compressed versions of the differences between that frame and the previous frame. This compression scheme is often called delta compression in flic file literature.

    Fastgraph includes both high-level and low-level routines for working

with flic files. The most important high-level routine, fg_showflic, plays the entire contents of a flic file any number of times. It can position the image such that its upper left corner is at the screen origin or at the graphics cursor position on the active video page or vitual buffer. The fg_showflic routine expects three arguments. The first is the flic file name, which may include a path name, but must be null- terminated. The second specifies the number of times to play the flic file. If the play count is zero, fg_showflic will play it continuously. The fg_showflic routine will stop playing the flic �

                                                Chapter 9:  Image Files   193


file if the Escape key is pressed. Note that this is the only way to stop playing the flic file if the play count is zero (continuous play).

    The third fg_showflic argument is a bit mask that controls how the image

is displayed. In the current version of Fastgraph, only the low-order three bits (bits 0 to 2) of the bit mask argument are meaningful. The following table summarizes the meanings of these bits.

             Bit Value  Meaning
              0    0    Delay between frames as indicated in flic header
              0    1    No delay between frames
              1    0    Display image relative to screen origin
              1    1    Display image relative to current graphics position
              2    0    Display image data from the specified flic file
              2    1    Display image data from the fg_imagebuf buffer
              4    0    Use palette data in flic file
              4    1    Ignore palette data in flic file

All other bits are reserved and should be zero to guarantee compatibility with future releases. The fg_showflic routine returns a value of 0 if successful, 1 if the specified file wasn't found, and 2 if the file is not a flic file.

    Example 9-6 is a simple flic file player. It uses the standard VGA/MCGA

256-color graphics mode (mode 19) to play the flic file GLASS.FLI, one of the examples supplied with Autodesk Animator. The upper left corner of the flic file will be at the screen origin, with a delay between frames as defined in the flic file header.

                                Example 9-6.
           #include <fastgraf.h>
           #include <stdio.h>
           void main(void);
           void main(void)
           {
              int status;
              fg_initpm();
              fg_setmode(19);
              status = fg_showflic("GLASS.FLI",1,0);
              if (status == 0) fg_waitkey();
              fg_setmode(3);
              fg_reset();
              if (status == 1)
                 printf("GLASS.FLI not found.\n");
              else if (status == 2)
                 printf("GLASS.FLI is not an FLI or FLC file.\n");
           }


    Fastgraph includes additional flic support routines similar to those for

PCX and GIF files. The fg_flichead routine reads the specified flic file's

194 Fastgraph User's Guide


128-byte header (full information about the header appears in Appendix H). The fg_flicmode function determines the optimal video mode for playing a flic file. Its only argument is a 128-byte array containing a flic file header returned by fg_flichead. If successful, it returns the optimal video mode number for playing the flic image. If the array does not contain a valid flic file header, fg_flicmode returns -1. The fg_flicsize routine returns the image dimensions from the flic header. Its first argument is a 128-byte flic header array, and is remaining two arguments receive the image width and height in pixels. Example 9-7 uses these three routines to obtain information about the GLASS.FLI file. It displays the optimal video mode number for playing the flic file, as well as the image dimensions.

                                Example 9-7.
         #include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
         void main(void);
         void main()
         {
            int mode, status;
            int width, height;
            unsigned char header[128];
            fg_initpm();
            status = fg_flichead("GLASS.FLI",header);
            if (status == -1) {
               printf("Can't open GLASS.FLI.\n");
               exit(1);
               }
            else if (status == -2) {
               printf("GLASS.FLI is not a FLI or FLC file.\n");
               exit(1);
               }
            mode = fg_flicmode(header);
            printf("Optimal display mode is %d.\n",mode);
            fg_flicsize(header,&width,&height);
            printf("Image size is %d by %d pixels.\n",width,height);
         }


    Fastgraph's low-level flic routines provide the ability to display flic

files one frame at a time. This is desirable when your program must perform other tasks between frames, or for playing two or more flic files at the same time. To use Fastgraph's low-level flic routines, call fg_flicopen for each flic file. The first fg_flicopen argument is the flic file name. The second argument is a 16-byte array that will receive a context descriptor for the flic file. You must create a context descriptor with fg_flicopen for each flic file you'll access with the low-level flic file routines (the number of flic files you can have open at any one time is limited by the FILES specifier in your CONFIG.SYS file). The context descriptor is then passed to other routines when accessing the flic file. If successful, fg_flicopen fills the context descriptor, positions the flic file at the first frame, and returns zero. The �

                                                Chapter 9:  Image Files   195


possible error return values are -1 (file not found) and -2 (file is not an FLI or FLC file).

    The fg_flicplay routine plays one or more frames from a flic file and

leaves the file positioned at the beginning of the next frame. Its three arguments are the same as for fg_showflic except the first argument is a context descriptor instead of a flic file name. The fg_flicskip routine advances over flic file frames. Its first argument is the flic file's context descriptor, and its second argument is the number of frames to skip (if the frame count is negative, the file position is reset to the first frame). Both routines return the number of frames played, which may be less than the number of frames requested if the end-of-file is reached. Fastgraph's last low-level flic routine, fg_flicdone, closes a flic file previously opened with fg_flicopen. Its only argument is the flic file's context descriptor.

    Example 9-8 is similar to example 9-6, but it plays the GLASS.FLI file

one frame at a time using Fastgraph's low-level flic routines. It opens the flic file with fg_flicopen, which returns a 16-byte context descriptor for the file. If the file was opened successfully, the program plays each frame by calling fg_flicplay in a loop, waiting for a keystroke between each frame (note that the bit mask passed to fg_flicplay has bit 0 set, as it's usually not too meaningful to delay between frames when playing frames individually). Eventually we'll reach the end-of-file, indicated by an fg_flicplay return value of zero. When this occurs, the program calls fg_flicdone and exits.

                                Example 9-8.
           #include <fastgraf.h>
           #include <stdio.h>
           void main(void);
           void main(void)
           {
              int frames;
              int status;
              char context[16];
              fg_initpm();
              fg_setmode(19);
              status = fg_flicopen("GLASS.FLI",context);
              if (status == 0) {
                 do {
                    frames = fg_flicplay(context,1,1);
                    fg_waitkey();
                    }
                 while (frames > 0);
                 fg_flicdone(context);
                 }
              fg_setmode(3);
              fg_reset();
              if (status == -1)
                 printf("GLASS.FLI not found.\n");
              else if (status == -2)                                          �

196 Fastgraph User's Guide


                 printf("GLASS.FLI is not an FLI or FLC file.\n");
           }


Pixel Run Files

    Fastgraph also provides its own mode-independent image file format called

pixel run format. Pixel run files are useful in programs that must run in different video modes (but with the same resolution) because you can use the same image files for two-color modes as for 256-color modes. Two variations of the pixel run format exist -- standard pixel run files (SPR files) and packed pixel run files (PPR files). The packed pixel run format does not support 256- color images but will produce a smaller file if the image has 16 colors or less. Pixel run files do not include a header or any color palette information.

    The best way to illustrate the pixel run file format is with an example.

Suppose we want to display a small triangle whose perimeter is a different color than its interior. To create the standard pixel run equivalent of this image, we must inscribe the triangle in a rectangular area. Hence, the pixel representation of our triangle might appear as shown here:

                              . . . . * . . . .
                              . . . * x * . . .
                              . . * x x x * . .
                              . * x x x x x * .
                              * * * * * * * * *
    As shown in this diagram, our triangle image is nine pixels wide at its

base and five pixels high. The pixels indicated by an asterisk (*) are the triangle's perimeter, while those indicated by an x represent its interior points. The pixels shown as periods (.) are not part of the triangle itself, but they are part of the image. In this example, we can treat them as background pixels.

    If we start at the lower left corner of the image and proceed to the

right, we could represent the first row of the image as nine pixels of color "asterisk". Such a group of consecutive identically colored pixels is called a pixel run, so a single pixel run describes the first row of the image. The row above this one is a bit more complex. It consists of five pixel runs: one pixel of color "period", followed by one of color "asterisk", then five of color "x", one of color "asterisk", and finally one of color "period".

    While we could construct separate pixel runs for each row of the image,

notice that three of the five rows in our triangle begin with the same color pixel as the rightmost pixel in the previous row. Fastgraph's pixel run formats let you take advantage of this property by allowing pixel runs to wrap from one row to the next. This means we can represent the pixel run of color "period" extending from the right side of the second row to the left side of the third row as a single run of three pixels.

    An standard pixel run (SPR) file is nothing more than such a sequence of

(color,count) pairs, as shown in the following diagram. �

                                                Chapter 9:  Image Files   197


                         byte 0   color for run 1
                              1   count for run 1
                              2   color for run 2
                              3   count for run 2



                           2n-2   color for run n
                           2n-1   count for run n


Each color is a value between 0 and 255 specifying the color index for that pixel run. Each count is a value between 0 and 255 specifying the length in pixels of that pixel run. If a single run exceeds 255 pixels, it must be broken into two or more runs. For example, we could represent a pixel run of length 265 as a run of length 255 followed by a run of length 10 of the same color. Note that the space in bytes needed to store an SPR image is twice the number of runs.

    Fastgraph's fg_showspr routine displays an SPR file. Its first argument

is the name of the file containing the image (it may include a path name). The file name must be terminated with a null character, so BASIC, FORTRAN, and Pascal programmers will need to store a zero byte as the last character of the file name string. The second argument is the width in pixels of the image. The fg_showspr routine displays the image such that its lower left corner is at the graphics cursor position. The possible return values for fg_showspr are success (0) and file not found (1). To create an SPR file, use the fg_makespr routine. Its arguments and return values are the same as for fg_makepcx and fg_makegif.

    Example 9-9 uses fg_showspr and fg_makespr to create a new SPR file from

selected rows of an existing 16-color 320x200 SPR file. Similar to examples 9-1 and 9-4, the program uses the file CORAL.SPR to create NEW.SPR, but it could easily be extended to work with any SPR files. The call to fg_move establishes the lower left corner of the screen as the graphics cursor position (contrast this with the upper left corner being the reference point for PCX, GIF, and flic files). The program then calls fg_showspr to display the image. After waiting for a keystroke, the program calls fg_makespr to create an SPR file named NEW.SPR from pixel rows 80 through 99 of the original image. In case the program encounters any problems, it prints an error message before exiting.

                                Example 9-9.
           #include <fastgraf.h>
           #include <stdio.h>
           #include <stdlib.h>
           void main(void);
           void main()                                                        �

198 Fastgraph User's Guide


           {
              int new_mode, old_mode;
              int read_status, write_status;
              fg_initpm();
              new_mode = fg_bestmode(320,200,1);
              if (new_mode < 0 || new_mode == 12) {
                 printf("This program requires a 320 ");
                 printf("x 200 color graphics mode.\n");
                 exit(1);
                 }
              old_mode = fg_getmode();
              fg_setmode(new_mode);
              fg_move(0,199);
              read_status = fg_showspr("CORAL.SPR",320);
              fg_waitkey();
              if (read_status == 0)
                 write_status = fg_makespr(0,319,80,99,"NEW.SPR");
              else
                 write_status = 1;
              fg_setmode(old_mode);
              fg_reset();
              if (read_status == 1)
                 printf("CORAL.SPR not found.\n");
              if (write_status == 1)
                 printf("NEW.SPR not created.\n");
           }


    If you have an image that only uses the first 16 color indices (0 to 15),

you can use Fastgraph's packed pixel run (PPR) image format. This format packs two color values into each color byte, so it takes three bytes instead of four to represent two pixel runs. This means a PPR file is 25% smaller than its SPR equivalent. In each set of three bytes, the high four bits of the first byte contain the color of the first run, and the low four bits contain the color of the second run. The second byte contains the length of the first run, and the third byte contains the length of the second run.

    The following diagram illustrates the structure of the packed pixel file.

In this example, the file is assumed to contain n pixel runs, where n is an even number. If n is odd, the byte offset for the last element is 3n/2 (truncated) instead of 3n/2-1, and the low four bits of the last color byte (that is, the color for pixel run n+1) are ignored.

                      7                4   3                0
              byte 0    color for run 1     color for run 2
                   1              count for run 1
                   2              count for run 2
                   3    color for run 3     color for run 4                   �
                                                Chapter 9:  Image Files   199


                   4              count for run 3
                   5              count for run 4



              3n/2-3   color for run n-1    color for run n
              3n/2-2             count for run n-1
              3n/2-1              count for run n


    The structure of the PPR file allows for color values between 0 and 15,

and run lengths between 0 and 255. The space in bytes needed to store an image in PPR format is 1.5 times the number of runs, compared to twice the number of runs for the SPR format.

    The fg_showppr and fg_makeppr routines display and create PPR files,

respectively. Their arguments and return values are the same as those of fg_showspr and fg_makespr. If we wanted to display PPR files instead of SPR files in example 9-9, all that's necessary is changing the fg_showspr and fg_makespr calls to fg_showppr and fg_makeppr.

    Fastgraph's fg_dispfile routine displays both SPR and PPR files. The

first of its three arguments is the name of the image file (it may include a path name). The file name must be terminated with a null character, so BASIC, FORTRAN, and Pascal programmers will need to store a zero byte as the last character of the file name string. The second argument is the image width in pixels, and the third argument defines the image format (that is, SPR or PPR). As with other pixel run display routines, fg_dispfile displays the image such that its lower left corner is at the graphics cursor position.

    Example 9-10 illustrates how to use fg_dispfile to display an image

stored in a pixel run file. The program displays two identical images, one in an SPR file and the other in a PPR file. Each image is a picture of the sea floor and some coral, as might be used for the background in an aquarium. The program runs in a 320x200 graphics mode, and the images fill the entire screen.

    The SPR image is in file CORAL.SPR. The program uses fg_move to establish

the lower left corner of the screen as the graphics cursor position and then calls fg_dispfile to display the image. The value of fg_dispfile's third argument tells Fastgraph the image format. A value of 0 indicates the file contains an image in SPR format, while a value of 1 indicates an image in PPR format. As mentioned earlier, the image fills the entire screen, so its width is 320 pixels.

    After waiting for a keystroke, the program clears the previous image from

the screen and then calls fg_dispfile to display the PPR image from the file CORAL.PPR. The program leaves the second image on the screen until another keypress, at which time it restores the original video mode and screen attributes and returns to DOS. � 200 Fastgraph User's Guide


                                Example 9-10.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int old_mode, new_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_move(0,199);
                   fg_dispfile("CORAL.SPR",320,0);
                   fg_waitkey();
                   fg_erase();
                   fg_dispfile("CORAL.PPR",320,1);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    The SNAPSHOT utility distributed with Fastgraph is a terminate and stay

resident program (TSR) that can capture graphics mode screen images and save them in SPR files. Thus, you can easily create files with SNAPSHOT and display them with fg_showspr or fg_dispfile. Another TSR utility, GrabRGB, is useful for capturing RGB color values from 256-color images. Appendix A contains complete descriptions of the SNAPSHOT and GrabRGB utilities.


Display Patterns

    Example 9-10 works well in the graphics video modes with 16 or 256

available colors. However, in the four-color CGA graphics modes the resulting image is not too good because of our limited color choices, and it would look even worse in the Hercules graphics mode. The Fastgraph routine fg_pattern allows you to associate a dither pattern (actually, any pixel sequence) with one of Fastgraph's 256 color indices appearing in a pixel run map. When displaying an SPR or PPR file, Fastgraph will use the pattern associated with that color index instead of displaying the color itself. �

                                                Chapter 9:  Image Files   201


    The fg_pattern routine requires two integer arguments -- a color index

(between 0 and 255) and the display pattern defined for that color index. A display pattern's structure resembles the structure of video memory and is thus dependent on the current video mode. The following sections list the initial display patterns and explain how to construct new display patterns for different graphics video modes.

CGA four-color graphics modes

    In the four-color CGA graphics modes (modes 4 and 5), the display pattern

consists of an 8-bit shift count followed by an 8-bit pixel pattern. Each pixel assumes a value between 0 and 3, so the pattern represents four pixels. In even-numbered pixel rows, Fastgraph uses the pixel pattern itself. In odd- numbered pixel rows, Fastgraph rotates the original pattern to the left by the number of bits specified by the shift count.

    For example, if we are using the default CGA color palette, we could

create a darker shade of cyan by alternating cyan pixels (color 1, 01 binary) with white pixels (color 3, 11 binary), as shown here:


                                 01 11 01 11


If we convert this pixel pattern to its hexadecimal equivalent, we get the value 77.

    To complete the display pattern, we need to determine the shift count. If

we use a shift count of zero, the resulting display will simply be a series of cyan and white vertical lines. What we really need is a checkerboard effect where a white pixel is above and below each cyan pixel, and vice versa. If we rotate the pattern one pixel (two bits) to the left, we will achieve the desired effect. That is, a shift count of two produces the following pixel patterns:

                      even-numbered rows   01 11 01 11
                       odd-numbered rows   11 01 11 01

Combining the shift count with the pixel pattern yields the display pattern 0277 hex. The shift count is normally a multiple of two; note that a zero shift count results in the same pattern being applied to all pixel rows.

    For the CGA four-color graphics modes, fg_setmode establishes the

following initial display patterns:

                      color       shift count    hexadecimal
                      index       and pattern    equivalent
                        0         0 00000000        0000
                        1         0 01010101        0055
                        2         0 10101010        00AA
                        3         0 11111111        00FF

These values are repeated as necessary to define color indices 4 to 255. That is, colors 4, 8, 12, ... , 252 use the same defaults as color 0. Colors 5, 9, 13, ... , 253 use the same defaults as color 1, and so forth. Also note that � 202 Fastgraph User's Guide


pattern 0000 represents four pixels of color 0, 0055 represents four pixels of color 1, 00AA represents four pixels of color 2, and 00FF represents four pixels of color 3.

CGA two-color graphics mode

    In the two-color CGA graphics mode (mode 6), the display pattern also

consists of an 8-bit shift count followed by an 8-bit pixel pattern. Each pixel assumes the value 0 or 1, so the pattern represents eight pixels. In even-numbered pixel rows, Fastgraph uses the pixel pattern itself. In odd- numbered pixel rows, Fastgraph rotates the original pattern to the left by the number of bits specified by the shift count.

    For example, we could create a lighter shade of white by alternating

black pixels (color 0) with white pixels (color 1), as shown here:


                               0 1 0 1 0 1 0 1


If we convert this pixel pattern to its hexadecimal equivalent, we get the value 55.

    To complete the display pattern, we need to determine the shift count. We

must rotate the pattern one pixel (one bit) to the left to achieve the checkerboard effect as in the CGA four color graphics modes. That is, a shift count of one produces the following pixel patterns:

                    even-numbered rows   0 1 0 1 0 1 0 1
                     odd-numbered rows   1 0 1 0 1 0 1 0

Combining the shift count with the pixel pattern yields the display pattern 0155 hex.

    For the CGA two-color graphics mode, fg_setmode establishes the initial

display patterns such that all even-numbered color indices are assigned the value 0000, while all odd-numbered color indices are assigned the value 00FF. Note that pattern 0000 represents eight pixels of color 0, and 00FF represents eight pixels of color 1.

Tandy/PCjr 16-color graphics mode

    In the Tandy/PCjr 16-color graphics mode (mode 9), the display pattern

also consists of an 8-bit shift count followed by an 8-bit pixel pattern. Each pixel assumes a value between 0 and 15, so the pattern represents two pixels. In even-numbered pixel rows, Fastgraph uses the pixel pattern itself. In odd- numbered pixel rows, Fastgraph rotates the original pattern to the left by the number of bits specified by the shift count.

    For example, we could create a lighter shade of blue by alternating blue

pixels (color 1, 0001 binary) with white pixels (color 15, 1111 binary), as shown here:


                                  0001 1111                                   �
                                                Chapter 9:  Image Files   203


If we convert this pixel pattern to its hexadecimal equivalent, we get the value 1F.

    To complete the display pattern, we need to determine the shift count.

Using the same process as in the CGA graphics modes, we must rotate the pattern one pixel (four bits) to the left to achieve the checkerboard effect. That is, a shift count of four produces the following pixel patterns:

                       even-numbered rows   0001 1111
                        odd-numbered rows   1111 0001

Combining the shift count with the pixel pattern yields the display pattern 041F hex. The shift count is normally zero or four; note that a zero shift count results in the same pattern being applied to all pixel rows.

    For the Tandy/PCjr 16-color graphics modes, fg_setmode establishes the

initial display patterns such that color 0 is assigned the value 0000 (two pixels of color 0), color 1 is assigned the value 0011 (two pixels of color 1), color 2 is assigned the value 0022 (two pixels of color 2), and so forth. These values are repeated as necessary to define color indices 16 to 255. That is, colors 0, 16, 32, ... , 240 use the same defaults as color 0. Colors 1, 17, 33, ... , 241 use the same defaults as color 1, and so forth.

Hercules graphics modes

    The structure of the display patterns for the Hercules graphics modes

(modes 11 and 12) is the same as two of the CGA graphics modes. For the standard Hercules graphics mode (mode 11), please refer to the discussion of CGA two-color (mode 6) display patterns. For the low-resolution Hercules graphics mode (mode 12), please refer to the discussion of the CGA four-color (mode 4) display patterns.

EGA/VGA/SVGA 16-color graphics modes

    In the EGA/VGA/SVGA 16-color graphics modes (modes 13 to 16, 18, 28, and

29), the display pattern consists of two 4-bit color values (for consistency with the other video modes, we still pass the display pattern as a 16-bit or 32-bit quantity). Each pixel assumes a value between 0 and 15 (0 and 5 in the EGA monochrome graphics mode), so the pattern represents two pixels. In even- numbered pixel rows, Fastgraph uses the pixel pattern itself. In odd-numbered pixel rows, Fastgraph rotates the original pattern one pixel (four bits) to the left.

    For example, we could create a lighter shade of blue by alternating blue

pixels (color 1, 0001 binary) with white pixels (color 15, 1111 binary), as shown here:


                                  0001 1111


If we convert this pixel pattern to its hexadecimal equivalent, we get the value 1F. The implied four-bit shift count produces the following pixel patterns: � 204 Fastgraph User's Guide


                       even-numbered rows   0001 1111
                        odd-numbered rows   1111 0001

Extending the pixel pattern to a 16-bit or 32-bit quantity yields the display pattern 001F hex.

    For the EGA/VGA/SVGA 16-color graphics modes, fg_setmode establishes the

initial display patterns such that color 0 is assigned the value 0000 (two pixels of color 0), color 1 is assigned the value 0011 (two pixels of color 1), color 2 is assigned the value 0022 (two pixels of color 2), and so forth. These values are repeated as necessary to define color indices 16 to 255. That is, colors 0, 16, 32, ... , 240 use the same defaults as color 0. Colors 1, 17, 33, ... , 241 use the same defaults as color 1, and so forth.

MCGA/VGA 2-color graphics mode

    In the two-color MCGA/VGA graphics mode (mode 17), the display pattern

consists of two 1-bit color values (for consistency with the other video modes, we still pass the display pattern as a 16-bit or 32-bit quantity). Each pixel assumes the value 0 or 1, so the pattern represents two pixels. In even- numbered pixel rows, Fastgraph uses the pixel pattern itself. In odd-numbered pixel rows, Fastgraph rotates the original pattern one pixel (one bit) to the left.

    For example, we could create a lighter shade of white by alternating

black pixels (color 0) with white pixels (color 1), as shown here:


                                     0 1


If we convert this pixel pattern to its hexadecimal equivalent, we get the value 01. The implied one-bit shift count produces the following pixel patterns:

                          even-numbered rows   0 1
                           odd-numbered rows   1 0

Extending the pixel pattern to a 16-bit or 32-bit quantity yields the display pattern 0001 hex.

    For the VGA/MCGA two-color graphics mode, fg_setmode establishes the

initial display patterns such that all even-numbered color indices are assigned the value 0000 (two pixels of color 0), while all odd-numbered color indices are assigned the value 0003 (11 binary, or two pixels of color 1).

256-color graphics modes

    The 256-color graphics modes (modes 19 through 27) offer 262,144

different colors, so dithering is seldom (if ever) required. For this reason, fg_pattern has no effect in these video modes. �

                                                Chapter 9:  Image Files   205


An example

    Example 9-11 illustrates the use of display patterns in several graphics

modes. This program runs in any 320x200 color graphics mode and displays the CORAL.PPR image with one or more of the color indices redefined. If the program runs in the standard CGA four-color mode (mode 4), it redefines the first 16 display patterns using the fg_pattern routine and the values in the CGApatterns array. In the Tandy/PCjr 16-color graphics mode (mode 9) and the EGA low-resolution graphics mode (mode 13), the program redefines color index 15 to produce an alternating gray and white dither pattern. In the MCGA 256- color mode (mode 19), display patterns are not available, so the program uses fg_setrgb to define color index 15 as slightly darker shade of gray than the default for color 7.

                                Example 9-11.
               #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main(void);
               int CGApatterns[] = {
                  0x0000,0x00FF,0x00FF,0x00FF,
                  0x02BB,0x0000,0x0222,0x0255,
                  0x00FF,0x00FF,0x00FF,0x0055,
                  0x00AA,0x00AA,0x00FF,0x0277
                  };
               void main()
               {
                  int color;
                  int old_mode, new_mode;
                  fg_initpm();
                  new_mode = fg_bestmode(320,200,1);
                  if (new_mode < 0 || new_mode == 12) {
                     printf("This program requires a 320 ");
                     printf("x 200 color graphics mode.\n");
                     exit(1);
                     }
                  old_mode = fg_getmode();
                  fg_setmode(new_mode);
                  if (new_mode == 4) {
                     fg_palette(0,0);
                     for (color = 0; color < 16; color++)
                        fg_pattern(color,CGApatterns[color]);
                     }
                  else if (new_mode == 9 || new_mode == 13)
                     fg_pattern(15,0x04F7);
                  else
                     fg_setrgb(15,38,38,38);
                  fg_move(0,199);
                  fg_showppr("CORAL.PPR",320);                                �

206 Fastgraph User's Guide


                  fg_waitkey();
                  fg_setmode(old_mode);
                  fg_reset();
               }


Controlling the Image Buffer Size

    By default, all of Fastgraph's image file display and creation routines

use an internal 4,096-byte buffer. This buffer provides an intermediate storage area, making it possible to perform more efficient buffered I/O when reading or writing the image files. The fg_imagebuf routine lets you define your own buffer for this purpose (the buffer size is limited to 64K bytes in real mode and 16-bit protected mode). Larger buffers generally make image display and creation faster. This is especially true in protected mode and when playing flic files. Calling fg_setmode resets the fg_imagebuf buffer to its default 4K size.

    The fg_imagebuf routine does not allocate storage for the internal

buffer. Rather, it just defines the array or dynamically allocated memory block to be used as the buffer. The first argument passed to fg_imagebuf is the address of this array or memory block, and the second argument is the internal buffer size in bytes, represented as an unsigned integer. In 32-bit modes, the address is passed as an ordinary near pointer, while in 16-bit modes it is passed as a far (segmented) pointer. Fastgraph uses a far pointer in 16-bit modes to avoid wasting valuable space in the default data segment, and it almost always results in the ability to use a larger buffer. In real mode Pascal programs, the space for the internal buffer must be allocated dynamically with the GetMem procedure because it provides the only way to pass something by far reference in Pascal. Protected mode Pascal programs can use either GetMem or the GlobalAllocPtr function to allocate the buffer memory. BASIC programs must pass the image buffer as a fixed-length string.

    Example 9-12 shows how to use fg_imagebuf to define a larger buffer when

displaying the CORAL.PCX file. In this example, we'll use a 20,000-byte static array as the image buffer. This size was chosen because it's larger than the PCX file size, so fg_showpcx can read the entire PCX file in one pass.

                                Example 9-12.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                #ifdef FG32
                char buffer[20000];
                #else
                char far buffer[20000];
                #endif
                void main()
                {
                   int old_mode;                                              �
                                                Chapter 9:  Image Files   207


                   fg_initpm();
                   if (fg_testmode(19,1) == 0) {
                      printf("This program requires a 320 ");
                      printf("x 200 MCGA graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(19);
                   fg_imagebuf(buffer,20000);
                   fg_showpcx("CORAL.PCX",0);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    You don't need to create separate buffers for each image you display or

create. Once you define an internal image buffer with fg_imagebuf, Fastgraph will use that buffer until your program exits, or until you call fg_imagebuf with a buffer size equal to zero.

    It's also possible to display PCX, GIF, and FLI/FLC images directly from

the buffer pointed to by fg_imagebuf. This can be quite useful, for instance, when we need to display the same image file several times because we only read the file from disk once. To do this, set bit 2 of the flags parameter when using Fastgraph's PCX, GIF, or FLI/FLC image display routines. This tells Fastgraph to retrieve the image data from the fg_imagebuf buffer rather than from the file itself. In protected mode applications, using this method usually provides better performance, especially when displaying FLI or FLC files. Example 9-13 shows how to display a PCX image stored in the fg_imagebuf buffer.

                                Example 9-13.
              #include <fastgraf.h>
              #include <io.h>
              #include <stdio.h>
              #include <stdlib.h>
              void main(void);
              #ifdef FG32
              char buffer[20000];
              #else
              char far buffer[20000];
              #endif
              void main()
              {
                 int file_size;
                 int old_mode;
                 FILE *stream;
                 fg_initpm();
                 if (fg_testmode(19,1) == 0) {                                �

208 Fastgraph User's Guide


                    printf("This program requires a 320 ");
                    printf("x 200 MCGA graphics mode.\n");
                    exit(1);
                    }
                 stream = fopen("CORAL.PCX","rb");
                 file_size = (int)(filelength(fileno(stream)));
                 fread(buffer,1,file_size,stream);
                 fclose(stream);
                 old_mode = fg_getmode();
                 fg_setmode(19);
                 fg_imagebuf(buffer,file_size);
                 fg_showpcx("",4);
                 fg_waitkey();
                 fg_setmode(old_mode);
                 fg_reset();
              }


    In example 9-13, we use a 20,000-byte array for the fg_imagebuf buffer.

The array used with fg_imagebuf must be large enough to hold the entire image file. Note that we pass the actual file size to fg_imagebuf (in this example, we assume the file size does not exceed 20,000 bytes). It is crucial that you specify the actual file size when displaying 256-color PCX files so Fastgraph can locate the extended (256-color) palette data that might follow the image data. You must also specify the actual file size when using Fastgraph's low- level flic support routines to play flic images from the fg_imagebuf buffer. For other types of image files, we can specify either the file size or the buffer size.

    It's not necessary to pass a file name to the image display routines if

the image data resides in the fg_imagebuf buffer. In other words, the image display routines ignore the file name argument when bit 2 of the flags argument is set. However, you must still include a "place holder" argument where a file name would otherwise be expected. We recommend using the null string as in the fg_showpcx call of example 9-13, although any string can be used instead.

    The maximum size of the image file we can display from the fg_imagebuf

buffer is of course limited to the buffer size. While this isn't in issue in 32-bit protected mode, it does impose an important restriction in real mode and 16-bit protected mode. The size of the fg_imagebuf buffer is limited to 64K bytes in 16-bit environments, meaning this feature applies only to image files that are 64K or less if you're using real mode or 16-bit protected mode.


Summary of Image File Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual. The image display and creation functions apply only to graphics video modes. �

                                                Chapter 9:  Image Files   209


    FG_DISPFILE displays an image stored in a standard or packed pixel run

file. The image is positioned so that its lower left corner is at the current graphics position.

    FG_FLICDONE closes the flic file associated with the specified context

descriptor.

    FG_FLICHEAD reads a flic file header into a 128-byte buffer.
    FG_FLICMODE determines the optimal video mode for the flic image

associated with the specified flic file header. The optimal mode is the 256- color graphics mode having the lowest resolution larger than or equal to the image dimensions.

    FG_FLICOPEN opens a flic file for subsequent processing by Fastgraph's

other low-level flic file support routines. If successful, the file pointer will be positioned at the beginning of the first frame.

    FG_FLICPLAY displays the next one or more frames in a flic file

previously opened with fg_flicopen.

    FG_FLICSIZE returns the dimensions for the flic image associated with the

specified flic file header.

    FG_FLICSKIP advances one or more frames in a flic file previously opened

with fg_flicopen. If the last frame played by fg_flicplay displayed the frame from the fg_imagebuf buffer, the frame position will be adjusted in the fg_imagebuf buffer. Otherwise, the flic file position itself will be adjusted.

    FG_GIFHEAD reads the GIF file's global header and first local header into

a 23-byte buffer.

    FG_GIFMODE determines the optimal video mode for displaying a GIF file.

The optimal mode is the video mode having the lowest resolution larger than or equal to the image dimensions.

    FG_GIFPAL retrieves the palette of an image stored in a GIF file. The

palette values are returned as RGB color components, each between 0 and 63. If the GIF file includes a local palette for the first image, fg_gifpal will return the values from the local palette. Otherwise, fg_gifpal will return the values from the GIF file's global palette.

    FG_GIFRANGE returns the image extents for the GIF image associated with

the specified GIF file header.

    FG_IMAGEBUF specifies the size and address of the buffer used internally

when creating or displaying GIF, PCX, FLI/FLC, or SPR/PPR files. Fastgraph's default internal buffer size is 4,096 bytes. Image display or creation is typically faster when a larger buffer is used, especially in protected mode or when playing flic files. In 16-bit environments, the size of the fg_imagebuf buffer is limited to 64K bytes.

    FG_LOADPCX loads a PCX image into the active virtual buffer.              �

210 Fastgraph User's Guide


    FG_MAKEGIF creates a GIF file from the specified rectangular region of

the active video page or virtual buffer. The region's extremes are expressed in screen space units. This routine is meaningful only in 16-color and 256- color graphics modes.

    FG_MAKEPCX creates a PCX file from the specified rectangular region of

the active video page or virtual buffer. The region's extremes are expressed in screen space units.

    FG_MAKEPPR creates a packed pixel run file from the specified rectangular

region of the active video page or virtual buffer. The region's extremes are expressed in screen space units.

    FG_MAKESPR creates a standard pixel run file from the specified

rectangular region of the active video page or virtual buffer. The region's extremes are expressed in screen space units.

    FG_PATTERN defines a display pattern for use when displaying pixel run

files in video modes that offer 16 or less colors.

    FG_PCXHEAD reads a PCX file header into a 128-byte buffer.
    FG_PCXMODE determines the optimal video mode for displaying a PCX file.

The optimal mode is the compatible video mode having the lowest resolution larger than or equal to the image dimensions.

    FG_PCXPAL retrieves the palette of an image stored in a PCX file, and the

number of colors in the palette. The palette values are returned as RGB color components, each between 0 and 63. If the PCX file includes an extended (256-color) palette, fg_pcxpal will return the values in the extended palette. Otherwise, fg_pcxpal will return the values from the 16-color palette in the PCX header.

    FG_PCXRANGE returns the image extents for the PCX image associated with

the specified PCX file header.

    FG_SHOWGIF displays an image stored in a GIF file.
    FG_SHOWFLIC displays an image stored in an FLI or FLC file (collectively

called flic files).

    FG_SHOWPCX displays an image stored in a PCX file.
    FG_SHOWPPR displays an image stored in a packed pixel run file. The image

will be positioned so its lower left corner is at the graphics cursor position of the active video page or virtual buffer.

    FG_SHOWSPR displays an image stored in a standard pixel run file. The

image will be positioned so its lower left corner is at the graphics cursor position of the active video page or virtual buffer.




Chapter 10



Bitmapped Images � 212 Fastgraph User's Guide


Overview

    In this chapter, we'll continue our discussion of images by concentrating

on an important class of images called bitmapped images. Fastgraph includes routines to display, retrieve, and manipulate bitmapped images in mode- specific and mode-independent formats. This chapter will discuss the Fastgraph routines that deal with both classes of bitmapped images.

    Displaying bitmapped images is an essential part of animation with

Fastgraph. While the image files discussed in the previous chapter are useful for displaying backgrounds or importing pictures from other sources, an animation sequence can only achieve its speed through the bitmapped image display routines described in this chapter, along with the block transfer routines of the next chapter.


Mode-Independent Bitmapped Images

    This section will discuss the image display routines that use the same

bitmapped image format for all graphics video modes. Another class of routines, described in the next section, use different formats for different video modes. While these mode-independent image display routines are more general, they achieve this generality at the sake of execution speed. This may especially be a concern if the image is large, or if speed is critical in an application (as in arcade-style graphics). For many programs, however, the mode-independent routines provide all the image display capability needed.

    Let's begin by returning to an example of a very simple image -- the

triangle introduced in the previous chapter:

                              . . . . * . . . .
                              . . . * x * . . .
                              . . * x x x * . .
                              . * x x x x x * .
                              * * * * * * * * *

Recall that the triangle's perimeter is a different color than its interior pixels, and to use this image with Fastgraph, we must inscribe the triangle in a rectangular area. As before, our triangle is nine pixels wide at its base and five pixels high. The pixels indicated by an asterisk (*) are the triangle's perimeter, while those indicated by an x represent its interior points. We need to distinguish between these pixels because they will be different colors. The pixels shown as periods (.) are not part of the triangle itself. They are required to make the image rectangular, so from Fastgraph's perspective they are indeed part of the image.

    The Fastgraph routine fg_drawmap is a suitable routine for drawing our

triangle. To use fg_drawmap, we must create separate bitmaps for each color in the image (excluding the points used to fill the rectangular region, which are considered transparent). In this example, we will thus need two bitmaps -- one for the perimeter points, and one for the interior points. Let's break the image into these two bitmaps. �

                                          Chapter 10:  Bitmapped Images   213


                 . . . . * . . . .        . . . . . . . . .
                 . . . * . * . . .        . . . . x . . . .
                 . . * . . . * . .        . . . x x x . . .
                 . * . . . . . * .        . . x x x x x . .
                 * * * * * * * * *        . . . . . . . . .
                 perimeter points          interior points
    The next step is to convert these two bitmaps into their binary

representations. Just as there are eight bits in a byte, we will create a data structure (an array in this case) with each byte holding eight pixels. Bits that are set (1) indicate the corresponding pixel will appear displayed in the color associated with that bitmap. Bits that are reset (0) leave the corresponding pixel unchanged. The size of each bitmap array must be at least 10 bytes because each bitmap contains five rows with nine pixels in each row (that is, two bytes are required for each row of the image). Hence, when we convert these bitmaps to their binary representations, and subsequently to their hexadecimal equivalent, the results will appear as shown here. The boldface bits represent the actual image; the other bits are filler bits needed to complete each row of the bitmaps after the ninth pixel. All filler bits must be zero.


              0 0 0 0 1 0 0 0   0 0 0 0 0 0 0 0         08   00
              0 0 0 1 0 1 0 0   0 0 0 0 0 0 0 0         14   00
              0 0 1 0 0 0 1 0   0 0 0 0 0 0 0 0         22   00
              0 1 0 0 0 0 0 1   0 0 0 0 0 0 0 0         41   00
              1 1 1 1 1 1 1 1   1 0 0 0 0 0 0 0         FF   80
                              perimeter bitmap


              0 0 0 0 0 0 0 0   0 0 0 0 0 0 0 0         00   00
              0 0 0 0 1 0 0 0   0 0 0 0 0 0 0 0         08   00
              0 0 0 1 1 1 0 0   0 0 0 0 0 0 0 0         1C   00
              0 0 1 1 1 1 1 0   0 0 0 0 0 0 0 0         3E   00
              0 0 0 0 0 0 0 0   0 0 0 0 0 0 0 0         00   00
                               interior bitmap
    The next matter is the order in which the bitmaps are stored in the

corresponding data structures. Since our data structure is an array, it is only necessary to show the relationship of the subscripts to the bitmap structures above. The next diagram shows the subscript order for the case of a two-column by five-row bitmap.


                                  [8]   [9]                                   �

214 Fastgraph User's Guide


                                  [6]   [7]
                                  [4]   [5]
                                  [2]   [3]
                                  [0]   [1]


    From this diagram, we see the first element of the array (that is, the

element with subscript [0]) represents the lower left corner of the image. The subscript progression then continues right until reaching the end of the first row. It then resumes at the leftmost element of the second row and continues to the right until the end of that row. It continues in this manner for all remaining rows.

    We are now ready to present an example program to display our triangle.

The program will use the Fastgraph routine fg_drawmap, which expects three arguments. The first argument is the bitmap array (passed by reference), the second is the width of the bitmap in bytes, and the last is the height of the bitmap in pixel rows. The fg_drawmap routine displays the image such that its lower left corner is at the graphics cursor position on the active video page. The routine has no effect in text video modes. Additionally, fg_drawmap displays the image using the current color index, which means we will need to call fg_drawmap once for each color in the image.

    Example 10-1 runs in any 320x200 color graphics mode (it could be made to

run in mode 12 too, but that would detract from the purpose of the example). After establishing the video mode, the program uses fg_rect to fill the entire screen with a gray rectangle (white in CGA). Next, the program establishes (156,101) as the graphics cursor position; this causes the triangle to be centered on the screen. The two calls to fg_drawmap, one for each color in the image, actually display the triangle. Note especially how fg_setcolor is used before each call to fg_drawmap to define the current color index. The result is a triangle with a blue perimeter (cyan in CGA) and green interior (magenta in CGA).

                                Example 10-1.
            #include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
            void main(void);
            char perimeter[] = {
               0xFF,0x80,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00
               };
            char interior[] = {
               0x00,0x00,0x3E,0x00,0x1C,0x00,0x08,0x00,0x00,0x00
               };
            void main()
            {
               int old_mode, new_mode;                                        �
                                          Chapter 10:  Bitmapped Images   215


               fg_initpm();
               new_mode = fg_bestmode(320,200,1);
               if (new_mode < 0 || new_mode == 12) {
                  printf("This program requires a 320 ");
                  printf("x 200 color graphics mode.\n");
                  exit(1);
                  }
               old_mode = fg_getmode();
               fg_setmode(new_mode);
               fg_setcolor(7);
               fg_rect(0,319,0,199);
               fg_move(156,101);
               fg_setcolor(1);
               fg_drawmap(perimeter,2,5);
               fg_setcolor(2);
               fg_drawmap(interior,2,5);
               fg_waitkey();
               fg_setmode(old_mode);
               fg_reset();
            }


    We should mention that fg_drawmap does not perform clipping when

displaying an image. If you want the image to be constrained by the current clipping limits, use fg_clipmap instead of fg_drawmap. The fg_clipmap routine takes the same three arguments as fg_drawmap, but it is not as fast as fg_drawmap because of the additional overhead required when performing the image clipping.

    The different color bitmaps used by fg_drawmap do not all have to be the

same size. In our triangle example, the perimeter is 9 pixels wide by 5 pixels high, but the interior is only 5 pixels wide by 3 pixels high. Hence, the bitmap for the interior pixels only requires one byte for each of its three rows, so we can store it in a three-byte array. Its structure would be:


                                 [2]   08
                                 [1]   1C
                                 [0]   3E


    Example 10-2 is similar to example 10-1, but it uses a three-byte array

for the interior bitmap. Note the second call to fg_move in this example. It is needed because the bottom row of the smaller interior bitmap corresponds to the second row of the larger perimeter bitmap. In other words, the interior bitmap must be displayed one row above the perimeter bitmap.

                                Example 10-2.
            #include <fastgraf.h>                                             �

216 Fastgraph User's Guide


            #include <stdio.h>
            #include <stdlib.h>
            void main(void);
            char perimeter[] = {
               0xFF,0x80,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00
               };
            char interior[] = {
               0x3E,0x1C,0x08
               };
            void main()
            {
               int old_mode, new_mode;
               fg_initpm();
               new_mode = fg_bestmode(320,200,1);
               if (new_mode < 0 || new_mode == 12) {
                  printf("This program requires a 320 ");
                  printf("x 200 color graphics mode.\n");
                  exit(1);
                  }
               old_mode = fg_getmode();
               fg_setmode(new_mode);
               fg_setcolor(7);
               fg_rect(0,319,0,199);
               fg_move(156,101);
               fg_setcolor(1);
               fg_drawmap(perimeter,2,5);
               fg_move(156,100);
               fg_setcolor(2);
               fg_drawmap(interior,1,3);
               fg_waitkey();
               fg_setmode(old_mode);
               fg_reset();
            }


    In example 10-2, the time required to execute the second call to fg_move

may not be worth the saving of 7 bytes. When array space is critical, or when the images are larger, the use of smaller bitmaps for certain colors may be more valuable.

    Yet another possibility for example 10-2 would be to shift the elements

of the interior bitmap two pixels to the left. In this way, the bitmap would be aligned against the left side of the array, as the perimeter bitmap is. The three values comprising the interior bitmap would then become F8, 70, and 20. We also would need to change the x coordinate in the second call to fg_move from 156 to 158. �

                                          Chapter 10:  Bitmapped Images   217


Mode-Specific Bitmapped Images

    This section will discuss the image display routines that use bitmapped

image formats specific to each text and graphics video mode. The different image formats closely resemble the structure of video memory in each mode, so these routines are much faster than displaying mode-independent bitmaps with fg_drawmap. If you use the mode-specific bitmaps in a program that supports several video modes, there will be some additional programming that is not needed when using mode-independent bitmaps. Usually, however, your efforts will be rewarded with significantly faster graphics.

    We'll demonstrate the use of mode-specific bitmaps in graphics modes with

the familiar two-color triangle whose pixel representation appears below.

                              . . . . * . . . .
                              . . . * x * . . .
                              . . * x x x * . .
                              . * x x x x x * .
                              * * * * * * * * *
    As before, our triangle is nine pixels wide at its base and five pixels

high. The pixels indicated by an asterisk (*) are the triangle's perimeter, while those indicated by an x represent its interior points. We need to distinguish between these pixels because they will be different colors. The pixels shown as periods (.) are not part of the triangle itself. They are required to make the image rectangular, so from Fastgraph's perspective they are indeed part of the image.


Regular Images

    The Fastgraph routine fg_drwimage displays regular mode-specific

bitmapped images (by regular, we mean an image that is neither clipped nor rotated). Its arguments and the bitmap array's subscript order are the same as for fg_drawmap. The major difference is the bitmap structure -- we combine the information for all colors into a single bitmap, in a way consistent with the structure of video memory for the various modes. As with the other image display routines, fg_drwimage displays the image on the active video page or virtual buffer with its lower left corner at the graphics cursor position (or the text cursor position for text modes). We'll now examine the use of fg_drwimage in several video modes.

CGA four-color graphics modes

    In the four-color CGA graphics modes (modes 4 and 5), each pixel can

assume a value between 0 and 3. This means it takes two bits to represent a pixel, or put another way, each byte of video memory holds four pixels. Our triangle image is nine pixels wide, so three bytes are needed for each row of the image. Because the image is five pixels high, we need a bitmap array of at least 15 bytes (five rows times three bytes per row) to hold the image.

    The image's binary representation and its hexadecimal equivalent for the

four-color CGA graphics modes are shown here. The binary values in boldface represent the actual image; the others are the filler bits needed to complete each row of the bitmap after the ninth pixel. We have coded the perimeter � 218 Fastgraph User's Guide


pixels to be color 1 (01 binary) and the interior pixels to be color 2 (10 binary). Any pixel whose value is zero (00 binary) is transparent and will thus leave the contents of video memory at that position unchanged.


        00 00 00 00   01 00 00 00   00 00 00 00         00   40   00
        00 00 00 01   10 01 00 00   00 00 00 00         01   90   00
        00 00 01 10   10 10 01 00   00 00 00 00         06   A4   00
        00 01 10 10   10 10 10 01   00 00 00 00         1A   A9   00
        01 01 01 01   01 01 01 01   01 00 00 00         55   55   40


    Example 10-3 uses this mode-specific bitmap to display the triangle in

the standard CGA four-color graphics mode (mode 4). After establishing the video mode, the program uses fg_rect to fill the entire screen with a white rectangle. Next, the program establishes (156,101) as the graphics cursor position; this causes the triangle to be centered on the screen. The call to fg_drwimage produces a triangle with a cyan perimeter (color 1) and a magenta interior (color 2).

                                Example 10-3.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             char triangle[] = {
                0x55,0x55,0x40, 0x1A,0xA9,0x00, 0x06,0xA4,0x00,
                0x01,0x90,0x00, 0x00,0x40,0x00
                };
             void main()
             {
                int old_mode;
                fg_initpm();
                if (fg_testmode(4,1) == 0) {
                   printf("This program requires a 320 ");
                   printf("x 200 CGA graphics mode.\n");
                   exit(1);
                   }
                old_mode = fg_getmode();
                fg_setmode(4);
                fg_setcolor(7);
                fg_rect(0,319,0,199);
                fg_move(156,101);
                fg_drwimage(triangle,3,5);
                fg_waitkey();                                                 �
                                          Chapter 10:  Bitmapped Images   219


                fg_setmode(old_mode);
                fg_reset();
             }


CGA two-color graphics mode

    In the two-color CGA graphics mode (mode 6), each pixel can assume the

values 0 or 1. This means it takes just one bit to represent a pixel, so each byte of video memory holds eight pixels. Our triangle image is nine pixels wide, so two bytes are needed for each row of the image. Because the image is five pixels high, we need a bitmap array of at least 10 bytes (five rows times two bytes per row) to hold the image.

    The image's binary representation and its hexadecimal equivalent for the

two-color CGA graphics mode are shown here. The binary values in boldface represent the actual image; the others are the filler bits needed to complete each row of the bitmap after the ninth pixel. We have coded both the perimeter pixels and the interior pixels to be color 1. Any pixel whose value is zero is transparent and will thus leave the contents of video memory at that position unchanged.


              0 0 0 0 1 0 0 0   0 0 0 0 0 0 0 0         08   00
              0 0 0 1 1 1 0 0   0 0 0 0 0 0 0 0         1C   00
              0 0 1 1 1 1 1 0   0 0 0 0 0 0 0 0         3E   00
              0 1 1 1 1 1 1 1   0 0 0 0 0 0 0 0         7F   00
              1 1 1 1 1 1 1 1   1 0 0 0 0 0 0 0         FF   80


    Example 10-4 uses this mode-specific bitmap to display the triangle in

the CGA two-color graphics mode (mode 6). After establishing the video mode, the program establishes (316,101) as the graphics cursor position; this causes the triangle to be centered on the screen. The call to fg_drwimage produces a solid triangle.

                                Example 10-4.
                  #include <fastgraf.h>
                  #include <stdio.h>
                  #include <stdlib.h>
                  void main(void);
                  char triangle[] = {
                     0xFF,0x80, 0x7F,0x00, 0x3E,0x00,
                     0x1C,0x00, 0x08,0x00
                     };
                  void main()
                  {
                     int old_mode;                                            �

220 Fastgraph User's Guide


                     fg_initpm();
                     if (fg_testmode(6,1) == 0) {
                        printf("This program requires a ");
                        printf("CGA graphics mode.\n");
                        exit(1);
                        }
                     old_mode = fg_getmode();
                     fg_setmode(6);
                     fg_move(316,101);
                     fg_drwimage(triangle,2,5);
                     fg_waitkey();
                     fg_setmode(old_mode);
                     fg_reset();
                  }


Tandy/PCjr 16-color graphics mode

    The structure of mode-specific bitmaps for the Tandy/PCjr 16-color

graphics mode (mode 9) is the same as the mode-specific bitmap structure for the EGA/VGA/SVGA 16-color graphics modes discussed later in this section.

Hercules graphics modes

    The structure of mode-specific bitmaps for the Hercules graphics modes

(modes 11 and 12) is the same as two of the CGA graphics modes. For the standard Hercules graphics mode (mode 11), please refer to the discussion of CGA two-color (mode 6) bitmaps. For the low-resolution Hercules graphics mode (mode 12), please refer to the discussion of the CGA four-color (mode 4) bitmaps.

EGA/VGA/SVGA 16-color graphics modes

    In the native EGA and VGA graphics modes (modes 13 through 18) and the

16-color SVGA graphics modes (modes 28 and 29), each pixel can assume a value between 0 and 15. This means it takes four bits to represent a pixel, so each byte of the bitmap holds two pixels. Our triangle image is nine pixels wide, so five bytes are needed for each row of the image. Because the image is five pixels high, we need a bitmap array of at least 25 bytes (five rows times five bytes per row) to hold the image.

    In these modes, it is easy to develop the hexadecimal representation of a

bitmap without first producing its binary equivalent. This is because a pixel value and a hexadecimal digit each occupy four bits. The triangle's hexadecimal representation for these video modes is shown here. The pixels in boldface represent the actual image; the others are the filler values needed to complete each row of the bitmap after the ninth pixel. We have chosen to display the perimeter pixels in color 1 and the interior pixels in color 2. Any pixel whose value is zero is transparent and will thus leave the contents of video memory at that position unchanged. �

                                          Chapter 10:  Bitmapped Images   221


                           00   00   10   00   00
                           00   01   21   00   00
                           00   12   22   10   00
                           01   22   22   21   00
                           11   11   11   11   10


    Example 10-5 is similar to example 10-3, but it uses the 320x200 EGA

graphics mode (mode 13) and the mode-specific bitmap just constructed to display the triangle. The call to fg_drwimage produces a triangle with a blue perimeter (color 1) and a green interior (color 2).

                                Example 10-5.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                char triangle[] = {
                   0x11,0x11,0x11,0x11,0x10,
                   0x01,0x22,0x22,0x21,0x00,
                   0x00,0x12,0x22,0x10,0x00,
                   0x00,0x01,0x21,0x00,0x00,
                   0x00,0x00,0x10,0x00,0x00
                   };
                void main()
                {
                   int old_mode;
                   fg_initpm();
                   if (fg_testmode(13,1) == 0) {
                      printf("This program requires a 320 ");
                      printf("x 200 EGA graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(13);
                   fg_setcolor(7);
                   fg_rect(0,319,0,199);
                   fg_move(156,101);
                   fg_drwimage(triangle,5,5);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }                                                             �

222 Fastgraph User's Guide


256-color graphics modes

    In 256-color graphics modes (modes 19 through 27), each pixel can assume

a value between 0 and 255 (FF hex). This means it takes eight bits to represent a pixel, or each byte of video memory holds one pixel. Our triangle image is nine pixels wide, so nine bytes are needed for each row of the image. Because the image is five pixels high, we need a bitmap array of at least 45 bytes (five rows times nine bytes per row) to hold the image. Note we will never need any filler bits in the 256-color video modes.

    It is especially simple to develop the bitmap for an image in the 256-

color modes because each byte holds exactly one pixel. The triangle's hexadecimal representation for the 256-color graphics modes is shown here. As before, we have coded the perimeter pixels to be color 1 (01 hex) and the interior pixels to be color 2 (02 hex). Any pixel whose value is zero is transparent and will thus leave the contents of video memory at that position unchanged.


                 00   00   00   00   01   00   00   00   00
                 00   00   00   01   02   01   00   00   00
                 00   00   01   02   02   02   01   00   00
                 00   01   02   02   02   02   02   01   00
                 01   01   01   01   01   01   01   01   01


    Example 10-6 is also similar to example 10-3, but it uses the MCGA 256-

color graphics mode (mode 19) and the mode-specific bitmap just constructed to display the triangle. The call to fg_drwimage produces a triangle with a blue perimeter (color 1) and a green interior (color 2).

                                Example 10-6.
              #include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
              void main(void);
              char triangle[] = {
                 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
                 0x00,0x01,0x02,0x02,0x02,0x02,0x02,0x01,0x00,
                 0x00,0x00,0x01,0x02,0x02,0x02,0x01,0x00,0x00,
                 0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,
                 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00
                 };
              void main()
              {
                 int old_mode;
                 fg_initpm();                                                 �
                                          Chapter 10:  Bitmapped Images   223


                 if (fg_testmode(19,1) == 0) {
                    printf("This program requires a 320 ");
                    printf("x 200 MCGA graphics mode.\n");
                    exit(1);
                    }
                 old_mode = fg_getmode();
                 fg_setmode(19);
                 fg_setcolor(7);
                 fg_rect(0,319,0,199);
                 fg_move(156,101);
                 fg_drwimage(triangle,9,5);
                 fg_waitkey();
                 fg_setmode(old_mode);
                 fg_reset();
              }


    Sometimes you may need to include black pixels that are not transparent

in a mode-specific bitmapped image. The easiest way to do this is to use fg_putimage, which we'll describe shortly. Another possibility is using fg_palette or fg_setrgb to make an unused color index black and then use that color index for non-transparent black pixels. For example, calling fg_palette(8,0) in a 16-color graphics mode would display color 8 pixels as black. Similarly, fg_setrgb(248,0,0,0) in a 256-color graphics mode would display color 248 pixels as black. The choice of colors 8 and 248 in these examples is arbitrary; any unused color will do. Yet another possibility is to use the masking maps discussed later in this chapter.

Virtual Buffers

         The structure of mode-specific bitmaps for virtual buffers is the

same as the mode-specific bitmap structure for 256-color graphics modes discussed in the previous section.

Text Modes

    You also can use the fg_drwimage routine to display images in text video

modes (modes 0, 1, 2, 3, and 7). As one might expect, the image structure in the text modes is rather different from the graphics modes. In Chapter 5 we saw that each character cell on the screen actually consists of a character and an attribute. The character value determines what character is displayed, while the attribute value controls the character's appearance. The structure of the attribute is:

                      bits         attribute
                       0-3     foreground color
                       4-6     background color
                        7          blinking
    The text mode image structure used with fg_drwimage also consists of a

series of characters and attributes. For example, the following diagram � 224 Fastgraph User's Guide


illustrates the structure of an image that is three characters wide and two characters high.


                   char   attr   char   attr   char   attr
                   char   attr   char   attr   char   attr


    To illustrate the use of fg_drwimage in a text video mode, we'll display

the phrase "hello there" on two different lines in the center of the screen. Furthermore, let's assume we would like the first character of each word to appear in foreground color 1, the second in color 2, and so forth. Our image will consist of two lines each containing five characters, and each character requires two bytes of storage (one for the character and another for its attribute), so we'll need a 20-byte array for holding the image. The array really doesn't hold a bitmap as in the graphics modes, so in the text modes the first argument passed to fg_drwimage is instead called the image array. In our example, the structure of the image array is:


          'h'    1    'e'    2    'l'    3    'l'    4    'o'    5
          't'    1    'h'    2    'e'    3    'r'    4    'e'    5


The subscript order that fg_drwimage uses for text modes is the same as for the graphics modes. For our five-row by two-column image, this means the array subscripts would be numbered as follows:


              [10] [11] [12] [13] [14] [15] [16] [17] [18] [19]
               [0]  [1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]  [9]


    Depending on the character and attribute values in the image array,

fg_drwimage can display new characters and attributes, new characters leaving the existing attribute unchanged, new attributes leaving the existing character unchanged, or leave both the existing character and attribute unchanged in video memory. To keep an existing character or attribute, simply specify a value of 0 in the corresponding element of the image array. This capability is analogous to the fact that zero-valued pixels in graphics mode bitmaps leave video memory unchanged.

    Example 10-7 demonstrates the use of fg_drwimage in the 80-column color

text mode (mode 3). After establishing the video mode and making the cursor invisible, the program calls fg_drwimage to display the "hello there" image just discussed (note we pass the dimensions of the image array as the number of bytes, not the number of characters). The program waits for a keystroke and then calls fg_drwimage again, passing a different image array (called "image") of the same size. This array changes the first letter of both words from lower case to upper case (leaving the attribute unchanged), and it makes the remaining characters have the same attribute as the first character. This is done in part by using zero-valued characters and attributes to leave video memory unchanged. After waiting for another keystroke, the program exits. �

                                          Chapter 10:  Bitmapped Images   225


                                Example 10-7.
                    #include <fastgraf.h>
                    void main(void);
                    char hello[] = {
                       't',1, 'h',2, 'e',3, 'r',4, 'e',5,
                       'h',1, 'e',2, 'l',3, 'l',4, 'o',5
                       };
                    char image[] = {
                       'T',0, 0,1, 0,1, 0,1, 0,1,
                       'H',0, 0,1, 0,1, 0,1, 0,1
                       };
                    void main()
                    {
                       int old_mode;
                       fg_initpm();
                       old_mode = fg_getmode();
                       fg_setmode(3);
                       fg_cursor(0);
                       fg_locate(12,37);
                       fg_drwimage(hello,10,2);
                       fg_waitkey();
                       fg_drwimage(image,10,2);
                       fg_waitkey();
                       fg_setmode(old_mode);
                       fg_reset();
                    }


Clipped Images

    The fg_drwimage routine does not perform clipping when displaying an

image. If you want the image to be constrained by the clipping limits (as established by the most recent call to fg_setclip), use fg_clpimage instead of fg_drwimage. The fg_clpimage routine takes the same three arguments as fg_drwimage and also displays the image such that its lower left corner is at the graphics cursor position. Unlike fg_drwimage, the fg_clpimage routine has no effect when used in a text video mode. Because of the additional overhead involved in checking the clipping limits, fg_clpimage is not as fast as fg_drwimage.


Reversed Images

    The fg_revimage routine displays an image reversed (that is, mirrored

about the y-axis) without clipping. It takes the same three arguments as fg_drwimage and also displays the image such that its lower left corner is at � 226 Fastgraph User's Guide


the graphics cursor position. The fg_revimage routine has no effect when used in a text video mode.


Reversed Clipped Images

    The fg_flpimage routine combines the effects of the fg_revimage and

fg_clpimage routines -- it displays a reversed image constrained by the current clipping limits. It takes the same three arguments as fg_drwimage and also displays the image such that its lower left corner is at the graphics cursor position. Like the fg_clpimage routine, fg_flpimage has no effect when used in a text video mode.


Images Without Transparent Pixels

    The fg_putimage routine is the same as fg_drwimage except it does not

consider color 0 pixels to be transparent. Because it does not need to check for transparent pixels, fg_putimage is faster than fg_drwimage. Using fg_putimage is recommended for cases where transparency is not an issue.


Some Examples

    Example 10-8 illustrates the use of fg_drwimage, fg_clpimage,

fg_revimage, fg_flpimage, and fg_putimage in the standard CGA four-color graphics mode (mode 4). The program uses each of these routines to display a small white arrow, as shown in this pixel map:

                             . . . . . . * . . .
                             . . . . . . * * . .
                             * * * * * * * * * .
                             * * * * * * * * * *
                             * * * * * * * * * .
                             . . . . . . * * . .
                             . . . . . . * . . .

As before, we must first convert this image to a bitmap. The image is ten pixels wide and seven high. In mode 4, each pixel occupies two bits, so we need a 21-byte array (7 rows by 3 columns) to store the image. Since we want to make the arrow white, each pixel will be displayed in color 3 (11 binary). Here is the bitmap and its hexadecimal equivalent for the arrow image in mode 4 (the actual image is in boldface).


        00 00 00 00   00 00 11 00   00 00 00 00         00   0C   00
        00 00 00 00   00 00 11 11   00 00 00 00         00   0F   00
        11 11 11 11   11 11 11 11   11 00 00 00         FF   FF   C0
        11 11 11 11   11 11 11 11   11 11 00 00         FF   FF   F0
        11 11 11 11   11 11 11 11   11 00 00 00         FF   FF   C0
        00 00 00 00   00 00 11 11   00 00 00 00         00   0F   00          �
                                          Chapter 10:  Bitmapped Images   227


        00 00 00 00   00 00 11 00   00 00 00 00         00   0C   00


    After establishing the video mode, the program fills the screen with

color 1 pixels and defines a clipping region. It then uses fg_drwimage to display the arrow pointing to the right and fg_clpimage to do the same thing, but with respect to the clipping limits. Because the left edge of the arrow is displayed at x=10 and the right clipping limit is at x=15, the call to fg_clpimage only draws the first six columns of the arrow (that is, it does not draw the arrow head).

    Next, example 10-8 uses fg_revimage to display the arrow pointing to the

left. To allow for the filler pixels, we must establish the graphics cursor position two pixels to the left of the position used by fg_drwimage if we want the tip of the left-pointing arrow to align with the tail of the right- pointing arrow. The program then uses fg_flpimage to display an arrow pointing to the left with regard to the clipping limits. The call to fg_flpimage displays the arrow head and the first two columns of the arrow shaft. Finally, the program uses fg_putimage to display the unclipped right-pointing arrow without transparent pixels (this produces a black border around the arrow).

                                Example 10-8.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             char arrow[] = {
                0x00,0x0C,0x00, 0x00,0x0F,0x00, 0xFF,0xFF,0xC0,
                0xFF,0xFF,0xF0, 0xFF,0xFF,0xC0, 0x00,0x0F,0x00,
                0x00,0x0C,0x00
                };
             void main()
             {
                int old_mode;
                fg_initpm();
                if (fg_testmode(4,1) == 0) {
                   printf("This program requires a 320 ");
                   printf("x 200 CGA graphics mode.\n");
                   exit(1);
                   }
                old_mode = fg_getmode();
                fg_setmode(4);
                fg_setcolor(1);
                fg_fillpage();
                fg_setclip(0,15,0,199);
                fg_move(10,10);
                fg_drwimage(arrow,3,7);
                fg_move(10,20);
                fg_clpimage(arrow,3,7);                                       �

228 Fastgraph User's Guide


                fg_move(8,30);
                fg_revimage(arrow,3,7);
                fg_move(8,40);
                fg_flpimage(arrow,3,7);
                fg_move(8,50);
                fg_putimage(arrow,3,7);
                fg_waitkey();
                fg_setmode(old_mode);
                fg_reset();
             }


    Example 10-9 is the same as example 10-8, but it uses the low resolution

EGA graphics mode (mode 13). If we changed the mode number specified in the calls to fg_testmode and fg_setmode, the program also would run in any 16- color graphics mode. In these modes, we store two pixels per byte in the bitmap array, so we need a 35-byte array (7 rows by 5 columns) to store the image. Here is the bitmap's hexadecimal equivalent for the arrow image in mode 13, followed by the program to display it.


                           00   00   00   F0   00
                           00   00   00   FF   00
                           FF   FF   FF   FF   F0
                           FF   FF   FF   FF   FF
                           FF   FF   FF   FF   F0
                           00   00   00   FF   00
                           00   00   00   F0   00


                                Example 10-9.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                char arrow[] = {
                   0x00,0x00,0x00,0xF0,0x00,
                   0x00,0x00,0x00,0xFF,0x00,
                   0xFF,0xFF,0xFF,0xFF,0xF0,
                   0xFF,0xFF,0xFF,0xFF,0xFF,
                   0xFF,0xFF,0xFF,0xFF,0xF0,
                   0x00,0x00,0x00,0xFF,0x00,
                   0x00,0x00,0x00,0xF0,0x00
                   };
                void main()
                {                                                             �
                                          Chapter 10:  Bitmapped Images   229


                   int old_mode;
                   fg_initpm();
                   if (fg_testmode(13,1) == 0) {
                      printf("This program requires a 320 ");
                      printf("x 200 EGA graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(13);
                   fg_setcolor(1);
                   fg_fillpage();
                   fg_setclip(0,15,0,199);
                   fg_move(10,10);
                   fg_drwimage(arrow,5,7);
                   fg_move(10,20);
                   fg_clpimage(arrow,5,7);
                   fg_move(8,30);
                   fg_revimage(arrow,5,7);
                   fg_move(8,40);
                   fg_flpimage(arrow,5,7);
                   fg_move(8,50);
                   fg_putimage(arrow,5,7);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


Retrieving Images

    Sometimes it's necessary to retrieve an image from video memory and store

it in one or more arrays as a bitmapped image. Fastgraph includes two routines, fg_getmap and fg_getimage, for this purpose. The fg_getmap routine retrieves pixels of the current color index and stores them in the mode- independent bitmap format used by fg_drawmap. The fg_getimage routine retrieves an image and stores it in the mode-specific bitmap format used by fg_drwimage, fg_clpimage, fg_revimage, fg_flpimage, and fg_putimage. The arguments to fg_getmap and fg_getimage are respectively analogous to those of fg_drawmap and fg_drwimage: the first is an array (passed by reference) to receive the bitmap, the second is the width of the bitmap in bytes, and the last is the height of the bitmap in pixel rows. With either routine, the graphics cursor position on the active video page defines the lower left corner of the image to retrieve.

    If we want to use fg_getmap to retrieve an image containing more than one

color, we must call the routine once per color. In this case we'll usually want to pass different bitmap arrays to fg_getmap (or perhaps different offsets into the same array). This might seem unusual at first, but it parallels the behavior of the fg_drawmap routine. That is, to display a multicolor image using fg_drawmap, we must call it once for each color in the image. � 230 Fastgraph User's Guide


    Example 10-10 demonstrates a typical use of the fg_getmap routine. The

program displays the word "text" in the upper left corner of the screen using a 320x200 graphics mode. It uses fg_getmap to retrieve the word as an image and then displays it in a new position with the fg_drawmap routine. Let's look at the program now, and afterward we'll more closely examine the screen coordinates and the structure of the bitmap array.

                               Example 10-10.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   char bitmap[32];
                   int old_mode, new_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(9);
                   fg_text("text",4);
                   fg_waitkey();
                   fg_move(0,7);
                   fg_getmap(bitmap,4,8);
                   fg_move(4,15);
                   fg_drawmap(bitmap,4,8);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    In all 320x200 graphics video modes, individual characters are 8 pixels

wide and 8 pixels high. This means the lower left corner of the (0,0) character cell is referenced by the screen coordinates (0,7). Hence, these are the coordinates of the first call to fg_move. The image retrieved in example 10-10 is four characters long (32 pixels wide), so we need a bitmap array capable of holding 8 rows of 32 pixels (4 bytes) each. Our bitmap array is therefore a 32-byte array, logically structured to have 4 columns and 8 rows. These values are the width and height arguments passed to fg_getmap and fg_drawmap. �

                                          Chapter 10:  Bitmapped Images   231


    After it retrieves the image, example 10-10 displays it one line below

and one-half character cell (four pixels) to the right of its original position. In other words, the program displays the image four pixels to the right of the (1,0) character cell. The lower left corner of that cell is referenced by the screen coordinates (0,15), so the image should appear at the position (4,15). These are the coordinates of the second call to fg_move.

    Example 10-11 illustrates the use of fg_getmap and fg_drawmap to retrieve

and display a two-color image. This example is similar to example 10-10, but this program first draws a rectangle in the upper left corner of the screen and then displays the word "text" on top of the rectangle in a different color. Each character in a 320x200 graphics video mode is 8 pixels wide and 8 pixels high, so the rectangle must be 32 pixels wide (4 characters times 8 pixels per character) and 8 pixels high. The image to retrieve will be the same size as the rectangle.

    The image retrieved in example 10-10 required a 32-byte array, logically

structured to have 4 columns and 8 rows. Example 10-11 will retrieve an image of the same structure, but the image contains two colors instead of just one. This means we need two 32-byte arrays, one for each color, to hold the image. We could instead use a single 64-byte array and pass an offset into that array (specifically, &bitmap[32]) for processing the second color.

                               Example 10-11.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   char bitmap1[32], bitmap2[32];
                   int old_mode, new_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(7);
                   fg_rect(0,31,0,7);
                   fg_setcolor(9);
                   fg_text("text",4);
                   fg_waitkey();
                   fg_move(0,7);
                   fg_setcolor(7);
                   fg_getmap(bitmap1,4,8);
                   fg_setcolor(9);                                            �

232 Fastgraph User's Guide


                   fg_getmap(bitmap2,4,8);
                   fg_move(4,15);
                   fg_setcolor(7);
                   fg_drawmap(bitmap1,4,8);
                   fg_setcolor(9);
                   fg_drawmap(bitmap2,4,8);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    Example 10-12 is similar to example 10-11, but it uses fg_getimage and

fg_drwimage instead of fg_getmap and fg_drawmap to retrieve and display the image. That is, it uses the mode-specific rather than the mode-independent image retrieval and display routines. When using the mode-specific routines, the size of the bitmap needed to hold the image depends on the video mode. For programs that run in only one video mode, bitmap widths are constant, but when a program must run in several video modes, the width is variable. The Fastgraph routine fg_imagesiz computes the number of bytes required to store a mode-specific bitmapped image of specified dimensions. Its two integer arguments specify the image width and height in pixels.

    The program computes the image width in bytes by passing a height of 1 to

fg_imagesiz. The size of the bitmap array in example 10-12 is 256 bytes, the size required in 256-color graphics modes (32 bytes times 8 bytes). Other video modes require less storage, so in these modes only a portion of the bitmap array will actually be used. The image width is then used in the calls to both fg_getimage and fg_drwimage.

                               Example 10-12.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   char bitmap[256];
                   int old_mode, new_mode;
                   int width;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   width = (int)fg_imagesiz(32,1);                            �
                                          Chapter 10:  Bitmapped Images   233


                   fg_setcolor(7);
                   fg_rect(0,31,0,7);
                   fg_setcolor(9);
                   fg_text("text",4);
                   fg_waitkey();
                   fg_move(0,7);
                   fg_getimage(bitmap,width,8);
                   fg_move(4,15);
                   fg_drwimage(bitmap,width,8);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


While this example used an array to store the image, it's usually preferable to allocate dynamic memory for this purpose. We could have done this in example 10-12 by calling fg_imagesiz with arguments of 32 (width) and 8 (height). The routine's return value would then tell us the number of bytes we would need to allocate.

    We can also use fg_getimage to retrieve images in text video modes. In

text modes, however, there are a few differences we must consider when using fg_getimage. First, the text cursor position, not the graphics cursor position, specifies the lower left corner of the image. Hence, we must use fg_locate instead of fg_move to define the image location. Second, the image width is always twice the number of characters per image row (that is, for each character we have a character byte and an attribute byte). The fg_getmap routine has no effect when used in a text video mode.

    Example 10-13 shows a simple use of fg_getimage in text modes. This

program is similar to example 10-12, but it runs in an 80-column text mode rather than a 320x200 graphics mode. As before, the program will retrieve the four characters "text" as an image from the upper left corner of the screen and then display it in a different location. Because the image consists of four characters in one row, the image width is 8 bytes and the image height is 1.

                               Example 10-13.
                  #include <fastgraf.h>
                  #include <stdio.h>
                  #include <stdlib.h>
                  void main(void);
                  void main()
                  {
                     int old_mode;
                     char image[8];
                     fg_initpm();
                     old_mode = fg_getmode();                                 �

234 Fastgraph User's Guide


                     if (fg_testmode(3,1))
                        fg_setmode(3);
                     else if (fg_testmode(7,1))
                        fg_setmode(7);
                     else {
                        printf("This program requires\n");
                        printf("an 80-column display.\n");
                        exit(1);
                        }
                     fg_cursor(0);
                     fg_setattr(9,7,0);
                     fg_text("text",4);
                     fg_waitkey();
                     fg_locate(0,0);
                     fg_getimage(image,8,1);
                     fg_locate(1,1);
                     fg_drwimage(image,8,1);
                     fg_waitkey();
                     fg_setmode(old_mode);
                     fg_reset();
                  }


    Finally, here's a tip that's worth remembering. In the native EGA and VGA

graphics modes (13 to 18) and the 16-color SVGA graphics modes (28 and 29), the routines for displaying and retrieving mode-specific bitmaps can be anywhere from 10% to 20% faster if the current graphics x position is an even number. This is because these routines must perform additional bitmap alignment when displaying or retrieving images starting at odd-numbered pixels.


Inverting Bitmaps

    Fastgraph's mode-independent and mode-specific bitmapped image display

routines expect images to be stored starting with the bottom row and proceeding toward the top. This convention is often contrary to the "top to bottom" row order used in other graphics libraries. The fg_invert routine reverses the row order of bitmapped images, so a "top to bottom" image becomes a "bottom to top" image, or vice versa. This will often make it easier to import such images from other sources for use with Fastgraph's bitmapped image display routines. Note that fg_invert does not change the orientation for Fastgraph's bitmapped image display routines; it merely reverses the row order of the image itself.

    The fg_invert routine requires three arguments. The first is the address

of the array containing the mode-independent or mode-specific bitmapped image data. The resulting inverted image is stored in this same array. The second and third arguments respectively specify the bitmap width and height in bytes.

    Example 10-14 is a modified version of example 10-6 that defines the

triangle's bitmap data starting with the top row and proceeding toward the bottom. To display this image with Fastgraph's fg_drwimage routine, we must �

                                          Chapter 10:  Bitmapped Images   235


translate the bitmapped image to the "bottom to top" format. The program performs this translation with fg_invert immediately after setting the video mode (though it could be done anytime before calling fg_drwimage). Other than the additional fg_invert call and the order of the bitmap data, example 10-14 is the same as example 10-6.

                               Example 10-14.
              #include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
              void main(void);
              char triangle[] = {
                 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
                 0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,
                 0x00,0x00,0x01,0x02,0x02,0x02,0x01,0x00,0x00,
                 0x00,0x01,0x02,0x02,0x02,0x02,0x02,0x01,0x00,
                 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01
                 };
              void main()
              {
                 int old_mode;
                 fg_initpm();
                 if (fg_testmode(19,1) == 0) {
                    printf("This program requires a 320 ");
                    printf("x 200 MCGA graphics mode.\n");
                    exit(1);
                    }
                 old_mode = fg_getmode();
                 fg_setmode(19);
                 fg_invert(triangle,9,5);
                 fg_setcolor(7);
                 fg_rect(0,319,0,199);
                 fg_move(156,101);
                 fg_drwimage(triangle,9,5);
                 fg_waitkey();
                 fg_setmode(old_mode);
                 fg_reset();
              }


    Note that fg_invert also can be used to create inverted versions of any

mode-independent or mode-specific bitmapped image. This means you can create versions of bitmaps mirrored about the x-axis, somewhat analogous to the way fg_revimage displays images mirrored about the y-axis. � 236 Fastgraph User's Guide


Converting Mode-Specific Bitmaps

    Earlier in this chapter we presented a bitmapped image format that was

independent of the video mode (such images are displayed with fg_drawmap or fg_clipmap). While this format works well for images with one or two colors, the performance can degrade significantly if the image contains many colors. In this section we'll show how Fastgraph's "one pixel per byte" mode-specific bitmap format used with 256-color graphics modes and virtual buffers can provide an alternate way to use the same image data in multiple video modes.

    The basis of this scheme is to store all bitmaps in the "one pixel per

byte" format. When using 256-color graphics modes or virtual buffers, we simply use the "one pixel per byte" bitmaps with the fg_drwimage family of routines because the bitmaps are already in the expected format. However, when using graphics modes with fewer colors, we must translate the bitmaps to a suitable format for those modes. Fastgraph's fg_pack routine provides an easy way to do this: it converts bitmapped images in the "one pixel per byte" format to the mode-specific bitmap format for the current video mode. The converted bitmaps can then be displayed with the fg_drwimage family.

    The fg_pack routine's first two arguments are the addresses of the source

and destination bitmap arrays. The source array contains the "one pixel per byte" bitmapped image, and the destination array will receive the converted mode-specific image (it's important to make sure the destination array is large enough to hold the converted image). The last two fg_pack arguments specify the width and height in pixels of the source bitmap. In 256-color graphics modes, or when a virtual buffer is active, fg_pack merely copies the source array contents to the destination array.

    Example 10-15 shows how you can use the same bitmap data in 256-color and

16-color graphics modes. We define our familiar triangle bitmap in the 256- color mode-specific format, as in example 10-6. The program first displays the triangle bitmap in the standard VGA/MCGA 320x200 256-color graphics mode (mode 19) against a gray background. After a keystroke, the program switches to the EGA/VGA 320x200 16-color graphics mode (mode 13). In this mode, fg_drwimage expects two pixels per bitmap byte, so we must call fg_pack to convert the bitmap data to this format. We store the resulting bitmap in the triangle16 array and again use fg_drwimage to display the triangle bitmap.

                               Example 10-15.
              #include <fastgraf.h>
              void main(void);
              char triangle[] = {
                 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
                 0x00,0x01,0x02,0x02,0x02,0x02,0x02,0x01,0x00,
                 0x00,0x00,0x01,0x02,0x02,0x02,0x01,0x00,0x00,
                 0x00,0x00,0x00,0x01,0x02,0x01,0x00,0x00,0x00,
                 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00
                 };
              char triangle16[25];
              void main()
              {                                                               �
                                          Chapter 10:  Bitmapped Images   237


                 int old_mode;
                 fg_initpm();
                 old_mode = fg_getmode();
                 fg_setmode(19);
                 fg_setcolor(7);
                 fg_fillpage();
                 fg_move(156,101);
                 fg_drwimage(triangle,9,5);
                 fg_waitkey();
                 fg_setmode(13);
                 fg_setcolor(7);
                 fg_fillpage();
                 fg_pack(triangle,triangle16,9,5);
                 fg_move(156,101);
                 fg_drwimage(triangle16,5,5);
                 fg_waitkey();
                 fg_setmode(old_mode);
                 fg_reset();
              }


Note that the 256-color bitmap is nine bytes wide and five bytes tall. When we convert the image to the 16-color mode-specific format, the bitmap width is reduced to five bytes because two pixels are packed into each byte. The second pixel in the last byte of each row becomes a transparent filler pixel (that is, its value is zero).

    As you might guess, Fastgraph's fg_unpack routine performs the opposite

function of fg_pack. That is, it converts a bitmap from the mode-specific format of the current video mode to the "one pixel per byte" format. The fg_unpack routine is intended as a helper function for displaying mode- specific images in virtual buffers when using video modes with fewer than 256 colors. When a virtual buffer is active, fg_drwimage always expects the bitmap to be in the "one pixel per byte" format, regardless of the current video mode. The fg_unpack routine makes it easy to convert images to this format before displaying them in a virtual buffer.

    The fg_unpack routine's first two arguments are the addresses of the

source and destination bitmap arrays. The source array contains the mode- specific bitmapped image, and the destination array will receive the converted "one pixel per byte" image. The last fg_unpack argument specifies the size of the source array in bytes. Like fg_pack, fg_unpack merely copies the source array contents to the destination array in 256-color graphics modes or when a virtual buffer is active.

    Example 10-16 illustrates how to use fg_unpack to convert mode-specific

bitmaps to the virtual buffer format. The program uses the 10-pixel by 7-pixel arrow bitmap of example 10-9 and runs in the EGA/VGA 320x200 16-color graphics mode (mode 13). In this mode, two pixels are packed into each bitmap byte, so the size of the bitmap array is 5x7, or 35 bytes. The call to fg_unpack converts the mode-specific image in the 35-byte arrow array into a "one pixel per byte" format image, storing the result in the 70-byte arrow256 array. � 238 Fastgraph User's Guide


We'll create a 70-byte virtual buffer -- just large enough to hold the 10x7 arrow bitmap -- and display the arrow256 bitmap in it against a light blue (color 9) background. Finally, we'll use fg_vbpaste to display the virtual buffer contents in the middle of the screen.

                               Example 10-16.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                char arrow[] = {
                   0x00,0x00,0x00,0xF0,0x00,
                   0x00,0x00,0x00,0xFF,0x00,
                   0xFF,0xFF,0xFF,0xFF,0xF0,
                   0xFF,0xFF,0xFF,0xFF,0xFF,
                   0xFF,0xFF,0xFF,0xFF,0xF0,
                   0x00,0x00,0x00,0xFF,0x00,
                   0x00,0x00,0x00,0xF0,0x00
                   };
                char arrow256[70];
                #ifdef FG32
                char buffer[70];
                #else
                char far buffer[70];
                #endif
                void main()
                {
                   int handle;
                   int old_mode;
                   fg_initpm();
                   if (fg_testmode(13,1) == 0) {
                      printf("This program requires a 320 ");
                      printf("x 200 EGA graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(13);
                   fg_unpack(arrow,arrow256,35);
                   fg_vbinit();
                   handle = fg_vbdefine(buffer,10,7);
                   fg_vbopen(handle);
                   fg_setcolor(9);
                   fg_fillpage();
                   fg_move(0,6);
                   fg_drwimage(arrow256,10,7);
                   fg_vbpaste(0,9,0,6,156,101);
                   fg_waitkey();                                              �
                                          Chapter 10:  Bitmapped Images   239


                   fg_vbclose();
                   fg_setmode(old_mode);
                   fg_reset();
                }


Bitmap Scaling and Shearing

    Fastgraph's fg_scale routine performs horizontal and vertical scaling of

bitmapped images. It expects a source bitmap stored in the "one pixel per byte" format of Fastgraph's 256-color modes, and it returns an expanded or reduced bitmap in the same format. To scale images in graphics modes with fewer than 256 colors, you must first use fg_unpack to convert the bitmap to the format expected by fg_scale, perform the scaling, and finally use fg_pack to convert the scaled image back to the mode-specific format. Because Fastgraph's virtual buffers also use the one pixel per byte format, you can also use fg_scale to scale images stored in virtual buffers.

    The fg_scale routine has six arguments. The first two specify the

addresses of the source and destination bitmap arrays. The source array contains the original (unscaled) bitmapped image; the destination array will receive the expanded or reduced (scaled) bitmap. Both bitmaps are stored in the "one pixel per byte" format. The third and fourth arguments specify the width and height in pixels of the unscaled image, while the fifth and sixth arguments do the same for the resulting scaled image.

    Example 10-17 shows how to expand and reduce bitmapped images with

fg_scale. The program displays a 64x40 light blue rectangle with a white border and the word SCALE centered inside it, in the upper left corner of the screen. It retrieves the rectangle contents as a mode-specific bitmap using fg_getimage. The first fg_scale call increases the size of this bitmap by 10 pixels in both directions, meaning the 64x40 image becomes a 74x50 image. The program then displays the expanded bitmap in the lower left corner of the screen using fg_putimage. The second fg_scale call reduces the original bitmap by a factor of two to create a 32x20 bitmap. The reduced bitmap is then displayed in the lower right corner, again using fg_putimage. Note that example 10-17 runs in mode 19, which is a 256-color graphics mode, so fg_getimage automatically stores the original bitmap in the "one pixel per byte" format expected by fg_scale.

                               Example 10-17.
      #include <fastgraf.h>
      void main(void);
      char source[64*40], dest[74*50];
      void main()
      {
         /* initialize the video environment */
         fg_initpm();
         fg_setmode(19);
         /* draw a blue rectangle with a thick white border */                �

240 Fastgraph User's Guide


         fg_setcolor(9);
         fg_rect(0,63,0,39);
         fg_setcolor(15);
         fg_boxdepth(5,5);
         fg_box(0,63,0,39);
         fg_move(32,20);
         fg_justify(0,0);
         fg_print("SCALE",5);
         /* retrieve the rectangle as a mode-specific bitmap */
         fg_move(0,39);
         fg_getimage(source,64,40);
         fg_waitkey();
         /* expand the bitmap by 10 pixels in each direction and   */
         /* then display it in the lower left corner of the screen */
         fg_move(0,199);
         fg_scale(source,dest,64,40,74,50);
         fg_putimage(dest,74,50);
         fg_waitkey();
         /* reduce the original bitmap by 50% in each direction and */
         /* then display it in the lower right corner of the screen */
         fg_move(288,199);
         fg_scale(source,dest,64,40,32,20);
         fg_putimage(dest,32,20);
         fg_waitkey();
         /* restore 80x25 text mode and exit */
         fg_setmode(3);
         fg_reset();
      }


    Shearing can be thought of as anchoring one corner of a rectangular

region and stretching the opposite corner horizontally or vertically. For example, bitmaps containing text or other characters could be sheared horizontally to the right for an italic effect. A sheared image will always be larger than the original image, and it will contain empty triangular areas at its corners. The empty areas will be filled with color 0 pixels, meaning they will be transparent when you display a sheared image with the fg_drwimage family of routines. Like fg_scale, fg_shear expects bitmaps in the "one pixel per byte" format and can likewise be used with images stored in virtual buffers.

    The fg_shear routine has six arguments. The first two specify the

addresses of the source and destination bitmap arrays. The source array contains the original bitmapped image; the destination array will receive the sheared bitmap. Both bitmaps are stored in the "one pixel per byte" format. The third and fourth arguments specify the width and height in pixels of the original image. For horizontal shears, the fifth argument specifies the �

                                          Chapter 10:  Bitmapped Images   241


resulting width in pixels of the sheared bitmap. For vertical shears, it specifies the resulting height.

    The final fg_shear argument defines the shear type. Four distinct shear

types are available:

    * horizontal left shear (region's bottom edge is stretched to the right)
    * horizontal right shear (region's top edge is stretched to the right)
    * vertical left shear (region's left edge is stretched up)
    * vertical right shear (region's right edge is stretched up)

The type is selected by a value between 0 and 3, respectively corresponding to the above four shear types. For example, shear type 2 represents a vertical left shear.

    Example 10-18 displays a 64x40 light blue rectangle with a white border

and the word SHEAR centered inside it, in the upper left corner of the screen. It retrieves the rectangle contents as a mode-specific bitmap using fg_getimage. The program then calls fg_shear to perform a 16-pixel horizontal right shear, which stretches the image's top edge 16 pixels to the right. This produces an 80x40 bitmap, which is then displayed in the lower left corner of the screen with fg_putimage. Because this example runs in mode 19, which is a 256-color graphics mode, fg_getimage automatically stores the original bitmap in the "one pixel per byte" format expected by fg_shear.

                               Example 10-18.
      #include <fastgraf.h>
      void main(void);
      char source[64*40], dest[80*40];
      void main()
      {
         /* initialize the video environment */
         fg_initpm();
         fg_setmode(19);
         /* draw a blue rectangle with a thick white border */
         fg_setcolor(9);
         fg_rect(0,63,0,39);
         fg_setcolor(15);
         fg_boxdepth(5,5);
         fg_box(0,63,0,39);
         fg_move(32,20);
         fg_justify(0,0);
         fg_print("SHEAR",5);
         /* retrieve the rectangle as a mode-specific bitmap */
         fg_move(0,39);
         fg_getimage(source,64,40);
         fg_waitkey();                                                        �

242 Fastgraph User's Guide


         /* shear the bitmap horizontally and to the right 16 pixels */
         /* then display it in the lower left corner of the screen   */
         fg_move(0,199);
         fg_shear(source,dest,64,40,80,1);
         fg_putimage(dest,80,40);
         fg_waitkey();
         /* restore 80x25 text mode and exit */
         fg_setmode(3);
         fg_reset();
      }


    It's possible to use fg_shear for rudimentary bitmap rotation. Shearing

an image horizontally left and then vertically right by the same amount will rotate an image counterclockwise. Similarly, shearing horizontally right and then vertically left will rotate it clockwise.

    Virtual buffers use the same "one pixel per byte" format expected by

fg_scale and fg_shear. This means you can pass virtual buffer addresses to these functions and apply scaling and shearing operations on virtual buffers. Note, however that 16-bit modes limit the size of arrays passed to fg_scale and fg_shear to 64K bytes, meaning you cannot apply these functions to larger virtual buffers. Further, the address of a real mode virtual buffer is a segment:offset pair, so you must use the large memory model to scale or shear images residing in virtual buffers in real mode programs.

    Example 10-19 demonstrates how to scale the contents of a virtual buffer.

The program creates two virtual buffers -- one is 320x200 pixels and the other is one-fourth this size, or 80x50 pixels. The CORAL.PCX image is loaded into the 320x200 virtual buffer using the fg_loadpcx routine and then copied to the visual page. The program then calls fg_scale, passing it the two virtual buffer addresses, to reduce the image to one-fourth its original size. The resulting image is stored in the 80x50 virtual buffer and finally copied to the lower left corner of the visual page.

                               Example 10-19.
          #include <fastgraf.h>
          #include <stdio.h>
          #include <stdlib.h>
          #if defined(__TURBOC__)
          #include <alloc.h>
          #else
          #include <malloc.h>
          #endif
          void main(void);
          void main()
          {
             int handle1, handle2;
          #if defined(__WATCOMC__) || defined(__HIGHC__)
             char *buffer1, *buffer2;
          #else                                                               �
                                          Chapter 10:  Bitmapped Images   243


             char far *buffer1, far *buffer2;
          #endif
             fg_initpm();
             fg_setmode(19);
             fg_vbinit();
          #if defined(__WATCOMC__) || defined(__HIGHC__)
             buffer1 = (char *)malloc(320*200);
             buffer2 = (char *)malloc(80*50);
          #elif defined(__TURBOC__)
             buffer1 = (char far *)farmalloc(320L*200L);
             buffer2 = (char far *)farmalloc(80L*50L);
          #else
             buffer1 = (char far *)halloc(320L*200L,1);
             buffer2 = (char far *)halloc(80L*50L,1);
          #endif
             if (buffer1 == NULL || buffer2 == NULL)
             {
                fg_setmode(3);
                fg_reset();
                printf("Could not create the virtual buffers.\n");
                exit(1);
             }
             handle1 = fg_vbdefine(buffer1,320,200);
             handle2 = fg_vbdefine(buffer2,80,50);
             fg_vbopen(handle1);
             fg_loadpcx("CORAL.PCX",0);
             fg_vbpaste(0,319,0,199,0,199);
             fg_waitkey();
             fg_scale(buffer1,buffer2,320,200,80,50);
             fg_vbopen(handle2);
             fg_vbpaste(0,79,0,49,0,199);
             fg_waitkey();
             fg_vbclose();
             fg_setmode(3);
             fg_reset();
          }


    In example 10-19, we created the virtual buffers with fg_vbdefine, so we

knew their addresses. What if we were using BASIC or real mode Pascal and created them with fg_vballoc? In this case the virtual buffer addresses wouldn't be immediately available to the program. Fortunately, there is an easy solution. Fastgraph's fg_vbaddr function returns the address of the specified virtual buffer; its only argument is the virtual buffer handle. In 16-bit modes, the address will be a real mode segment:offset pair or protected mode selector:offset pair. In 32-bit modes, it will be an offset into the default data segment. If you were using fg_vballoc in example 10-19, the virtual buffer creation and address retrieval could be done as follows:

    char far *buffer1, far *buffer2;                                          �

244 Fastgraph User's Guide


    handle1 = fg_vballoc(320,200);
    handle2 = fg_vballoc(80,50);
    if (handle1 < 0 || handle2 < 0) {
       fg_setmode(3);
       fg_reset();
       printf("Could not create the virtual buffers.\n");
       exit(1);
       }
    buffer1 = (char far *)fg_vbaddr(handle1);
    buffer2 = (char far *)fg_vbaddr(handle2);

The statements to release the memory allocated to the virtual buffers would be:

    fg_vbclose();
    fg_vbfree(handle1);
    fg_vbfree(handle2);


Pixel Run Maps

    The bitmaps used with the fg_drawmap, fg_drwimage, and related routines

can consume array space quite rapidly. This is especially true if the image is large or contains many colors. For example, a mode-independent bitmapped image that occupies the entire screen in a 320x200 graphics mode requires 8,000 bytes of space per color. Fastgraph provides another mode-independent image format called pixel run maps, which are more efficient in terms of space. Pixel run maps are structured just like the pixel run files introduced in the previous chapter, but the image resides in an array instead of a file.

    Let's return to our familiar triangle example and show how we could use a

pixel run map to display it.

                              . . . . * . . . .
                              . . . * x * . . .
                              . . * x x x * . .
                              . * x x x x x * .
                              * * * * * * * * *

As before, the pixels indicated by an asterisk (*) are the triangle's perimeter, while those indicated by an x represent its interior points. The pixels shown as periods (.) are not part of the triangle itself, but they are part of the pixel run map.

    Using the standard pixel run format introduced in the previous chapter,

we see it takes 16 pixel runs to store our triangle image as a pixel run map. If we want to display the perimeter pixels in color 1, the interior pixels in color 2, and the filler area in color 7, the pixel run map would contain 16 sets of (color,count) pairs: (1,9), (7,1), (1,1), (2,5), (1,1), (7,3), (1,1), (2,3), (1,1), (7,5), (1,1), (2,1), (1,1), (7,7), (1,1), and (7,4). Unlike the bitmapped image formats already discussed, pixel run maps have no provision for transparent colors.

    The Fastgraph routine fg_display displays an image stored as a pixel run

map. The fg_display routine expects three arguments. The first is an array containing the pixel runs (passed by reference), the second is the number of �

                                          Chapter 10:  Bitmapped Images   245


pixel runs in the array, and the third is the width in pixels of the image. As with the other image display routines, fg_display displays the image such that its lower left corner is at the graphics cursor position on the active video page or virtual buffer. Again, the format of the pixel run map is the same as that of a standard pixel run file. In addition, any display patterns defined by fg_pattern also apply to fg_display.

    Example 10-20 uses the fg_display routine to display the triangle as a

pixel run map in a 320x200 graphics mode. The program displays the triangle against a background of color 7, so the selection of color 7 for the filler area was important. If some other color were chosen, the filler area would not blend in with the background.

                               Example 10-20.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                char triangle[] = {
                   1,9, 7,1, 1,1, 2,5, 1,1, 7,3, 1,1, 2,3,
                   1,1, 7,5, 1,1, 2,1, 1,1, 7,7, 1,1, 7,4
                   };
                void main()
                {
                   int old_mode, new_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(7);
                   fg_rect(0,319,0,199);
                   fg_move(156,101);
                   fg_display(triangle,16,9);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    As you might guess, Fastgraph also offers a packed pixel run map image

format analogous to the packed pixel run file format introduced in the previous chapter. Example 10-21 is the same as example 10-20, but it uses fg_displayp rather than fg_display to display the image. Note the use of � 246 Fastgraph User's Guide


hexadecimal numbers for defining the packed color values, which of course is not necessary but certainly easier to read than expressing the quantities as decimal numbers. As with fg_display, any display patterns defined by fg_pattern also apply to fg_displayp.

                               Example 10-21.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                char triangle[] = {
                   0x17,9,1, 0x12,1,5, 0x17,1,3, 0x12,1,3,
                   0x17,1,5, 0x12,1,1, 0x17,1,7, 0x17,1,4
                   };
                void main()
                {
                   int old_mode, new_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(7);
                   fg_rect(0,319,0,199);
                   fg_move(156,101);
                   fg_displayp(triangle,16,9);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    Both fg_display and fg_displayp require the pixel run image to be stored

in an array. In examples 10-20 and 10-21, the image is defined within the program itself. We can also use these routines in place of fg_dispfile when the image is stored in a file if we first read the file contents into an array. Example 10-22 demonstrates this procedure. The program displays two identical images stored in files, one in standard pixel run format and the other in packed pixel run format.

    The first image, in standard pixel run format, is in the file CORAL.SPR.

Note the program must open the file for reading in binary mode ("rb" in the call to fopen). The program reads the file's entire contents into the pixel_runs array, whose size must be at least as large as the file size. �

                                          Chapter 10:  Bitmapped Images   247


Because the image is stored in standard pixel run format, the number of pixel runs is one-half the file size. The program then uses fg_move to establish the lower left corner of the screen as the graphics cursor position and then calls fg_display to display the image. The image fills the entire screen, so its width is 320 pixels.

    After waiting for a keystroke, the program similarly displays the second

image. This image is in the file CORAL.PPR and is stored in packed pixel run format. Because the image is packed, the number of pixel runs is two-thirds the file size. The program then clears the previous image from the screen and calls fg_displayp to display the image. After another keystroke, the program restores the original video mode and screen attributes and returns to DOS.

                               Example 10-22.
             #include <fastgraf.h>
             #include <io.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             char pixel_runs[20000];
             void main()
             {
                FILE *stream;
                int file_size, run_count;
                int old_mode, new_mode;
                fg_initpm();
                new_mode = fg_bestmode(320,200,1);
                if (new_mode < 0 || new_mode == 12) {
                   printf("This program requires a 320 ");
                   printf("x 200 color graphics mode.\n");
                   exit(1);
                   }
                old_mode = fg_getmode();
                fg_setmode(new_mode);
                stream = fopen("CORAL.SPR","rb");
                file_size = (int)(filelength(fileno(stream)));
                fread(pixel_runs,sizeof(char),file_size,stream);
                fclose(stream);
                run_count = file_size / 2;
                fg_move(0,199);
                fg_display(pixel_runs,run_count,320);
                fg_waitkey();
                stream = fopen("CORAL.PPR","rb");
                file_size = (int)(filelength(fileno(stream)));
                fread(pixel_runs,sizeof(char),file_size,stream);
                fclose(stream);
                run_count = file_size / 3 * 2;
                fg_erase();
                fg_displayp(pixel_runs,run_count,320);                        �

248 Fastgraph User's Guide


                fg_waitkey();
                fg_setmode(old_mode);
                fg_reset();
             }


Masking Maps

    It is not possible to include color 0 pixels in an image displayed with

fg_drwimage, fg_clpimage, fg_revimage, or fg_flpimage. This is because these routines consider color 0 pixels to be transparent, which means such pixels do not affect the corresponding pixels in video memory. There are times, however, when you will want color 0 pixels to be destructive, or replace the video memory contents.

    Consider again the arrow image of example 10-8. In that example, we

displayed a white (color 3) arrow against a black (color 0) background in the standard CGA four-color graphics mode. Suppose, though, that we want to do just the opposite -- display a black (color 0) arrow against a white (color 3) background. We could of course use fg_putimage, fg_drawmap, or one of the routines for displaying pixel run maps, but these methods do not support clipping or reversing an image. There are, however, four Fastgraph routines designed just for this purpose. These routines are fg_drawmask, fg_clipmask, fg_revmask, and fg_flipmask.

    Each of these routines uses a data structure called a masking map. A

masking map is similar in structure to a pixel run map, but it does not include any information about colors. Instead, it consists of a series of pixel runs that alternate between protected and unprotected pixels. An example might best clarify this.

    Once again, here is the arrow image of example 10-8.
                             . . . . . . * . . .
                             . . . . . . * * . .
                             * * * * * * * * * .
                             * * * * * * * * * *
                             * * * * * * * * * .
                             . . . . . . * * . .
                             . . . . . . * . . .

This time, though, we want the arrow to appear in color 0. Put another way, we need the "period" pixels (.) to protect video memory, while we want the "asterisk" pixels (*) to zero video memory. Looking at this problem from the perspective of a pixel run map, we have an alternating series of "protect" and "zero" runs. We don't need any information about pixel colors, just whether to protect or to zero video memory.

    This is precisely the structure of a masking map. Starting from the lower

left corner of the image and proceeding to the right, wrapping up to the next row when needed, we could represent this image as a masking map with 6 protected pixels, 1 zeroed pixel, 9 protected pixels, 2 zeroed pixels, and so on. In general, the structure of a masking map is as follows. �

                                          Chapter 10:  Bitmapped Images   249


                      [1]   length of 1st protect run
                      [2]   length of 1st  zero   run
                      [3]   length of 2nd protect run
                      [4]   length of 2nd  zero   run
                                        .
                                        .
                                        .
                    [n-2]   length of final protect run
                    [n-1]   length of final  zero   run


    Looking at this diagram, we see the even-numbered array elements hold the

length of the "protect" runs, and the odd-numbered elements hold the length of the "zero" runs. If you need the first run to be a "zero" run, just include a "protect" run of length zero as the first element of the array. If the final run is a "protect" run, you do not need to include a zero-length "zero" run at the end of the array. Finally, if either type of run exceeds 255 pixels, you'll need to split this into two or more pixel runs. In this case, be sure to include a zero-length run of the other type between the two array elements.

    Example 10-23 illustrates the use of a masking map through fg_drawmask,

fg_clipmask, fg_revmask, and fg_flipmask in the standard CGA four-color graphics mode (mode 4) to draw a black (color 0) arrow against a white background. These four routines are respectively analogous to fg_drwimage, fg_clpimage, fg_revimage, and fg_flpimage, but they use masking maps rather than bitmaps. The first argument of each routine is the masking map array (passed by reference), the second argument is the number of runs (that is, the number of elements) in the masking map array, and the third argument is the width in pixels of the image.

                               Example 10-23.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                char arrow[] = {6,1,9,2,2,9,1,19,7,2,8,1};
                void main()
                {
                   int old_mode;
                   fg_initpm();
                   if (fg_testmode(4,1) == 0) {
                      printf("This program requires a 320 ");
                      printf("x 200 CGA graphics mode.\n");
                      exit(1);
                      }                                                       �

250 Fastgraph User's Guide


                   old_mode = fg_getmode();
                   fg_setmode(4);
                   fg_setclip(0,15,0,199);
                   fg_setcolor(3);
                   fg_rect(0,319,0,199);
                   fg_move(10,10);
                   fg_drawmask(arrow,12,10);
                   fg_move(10,20);
                   fg_clipmask(arrow,12,10);
                   fg_move(10,30);
                   fg_revmask(arrow,12,10);
                   fg_move(10,40);
                   fg_flipmask(arrow,12,10);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    One of the more useful features of masking maps is their ability to clear

a portion of video memory before placing an image there. This technique provides an efficient, simple way to include color 0 pixels in an image. It is especially effective when displaying large or dithered images because the masking map is typically much smaller than the bitmap required by fg_drawmap or its related routines. Example 10-24 illustrates this process in the standard CGA four-color graphics mode (mode 4) by displaying our arrow image against a colored background. In this example, the arrow has a white (color 3) perimeter and a black (color 0) interior.

    The program displays the arrow in two steps. It first uses fg_drawmask to

clear the video memory where the arrow will be displayed. It then draws the arrow's perimeter using fg_drwimage. The interior pixels in the perimeter bitmap are transparent, but since we just zeroed that video memory, they appear in color 0. Note we could improve this example by creating a smaller masking map that only applies to the rectangle inscribing the arrow's interior. That is, we don't need to zero the video memory under the arrow's perimeter because we will immediately display other pixels there.

                               Example 10-24.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             char arrow_white[] = {
                0x00,0x0C,0x00, 0x00,0x0F,0x00, 0xFF,0xFC,0xC0,
                0xC0,0x00,0x30, 0xFF,0xFC,0xC0, 0x00,0x0F,0x00,
                0x00,0x0C,0x00
                };
             char arrow_black[] = {6,1,9,2,2,9,1,19,7,2,8,1};                 �
                                          Chapter 10:  Bitmapped Images   251


             void main()
             {
                int old_mode;
                fg_initpm();
                if (fg_testmode(4,1) == 0) {
                   printf("This program requires a 320 ");
                   printf("x 200 CGA graphics mode.\n");
                   exit(1);
                   }
                old_mode = fg_getmode();
                fg_setmode(4);
                fg_setcolor(2);
                fg_rect(0,319,0,199);
                fg_move(10,10);
                fg_drawmask(arrow_black,12,10);
                fg_drwimage(arrow_white,3,7);
                fg_waitkey();
                fg_setmode(old_mode);
                fg_reset();
             }


Summary of Bitmapped Image Display Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    For all bitmapped image routines, images are displayed or retrieved so

their lower left corner is at the graphics cursor position (or text cursor position for those routines that also work in text video modes). In 16-bit environments, the size of any arrays passed to these routines is limited to 64K bytes.

    FG_CLIPMAP displays a clipped image stored as a mode-independent bitmap.

This routine has no effect when used in a text video mode.

    FG_CLIPMASK displays a clipped image stored as a masking map. This

routine has no effect when used in a text video mode.

    FG_CLPIMAGE displays a clipped image stored as a mode-specific bitmap.

Color 0 pixels are considered transparent. This routine has no effect when used in a text video mode.

    FG_DISPLAY displays an image stored in Fastgraph's standard pixel run

format, where the image resides in an array. This routine has no effect when used in a text video mode. � 252 Fastgraph User's Guide


    FG_DISPLAYP displays an image stored in Fastgraph's packed pixel run

format, where the image resides in an array. This routine has no effect when used in a text video mode.

    FG_DRAWMAP displays an image stored as a mode-independent bitmap. This

routine has no effect when used in a text video mode.

    FG_DRAWMASK displays an image stored as a masking map. This routine has

no effect when used in a text video mode.

    FG_DRWIMAGE displays an image stored as a mode-specific bitmap. Color 0

pixels are considered transparent.

    FG_FLIPMASK displays a reversed clipped image stored as a masking map.

This routine has no effect when used in a text video mode.

    FG_FLPIMAGE displays a reversed clipped image stored as a mode-specific

bitmap. Color 0 pixels are considered transparent. This routine has no effect when used in a text video mode.

    FG_GETIMAGE retrieves an image as a mode-specific bitmap.
    FG_GETMAP retrieves an image as a mode-independent bitmap. This routine

has no effect when used in a text video mode.

    FG_IMAGESIZ determines the number of bytes required to store a mode-

specific bitmapped image of specified dimensions.

    FG_INVERT inverts the row order of a mode-specific or mode-independent

bitmapped image, so a "top to bottom" image becomes a "bottom to top" image, or vice versa.

    FG_PACK converts a bitmap in the "one pixel per byte" format used in

256-color graphics modes and virtual buffers to the mode-specific bitmap format for the current video mode.

    FG_PUTIMAGE displays an image stored as a mode-specific bitmap. No

support is provided for transparent pixels.

    FG_REVIMAGE displays a reversed image stored as a mode-specific bitmap.

Color 0 pixels are considered transparent. This routine has no effect when used in a text video mode.

    FG_REVMASK displays a reversed image stored as a masking map. This

routine has no effect when used in a text video mode.

    FG_SCALE expands or reduces a bitmapped image stored in the "one pixel

per byte" format.

    FG_SHEAR shears a bitmapped image stored in the "one pixel per byte"

format.

    FG_UNPACK converts a mode-specific bitmapped image to the "one pixel per

byte" format used in 256-color graphics modes and virtual buffers. �

                                          Chapter 10:  Bitmapped Images   253


    FG_VBADDR returns the address of the specified virtual buffer. In 16-bit

modes, the address will be a real mode segment:offset pair or protected mode selector:offset pair. In 32-bit modes, it will be an offset into the default data segment. � 254 Fastgraph User's Guide




Chapter 11



Block Transfer Routines � 256 Fastgraph User's Guide


Overview

    The Fastgraph routines described in this chapter copy rectangular blocks

between areas of video memory, between virtual buffers, between conventional memory and video memory, or between conventional memory and virtual buffers. Such routines are sometimes called Blit or BitBlt routines in other literature. Block transfers are useful in many graphics applications, but they are especially important in animation.

    Fastgraph provides several types of block transfer routines, each

optimized for its specific purpose. Because these routines are often used in speed-critical contexts, they do not perform clipping. If needed, clipping can generally be done at the application level by adjusting the block coordinates to fit within the clipping region.

    This chapter will discuss Fastgraph's block transfer routines in detail.

The information presented here, combined with the video page, virtual buffer, and image management routines of the previous three chapters, will provide the tools we need for the animation techniques presented in the next chapter.


Full Page Transfer

    Fastgraph's simplest block transfer routine is fg_copypage, introduced in

Chapter 8. The fg_copypage routine transfers the entire contents of one video page to another. The first argument is the number of the source video page, and the second argument is the number of the destination video page. The pages may be physical, virtual, or logical video pages. If both the source and destination pages are logical pages, the pages must exist in the same type of memory. For example, you cannot copy a logical page in extended memory to a logical page in conventional memory. The fg_copypage routine always works with video pages, even if a virtual buffer is active.

    Example 11-1 illustrates the use of fg_copypage in a 320x200 color

graphics mode. The program displays the word "test" in the middle of the visual page (page 0) and then uses fg_allocate to create a virtual video page (page 1). The virtual page is needed in case the program is running in a video mode with only one physical page. Next, the program uses fg_copypage to transfer the visual page contents to page 1. After waiting for a keystroke, the program erases the visual page, waits for another keystroke, and copies the contents of page 1 back to the visual page. It then releases the virtual page and exits.

                                Example 11-1.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int new_mode, old_mode;
                   fg_initpm();                                               �
                                   Chapter 11:  Block Transfer Routines   257


                   new_mode = fg_bestmode(320,200,2);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(7);
                   fg_rect(0,319,0,199);
                   fg_setcolor(9);
                   fg_locate(12,18);
                   fg_text("test",4);
                   fg_waitkey();
                   fg_allocate(1);
                   fg_copypage(0,1);
                   fg_erase();
                   fg_waitkey();
                   fg_copypage(1,0);
                   fg_waitkey();
                   fg_freepage(1);
                   fg_setmode(old_mode);
                   fg_reset();
                }


Byte Boundaries

    Video memory, like standard random-access memory, is divided into units

called bytes. In text modes, each byte holds either a character or an attribute. In graphics modes, each byte of video memory holds one or more horizontally contiguous pixels. If two adjacent horizontal pixels are stored in different bytes, then we say a byte boundary exists between the two pixels.

    The number of pixels per byte depends on the video mode being used, so

the location of the byte boundaries also depends on the video mode. That is, a byte boundary in a CGA graphics mode is not necessarily a byte boundary in a VGA graphics mode. The following table summarizes the number of pixels per byte of video memory and the byte boundary sequences for each supported graphics video mode. Notice that any horizontal coordinate whose value is a multiple of 8 is always a byte boundary, regardless of the video mode.

                      mode     pixels     horizontal coordinates
                     number   per byte    of byte boundaries
                        4         4       0, 4,  8, 12, ... , 316
                        5         4       0, 4,  8, 12, ... , 316
                        6         8       0, 8, 16, 24, ... , 632
                        9         2       0, 2,  4,  6, ... , 318
                       11         8       0, 8, 16, 24, ... , 712
                       12         4       0, 4,  8, 12, ... , 316             �

258 Fastgraph User's Guide


                       13         8       0, 8, 16, 24, ... , 312
                       14         8       0, 8, 16, 24, ... , 632
                       15         8       0, 8, 16, 24, ... , 632
                       16         8       0, 8, 16, 24, ... , 632
                       17         8       0, 8, 16, 24, ... , 632
                       18         8       0, 8, 16, 24, ... , 632
                       19         1       0, 1,  2,  3, ... , 319
                       20         1       0, 4,  8, 12, ... , 316
                       21         1       0, 4,  8, 12, ... , 316
                       22         1       0, 4,  8, 12, ... , 316
                       23         1       0, 4,  8, 12, ... , 316
                       24         1       0, 1,  2,  3, ... , 639
                       25         1       0, 1,  2,  3, ... , 639
                       26         1       0, 1,  2,  3, ... , 799
                       27         1       0, 1,  2,  3, ... , 1023
                       28         8       0, 8, 16, 24, ... , 792
                       29         8       0, 8, 16, 24, ... , 1016
    Block transfer routines are often used in animation sequences requiring

high-performance graphics, so these routines must be as efficient as possible. To this end, Fastgraph will force their horizontal pixel coordinates to byte boundaries, which eliminates the need to process any pixels individually. Fastgraph accomplishes this by reducing minimum horizontal coordinates to a byte boundary and extending maximum horizontal coordinates to the last pixel in a video memory byte. Since we are talking about pixel coordinates and not character cells, the coordinate adjustment only occurs in graphics video modes. Designing an application so block transfers occur on byte boundaries might take additional planning, but it will be time well spent.

    An example might best help explain this important feature. In the

EGA/VGA/SVGA 16-color graphics modes (modes 13 to 18, 28, and 29), byte boundaries occur at every eighth pixel. Thus, when you use the block transfer routines in these modes, Fastgraph reduces minimum x coordinates to the next lower multiple of eight. Similarly, it extends their maximum x coordinates to the next higher multiple of eight, less one pixel. That is, if a minimum x coordinate is 10 and a maximum x coordinate is 30, Fastgraph will adjust these values to 8 and 31 respectively. If the x coordinates were originally 8 and 31, Fastgraph would leave them unchanged.

    In the MCGA and SVGA 256-color graphics modes (modes 19 and 24 to 27)

each pixel occupies a separate byte of video memory, so Fastgraph does not need to adjust horizontal coordinates. However, in the XVGA graphics modes (modes 20 to 23), some coordinate adjustment might be needed. The XVGA modes store four pixels at each video memory address, one in each of four bit planes. The bit plane number for a pixel whose horizontal coordinate is x is given by the quantity x modulo 4. In XVGA modes, the source and destination minimum x coordinates must reference pixels in the same bit plane. Put another way, the relation

              xmin_source modulo 4 = xmin_destination modulo 4

must be true. If it isn't, Fastgraph reduces the destination minimum x value to the same bit plane as the source minimum x value. �

                                   Chapter 11:  Block Transfer Routines   259


Dual SVGA Banks

    Accessing video memory in SVGA graphics modes is controlled through a

banking scheme that maps contiguous 64KB blocks of video memory into a segmented address space. In other words, referencing a specific byte in video memory requires a bank number and an address within that bank. Some SVGA chipsets provide separate read and write bank registers, while others perform both operations through the same bank register.

    If a chipset supports separate read and write banks, Fastgraph's block

transfer routines can copy the source region directly to the destination region. However, chipsets that employ a single bank register require that these routines copy the source region to an intermediate buffer and then copy the buffer contents to the destination. This obviously makes a block transfer operation slower on single-bank chipsets. Bit 3 of the fg_svgastat return value will be set if the active SVGA chipset supports separate read and write banks.


The "Hidden" Video Page

    Some of Fastgraph's block transfer routines reference a video page called

the hidden page. The Fastgraph routine fg_sethpage defines which video page will be used as the hidden page. This routine takes as its only argument an integer value specifying the hidden page number. If you are using a virtual video page for the hidden page, you must call fg_sethpage after allocating that page. There is also a routine named fg_gethpage that returns the hidden page number, as specified in the most recent call to fg_sethpage, as its function value. The fg_gethpage routine takes no arguments.


Saving and Restoring Blocks

    The next two block transfer routines we'll discuss are fg_save and

fg_restore. The fg_save routine transfers a rectangular region from the active video page (as defined in the most recent call to fg_setpage) to the same position on the hidden video page (as defined in the most recent call to fg_sethpage). The fg_restore routine performs the complementary task -- it transfers a rectangular region from the hidden page to the active page. Each of these routines requires four arguments that define the coordinates of the block to transfer, in the order minimum x, maximum x, minimum y, and maximum y. In text modes, the coordinates are expressed as character space quantities (rows and columns). In graphics modes, they are expressed as screen space values (pixels), with the x coordinates extended to byte boundaries if required. There are also world space versions of these routines named fg_savew and fg_restorew available in graphics modes. The fg_restore, fg_restorew, fg_save, and fg_savew routines always work with video pages, even if a virtual buffer is active.

    Example 11-2 demonstrates the use of fg_save, fg_restore, and fg_sethpage

in an 80-column text video mode. After establishing the video mode (note the calls to fg_testmode specify that two video pages are needed), the program fills the screen with text and then waits for a keystroke. Following this, the program displays a small pop-up window prompting for another keystroke. After waiting for the second keystroke, the program erases the pop-up window by � 260 Fastgraph User's Guide


restoring the original screen contents, and then waits for yet another keystroke before returning to DOS. We'll present the program now, and afterward analyze it in detail.

                                Example 11-2.
               #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main(void);
               void main()
               {
                  int row;
                  int old_mode;
                  char string[17];
                  fg_initpm();
                  old_mode = fg_getmode();
                  if (fg_testmode(3,2))
                     fg_setmode(3);
                  else if (fg_testmode(7,2))
                     fg_setmode(7);
                  else {
                     printf("This program requires\n");
                     printf("an 80-column display.\n");
                     exit(1);
                     }
                  fg_cursor(0);
                  fg_setattr(9,7,0);
                  for (row = 0; row < 25; row++) {
                     sprintf(string," This is row %2d ",row);
                     fg_locate(row,0);
                     fg_text(string,16);
                     fg_text(string,16);
                     fg_text(string,16);
                     fg_text(string,16);
                     fg_text(string,16);
                     }
                  fg_waitkey();
                  fg_allocate(1);
                  fg_sethpage(1);
                  fg_save(32,47,11,13);
                  fg_setcolor(1);
                  fg_rect(32,47,11,13);
                  fg_setattr(15,1,0);
                  fg_locate(12,33);
                  fg_text("Press any key.",14);
                  fg_waitkey();
                  fg_restore(32,47,11,13);
                  fg_waitkey();                                               �
                                   Chapter 11:  Block Transfer Routines   261


                  fg_freepage(1);
                  fg_setmode(old_mode);
                  fg_reset();
               }


    Example 11-2 first establishes the video mode and uses fg_cursor to make

the BIOS cursor invisible. It then executes a for loop that fills each row of the screen with the phrase "This is row n", where n is the row number (between 0 and 24). Next, the program uses fg_allocate to create video page 1 as a virtual video page. This is needed in case the program is running in mode 7, which has only one true page (if the program is running in mode 3, fg_allocate has no effect). The program then makes page 1 the hidden page by calling fg_sethpage.

    After setting up the hidden video page, but before displaying the pop-up

window, example 11-2 uses fg_save to save the current contents of the area that the pop-up window will replace. The fg_save routine copies this region to the hidden page. The program then displays the pop-up window in the middle of the screen and leaves it there until a key is pressed. Following this, the program uses fg_restore to replace the pop-up window with the original contents of that region. This effectively erases the pop-up window and restores the original screen. The program then waits for another keystroke, after which it releases the virtual page and returns to DOS.

    The next example, 11-3, is similar to example 11-2, but it runs in a

320x200 color graphics mode instead of a text mode. The main differences between this program and example 11-2 are the use of 40-column text and the use of screen space coordinates instead of character space coordinates in the calls to fg_save, fg_restore, and fg_rect. Note that the call to fg_allocate creates a virtual page if the program is running in modes 4, 9, or 19. In modes 13 and 20, which respectively have four and eight physical pages, fg_allocate does nothing.

                                Example 11-3.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             void main()
             {
                int row;
                int new_mode, old_mode;
                char string[21];
                fg_initpm();
                new_mode = fg_bestmode(320,200,2);
                if (new_mode < 0 || new_mode == 12) {
                   printf("This program requires a 320 ");
                   printf("x 200 color graphics mode.\n");
                   exit(1);
                   }
                old_mode = fg_getmode();
                fg_setmode(new_mode);                                         �

262 Fastgraph User's Guide


                fg_setcolor(7);
                fg_rect(0,319,0,199);
                fg_setcolor(9);
                for (row = 0; row < 25; row++) {
                   sprintf(string,"   This is row %2d   ",row);
                   fg_locate(row,0);
                   fg_text(string,20);
                   fg_text(string,20);
                   }
                fg_waitkey();
                fg_allocate(1);
                fg_sethpage(1);
                fg_save(96,223,88,111);
                fg_setcolor(1);
                fg_rect(96,223,88,111);
                fg_setcolor(15);
                fg_locate(12,13);
                fg_text("Press any key.",14);
                fg_waitkey();
                fg_restore(96,223,88,111);
                fg_waitkey();
                fg_freepage(1);
                fg_setmode(old_mode);
                fg_reset();
             }


A More General Block Transfer Routine

    The fg_save and fg_restore routines each copy a rectangular region from

one video page to the same position on another video page. What if you need to copy the region to a different position on another video page, or copy it elsewhere on the same video page? Fastgraph provides a more general block transfer routine named fg_transfer. The fg_transfer routine copies a rectangular region on any video page to any position on any video page (however, it cannot copy overlapping blocks on the same video page). Like fg_save and fg_restore, fg_transfer works in text and graphics video modes. In graphics modes, fg_transfer extends its x coordinates to byte boundaries if necessary. The fg_transfer routine always works with video pages, even if a virtual buffer is active (use fg_vbcut and fg_vbpaste to copy blocks between virtual buffers and video pages, or fg_vbcopy to copy blocks between virtual buffers).

    The fg_transfer routine requires eight integer arguments. The first four

arguments define the region to copy, in the same order as expected by fg_save and fg_restore. The next two arguments define the lower left corner of the block destination, while the final two arguments respectively specify the source and destination video page numbers. In short, fg_transfer copies the specified region from the source page to the specified position on the destination page. �

                                   Chapter 11:  Block Transfer Routines   263


    Example 11-4 is the same as example 11-2, but it uses fg_transfer rather

than fg_save and fg_restore. We have arbitrarily chosen to copy the region overwritten by the pop-up window to the lower left corner of the hidden page (page 1). When we copy this region back to the visual page, we copy from the lower left corner of the hidden page back to the original position on the visual page (page 0). This sequence is shown in the following diagram.

             (11,32)    (11,47)               (22,0)     (22,15)
                                first call
               This is row 11   ------------>   This is row 11
               This is row 12                   This is row 12
               This is row 13   <------------   This is row 13
                                  second call
             (13,32)    (13,47)               (24,0)     (24,15)
                visual page (0)                  hidden page (1)

To copy one region to a new position and then back to its original position, note how we make the fifth and sixth arguments in the first call to fg_transfer the same values as the first and fourth arguments in the second call. Similarly, the fifth and sixth arguments in the second call must be the same as the first and fourth arguments in the first call. With all that out of the way, here is example 11-4.

                                Example 11-4.
               #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main(void);
               void main()
               {
                  int row;
                  int old_mode;
                  char string[17];
                  fg_initpm();
                  old_mode = fg_getmode();
                  if (fg_testmode(3,2))
                     fg_setmode(3);
                  else if (fg_testmode(7,2))
                     fg_setmode(7);
                  else {
                     printf("This program requires\n");
                     printf("an 80-column display.\n");
                     exit(1);
                     }
                  fg_cursor(0);
                  fg_setattr(9,7,0);
                  for (row = 0; row < 25; row++) {
                     sprintf(string," This is row %2d ",row);
                     fg_locate(row,0);                                        �

264 Fastgraph User's Guide


                     fg_text(string,16);
                     fg_text(string,16);
                     fg_text(string,16);
                     fg_text(string,16);
                     fg_text(string,16);
                     }
                  fg_waitkey();
                  fg_allocate(1);
                  fg_transfer(32,47,11,13,0,24,0,1);
                  fg_setcolor(1);
                  fg_rect(32,47,11,13);
                  fg_setattr(15,1,0);
                  fg_locate(12,33);
                  fg_text("Press any key.",14);
                  fg_waitkey();
                  fg_transfer(0,15,22,24,32,13,1,0);
                  fg_fg_waitkey();
                  fg_freepage(1);
                  fg_setmode(old_mode);
                  fg_reset();
               }


    Example 11-5 illustrates another use of the fg_transfer routine. This

example is functionally identical to example 10-10, but it uses fg_transfer instead of fg_getmap and fg_drawmap. With the fg_transfer routine, we eliminate the calls to fg_getmap and fg_drawmap, the two calls to fg_move, and the 32-byte array needed to retrieve the block. As an added bonus, using fg_transfer is much faster than the technique of example 10-10, although we probably won't notice this gain with such a small block.

    The block copied in example 11-5 is one row of four characters, so its

width in screen space is 32 pixels and its height is 8 pixels. Because the block is in the upper left corner of the screen, the block boundaries are xmin=0, xmax=31, ymin=0, and ymax=7. We want to move the block one-half character cell (4 pixels) to the right and one row (8 pixels) down, so our destination coordinates are x=4 (xmin+4) and y=15 (ymax+8). Note how the program restricts itself to modes 19 and 20 to insure the block copy is not affected by byte boundaries. Also, we are copying the block from one position to another on the visual page, so both the source and destination pages are 0.

                                Example 11-5.
                 #include <fastgraf.h>
                 #include <stdio.h>
                 #include <stdlib.h>
                 void main(void);
                 void main()
                 {
                    int old_mode, new_mode;
                    fg_initpm();                                              �
                                   Chapter 11:  Block Transfer Routines   265


                    new_mode = fg_bestmode(320,200,1);
                    if (new_mode < 19) {
                       printf("This program requires a ");
                       printf("256-color graphics mode.\n");
                       exit(1);
                       }
                    old_mode = fg_getmode();
                    fg_setmode(new_mode);
                    fg_setcolor(9);
                    fg_text("text",4);
                    fg_waitkey();
                    fg_transfer(0,31,0,7,4,15,0,0);
                    fg_waitkey();
                    fg_setmode(old_mode);
                    fg_reset();
                 }


    Example 11-6 shows yet another application of fg_transfer in a graphics

video mode. The program displays a rectangle in the upper left quadrant of the screen and then centers the word "quadrant" inside the rectangle. After waiting for a keystroke, the program uses fg_transfer to first copy the upper left quadrant to the upper right quadrant. It then uses fg_transfer again to copy the upper half of the screen to the lower half. The result of this is the screen being filled with what was originally in the upper left quadrant.

                                Example 11-6.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int new_mode, old_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(7);
                   fg_rect(0,159,0,99);
                   fg_setcolor(9);
                   fg_locate(6,6);
                   fg_text("quadrant",8);                                     �

266 Fastgraph User's Guide


                   fg_waitkey();
                   fg_transfer(0,159,0,99,160, 99,0,0);
                   fg_transfer(0,319,0,99,  0,199,0,0);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


Block Transfer Routines for Virtual Buffers

    Fastgraph's fg_restore, fg_save, and fg_transfer routines copy blocks

between physical or virtual video pages. Other routines are provided for block transfers between virtual buffers and video pages, or between virtual buffers. In our discussion of virtual buffers in Chapter 8, we described Fastgraph's fg_vbcut and fg_vbpaste routines. Recall that fg_vbcut copies a block from the active video page to the active virtual buffer, while fg_vbpaste copies a block from the active virtual buffer to the active video page.

    We'll now introduce another block transfer routine, fg_vbcopy, for

copying blocks between two virtual buffers, or to a non-overlapping position in the same virtual buffer. The fg_vbcopy arguments are exactly the same as those of fg_transfer, except the last two arguments reference the source and destination virtual buffer handles instead of video page numbers. Example 11-7 is similar to example 11-6, but it uses fg_vbcopy to perform the two block copy operations in a 320x200 virtual buffer (these were done with fg_transfer in example 11-6). After this, it calls fg_vbpaste to display the virtual buffer contents.

                                Example 11-7.
               #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main(void);
               #ifdef FG32
               char buffer[64000];
               #else
               char far buffer[64000];
               #endif
               void main()
               {
                  int handle;
                  int new_mode, old_mode;
                  fg_initpm();
                  new_mode = fg_bestmode(320,200,1);
                  if (new_mode < 0 || new_mode == 12) {
                     printf("This program requires a 320 ");
                     printf("x 200 color graphics mode.\n");
                     exit(1);                                                 �
                                   Chapter 11:  Block Transfer Routines   267


                     }
                  old_mode = fg_getmode();
                  fg_setmode(new_mode);
                  fg_vbinit();
                  handle = fg_vbdefine(buffer,320,200);
                  fg_vbopen(handle);
                  fg_setcolor(7);
                  fg_rect(0,159,0,99);
                  fg_setcolor(9);
                  fg_locate(6,6);
                  fg_text("quadrant",8);
                  fg_vbcopy(0,159,0,99,160, 99,handle,handle);
                  fg_vbcopy(0,319,0,99,  0,199,handle,handle);
                  fg_vbpaste(0,319,0,199,0,199);
                  fg_waitkey();
                  fg_vbclose();
                  fg_setmode(old_mode);
                  fg_reset();


Blocks with Transparent Colors

    The next block transfer routines we'll discuss are fg_tcxfer, fg_tcmask,

and fg_tcdefine. The fg_tcxfer routine is similar to fg_transfer in that it copies a rectangular region from one position to another, but fg_tcxfer allows you to treat one or more colors as transparent (the name fg_tcxfer stands for transparent color transfer). In other words, any pixel whose color value is defined to be transparent is not copied to the destination area. The fg_tcxfer routine's arguments are the same as for the fg_transfer routine, but fg_tcxfer has no effect in text video modes. Because fg_tcxfer must examine the color of individual pixels, it is not nearly as fast as fg_transfer. The fg_tcxfer routine always works with video pages, even if a virtual buffer is active (the fg_vbtcxfer routine, described in the next section, provides transparent color block transfers for virtual buffers).

    You can use either fg_tcmask or fg_tcdefine to define which colors are

considered transparent in subsequent calls to fg_tcxfer. The fg_tcmask routine's argument is an integer bit mask (specifically, a 16-bit mask) where each bit indicates whether or not the color is transparent. For example, if bit 0 (the rightmost bit) is set in the mask, then color 0 will be transparent; if bit 0 is reset, color 0 will not be transparent. Because the bit mask size is 16 bits, only the first 16 color values may be defined as transparent using fg_tcmask.

    Example 11-8 illustrates the use of the fg_tcxfer and fg_tcmask routines.

This program is similar to example 11-6, except the color of the word "quadrant" (color 9) is defined to be transparent, and fg_tcxfer is used in place of fg_transfer. Because color 9 maps to color 1 in the CGA four-color graphics mode (mode 4), we must define both colors 1 and 9 to be transparent (remember, fg_tcmask considers actual color values transparent, not color indices). The bit mask passed to fg_tcmask thus will be 0000 0010 0000 0010 � 268 Fastgraph User's Guide


binary, or 0202 hex. This causes the word "quadrant" to appear in the background color (color 0) instead of color 9 in the upper right, lower left, and lower right quadrants.

                                Example 11-8.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int new_mode, old_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(7);
                   fg_rect(0,159,0,99);
                   fg_setcolor(9);
                   fg_locate(6,6);
                   fg_text("quadrant",8);
                   fg_waitkey();
                   fg_tcmask(0x0202);
                   fg_tcxfer(0,159,0,99,160, 99,0,0);
                   fg_tcxfer(0,319,0,99,  0,199,0,0);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    The fg_tcdefine routine expects two integer arguments -- one defining the

color number (between 0 and 255) and another defining the transparency state associated with that color. If the state is zero, the specified color will be opaque (non-transparent). If it is any other value, the color will be transparent. In the previous example, we could use fg_tcdefine instead of fg_tcmask to make colors 1 and 9 transparent by replacing the call to fg_tcmask with the following:


                              fg_tcdefine(1,1);
                              fg_tcdefine(9,1);                               �
                                   Chapter 11:  Block Transfer Routines   269


If you don't call fg_tcmask or fg_tcdefine, the fg_tcxfer routine considers no colors transparent.


Transparent Block Transfers for Virtual Buffers

    Fastgraph's fg_vbtcxfer routine transfers blocks with transparent colors

from the active virtual buffer to the active video page. Its arguments the same as those of fg_vbpaste, but it does not copy any pixels whose colors are transparent. The fg_tcdefine or fg_tcmask routines define which colors are transparent, as when using fg_tcxfer.

    Example 11-9 achieves the same result as example 11-8, but it does so

using virtual buffers. Rather than create a full-screen virtual buffer, however, this example creates a virtual buffer one-fourth the screen size and transfers the virtual buffer contents to each quadrant of the visual page in four separate operations. In the upper left quadrant, we simply call fg_vbpaste to display the virtual buffer contents. The three fg_vbtcxfer calls fill the other quadrants, but with color 9 pixels being transparent. This sequence of block copy operations from the virtual buffer creates the same resulting display as example 11-8. Note that this example uses fg_tcdefine to make color 9 transparent; we could just as well have used fg_tcmask.

                                Example 11-9.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                #ifdef FG32
                char buffer[16000];
                #else
                char far buffer[16000];
                #endif
                void main()
                {
                   int handle;
                   int new_mode, old_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_vbinit();
                   handle = fg_vbdefine(buffer,160,100);
                   fg_vbopen(handle);
                   fg_setcolor(7);                                            �

270 Fastgraph User's Guide


                   fg_fillpage();
                   fg_setcolor(9);
                   fg_locate(6,6);
                   fg_text("quadrant",8);
                   fg_vbpaste(0,159,0,99,0,99);
                   fg_waitkey();
                   fg_tcdefine(9,1);
                   fg_vbtcxfer(0,159,0,99,160,99);
                   fg_vbtcxfer(0,159,0,99,0,199);
                   fg_vbtcxfer(0,159,0,99,160,199);
                   fg_waitkey();
                   fg_vbclose();
                   fg_setmode(old_mode);
                   fg_reset();
                }


Transferring Blocks to and from Conventional Memory

    The final two block transfer routines we'll discuss are fg_getblock and

fg_putblock. The fg_getblock routine transfers a rectangular region from the active video page or virtual buffer to an array (you can use fg_imagesiz to determine the array size needed to store the block). The fg_putblock routine transfers a block previously retrieved with fg_getblock to the active page or virtual buffer. While these two routines are faster than fg_getimage and fg_putimage, they are not as fast as fg_restore, fg_save, and fg_transfer.

    Each of these routines requires five arguments. The first is the address

of the array that will receive or that contains the block. The remaining four arguments define the position of the block on the active page or virtual buffer, in the order minimum x, maximum x, minimum y, and maximum y. In text modes, the coordinates are expressed as character space quantities (rows and columns). In graphics modes, they are expressed as screen space values (pixels), with the x coordinates extended to byte boundaries if required.

    Note that both fg_getblock and fg_putblock expect the array address to be

passed by far reference except in BASIC. This means real mode Pascal programs must use the GetMem procedure to allocate storage for the buffer, as this is the only way to pass something by far reference in real mode Pascal. In 16-bit environments, the maximum size of a block is 64K bytes, regardless of which compiler you're using.

    Example 11-10 is similar to example 11-5 and shows fg_getblock and

fg_putblock in action in a 320x200 graphics mode. The program displays the word "text" and retrieves it into a 32 by 8 pixel block. After a keystroke, it displays the block 8 pixels below and 8 pixels to the right of its original position. The size of the buffer was chosen to be 256 bytes to accommodate the largest size required for a 32 by 8 block (which occurs in the 256-color graphics modes). Note also how the source and destination horizontal block extremes were chosen for byte boundary alignment in case fg_bestmode selected a 16-color graphics mode.

                               Example 11-10.                                 �
                                   Chapter 11:  Block Transfer Routines   271


                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                #ifdef FG32
                char buffer[256];
                #else
                char far buffer[256];
                #endif
                void main()
                {
                   int old_mode, new_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(9);
                   fg_text("text",4);
                   fg_getblock(buffer,0,31,0,7);
                   fg_waitkey();
                   fg_putblock(buffer,8,39,8,15);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


Summary of Block Transfer Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    For all block transfer routines, Fastgraph extends the horizontal pixel

coordinates to a byte boundary when the routines are used in a graphics video mode.

    FG_COPYPAGE transfers the contents of one video page to another. The

pages may be physical, virtual, or logical video pages. If both pages are logical pages, they must exist in the same type of memory. The fg_copypage routine does not work with virtual buffers. � 272 Fastgraph User's Guide


    FG_GETBLOCK retrieves the block (for later display with fg_putblock) at

the specified position on the active video page or virtual buffer. In text modes, the block extremes are defined in character space; in graphics modes, they are defined in screen space.

    FG_GETHPAGE returns the hidden page number, as defined in the most recent

call to fg_sethpage.

    FG_PUTBLOCK displays the block (previously obtained with fg_getblock) at

the specified position on the active video page or virtual buffer. In text modes, the block extremes are defined in character space; in graphics modes, they are defined in screen space.

    FG_RESTORE copies a block from the hidden video page to the same position

on the active video page. The fg_restore routine does not work with virtual buffers.

    FG_RESTOREW is the same as fg_restore, but the block extremes are

specified as world space coordinates. The fg_restorew routine does not work with virtual buffers.

    FG_SAVE copies a block from the active video page to the same position on

the hidden video page. The fg_save routine does not work with virtual buffers.

    FG_SAVEW is the same as fg_save, but the block extremes are specified as

world space coordinates. The fg_savew routine does not work with virtual buffers.

    FG_SETHPAGE defines the hidden video page (used by fg_restore,

fg_restorew, fg_save, and fg_savew).

    FG_TCDEFINE defines the transparent attribute of a color index for use

with the fg_tcxfer routine. This routine has no effect when used in a text video mode.

    FG_TCMASK defines which of the first 16 colors the fg_tcxfer routine will

consider transparent. This routine has no effect when used in a text video mode.

    FG_TCXFER copies a block from any position on any video page to any

position on any video page, excluding any pixels whose color value is transparent. This routine has no effect when used in a text video mode and does not work with virtual buffers.

    FG_TRANSFER copies a block from any position on any video page to any

position on any video page. It is Fastgraph's most general block transfer routine. The fg_transfer routine does not work with virtual buffers.

    FG_VBCOPY copies a rectangular region from one virtual buffer to another,

or to a non-overlapping position within the same virtual buffer.

    FG_VBTCXFER copies a rectangular region from the active virtual buffer to

the active video page, excluding any transparent pixels.




Chapter 12



Animation Techniques � 274 Fastgraph User's Guide


Overview

    Unlike other microcomputers, the IBM PC and PS/2 family of systems do not

have any special graphics hardware or firmware to help in performing animation. This means any animation done on these systems must be implemented entirely through software. This chapter will show how to do this using Fastgraph's video page management, image display, and block transfer routines. The methods described in this chapter are not intended to be all inclusive, for that would itself fill a separate volume at least as large as this manual. However, the animation techniques presented here should provide a basis that you can readily extend to develop more sophisticated uses of animation. The examples in this chapter are restricted to graphics video modes.


Simple Animation

    The first type of animation we'll examine is called simple animation. In

simple animation, we display an object, erase it, and then display it in a new position. When we perform this "erase and redisplay" sequence repetitively, the object moves. This method, however, has two drawbacks. First, unless the object is rather small, it will flicker because the erasing and display of the object does not coincide with the refresh rate of the video display. Second, and perhaps more importantly, anything underneath the object is not saved as the object moves across it. Despite these limitations, simple animation is sometimes useful, and it is a good place to begin our discussion of animation techniques.

    Example 12-1 moves a small bright green rectangle (magenta in CGA) from

left to right across the screen in any 320x200 color graphics mode. The program moves the rectangle, 20 pixels wide and 10 pixels high, using a for loop. This loop first uses fg_clprect to display the rectangle, then uses fg_waitfor to leave the object on the screen momentarily, and finally uses fg_clprect again to erase the rectangle by redisplaying it in the original background color (fg_waitfor is described in Chapter 16). We use fg_clprect rather than fg_rect because the first few and last few loop iterations result in at least part of the rectangle being off the screen. Each successive loop iteration displays the rectangle five pixels to the right of its previous position.

                                Example 12-1.
         #include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
         void main(void);
         void main()
         {
            int new_mode, old_mode;
            int x;
            /* initialize the video environment */
            fg_initpm();
            new_mode = fg_bestmode(320,200,1);                                �
                                      Chapter 12:  Animation Techniques   275


            if (new_mode < 0 || new_mode == 12) {
               printf("This program requires a 320 ");
               printf("x 200 color graphics mode.\n");
               exit(1);
               }
            old_mode = fg_getmode();
            fg_setmode(new_mode);
            /* move the object across the screen */
            for (x = -20; x < 320; x+=5) {
               fg_setcolor(10);
               fg_clprect(x,x+19,95,104);
               fg_waitfor(1);
               fg_setcolor(0);
               fg_clprect(x,x+19,95,104);
               }
            /* restore the original video mode and return to DOS */
            fg_setmode(old_mode);
            fg_reset();
         }


    Example 12-2 is the same as example 12-1, but it shows what happens when

we move the rectangle across an existing background (in this case, the background is solid white). If you run this program, you'll see that the rectangle leaves a trail of color 0 pixels behind it. While this might be occasionally useful, it demonstrates that simple animation is destructive because it does not preserve the background. In this example, if we changed the second call to fg_setcolor within the for loop to revert to color 15 instead of color 0, the background would be restored. In general, though, it may not be this easy to replace the background, so we must rely on some other method for preserving it.

                                Example 12-2.
         #include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
         void main(void);
         void main()
         {
            int new_mode, old_mode;
            int x;
            /* initialize the video environment */
            fg_initpm();
            new_mode = fg_bestmode(320,200,1);
            if (new_mode < 0 || new_mode == 12) {
               printf("This program requires a 320 ");
               printf("x 200 color graphics mode.\n");
               exit(1);                                                       �

276 Fastgraph User's Guide


               }
            old_mode = fg_getmode();
            fg_setmode(new_mode);
            /* draw some type of background */
            fg_setcolor(15);
            fg_rect(0,319,0,199);
            /* move the object across the screen */
            for (x = -20; x < 320; x+=5) {
               fg_setcolor(10);
               fg_clprect(x,x+19,95,104);
               fg_waitfor(1);
               fg_setcolor(0);
               fg_clprect(x,x+19,95,104);
               }
            /* restore the original video mode and return to DOS */
            fg_setmode(old_mode);
            fg_reset();
         }


    To summarize, we've seen that simple animation is easy to implement, but

it is destructive and typically causes the animated object to flicker. For these reasons, it is not used too frequently.


XOR Animation

    "Exclusive or" animation, or XOR animation for short, is an interesting

extension of simple animation and is most useful when animating a single-color object against a single-color background. Like simple animation, it uses the "erase and redisplay" technique to move an object, but it does this differently. Instead of erasing the object by displaying it in the background color, XOR animation does so by displaying it in the same color using an exclusive or, or XOR, operation. This method relies on a specific property of the exclusive or operator:

               (object XOR background) XOR object = background

In other words, if you XOR something twice in the same position, the result is the same as the original image in that position.

    Example 12-3 demonstrates XOR animation. This program is similar to

example 12-2, but it only runs in the 320x200 EGA graphics mode (mode 13). After establishing the video mode, it uses the Fastgraph routine fg_setfunc to select XOR mode. This causes any subsequent graphics output to be XORed with the contents of video memory instead of just replacing it. The fg_setfunc routine is described further in Chapter 17.

    The other differences between examples 12-3 and 12-2 are that the call to

fg_setcolor has been moved outside the for loop, and that fg_setcolor takes a �

                                      Chapter 12:  Animation Techniques   277


different value. Since the existing background is bright white (color 15), we can't just use color 10 if we want to display a bright green object. The desired value is that which when XORed with color 15 produces color 10; the easiest way to obtain this value is to XOR these two numbers. The call to fg_setcolor can be moved outside the loop because we display the object using the same color index throughout.

                                Example 12-3.
         #include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
         void main(void);
         void main()
         {
            int old_mode;
            int x;
            /* initialize the video environment */
            fg_initpm();
            if (fg_testmode(13,1) == 0) {
               printf("This program requires EGA.\n");
               exit(1);
               }
            old_mode = fg_getmode();
            fg_setmode(13);
            fg_setfunc(3);
            /* draw some type of background */
            fg_setcolor(15);
            fg_rect(0,319,0,199);
            /* move the object across the screen */
            fg_setcolor(10^15);
            for (x = -20; x < 320; x+=5) {
               fg_clprect(x,x+19,95,104);
               fg_waitfor(1);
               fg_clprect(x,x+19,95,104);
               }
            /* restore the original video mode and return to DOS */
            fg_setmode(old_mode);
            fg_reset();
         }


    Fastgraph only supports the XOR pixel operation in the native EGA and VGA

graphics video modes (modes 13 through 18) and 16-color SVGA modes (28 and 29). Thus, you cannot use XOR animation in CGA, Tandy/PCjr, Hercules, or 256- color graphics modes. � 278 Fastgraph User's Guide


    While XOR animation is non-destructive (that is, it restores the original

background), it still suffers from the flickering encountered in simple animation. In spite of this, it may be useful when animating a single-color object against a single-color background.


Static Frame Animation

    Static frame animation uses a different strategy than simple animation or

XOR animation. The general scheme of this method is to create the entire animation sequence off-screen and then successively display each item, or frame, in this sequence on one position of the visual video page. This results in a visually appealing animation that is non-destructive and does not include the flickering associated with simple animation and XOR animation. Static frame animation requires the visual video page and one or more additional pages (or virtual buffers) to implement. The number of pages needed depends on the number of frames and the size of each frame.

    Example 12-4 runs in any 320x200 color graphics video mode and

illustrates a simple use of static frame animation. The program displays an animation sequence containing 12 frames; it displays this sequence three times. The animation sequence consists of a bright green rectangle (magenta in CGA) moving from left to right across the center of the frame. Each frame is 96 pixels wide and 50 pixels high. The 12 frames are set up on an off-screen video page as shown here:

                        0       95 96     191 192    287
                     0
                         frame 1    frame 2    frame 3
                    49
                    50
                         frame 4    frame 5    frame 6
                    99
                   100
                         frame 7    frame 8    frame 9
                   149
                   150
                         frame 10   frame 11   frame 12
                   199


    Example 12-4 first establishes the video mode and allocates the

additional video page (needed if using a video mode in which page 1 is a virtual video page). The program then generates the background for frame 1; the background is a blue rectangle (cyan in CGA) with a white ellipse centered on it. After the call to fg_ellipse, the first frame is ready.

    The next step is to create the remaining 11 frames. In frame 2, the right

half of the 20-pixel wide rectangle will enter the left edge of the frame. In frame 3, the rectangle will be ten pixels farther right, or aligned against the left edge of the frame. In frames 4 through 12, the rectangle will be ten pixels farther right in each frame, so by frame 12 only the left half of the �

                                      Chapter 12:  Animation Techniques   279


rectangle appears on the right edge of the frame. The first for loop in the program builds frames 2 through 12 by copying the background from frame 1 and then displaying the rectangle (that is, the animated object) in the proper position for that frame.

    The second for loop performs the animation sequence. To display the 12-

frame sequence three times, it must perform 36 iterations. The loop simply copies each frame from the proper position on video page 1 to the middle of the visual video page. Note how fg_waitfor is used to pause momentarily between frames.

                                Example 12-4.
       #include <fastgraf.h>
       #include <stdio.h>
       #include <stdlib.h>
       void main(void);
       #define VISUAL 0
       #define HIDDEN 1
       int xmin[] = {  0, 96,192,  0, 96,192,  0, 96,192,  0, 96,192};
       int ymax[] = { 49, 49, 49, 99, 99, 99,149,149,149,199,199,199};
       void main()
       {
          int new_mode, old_mode;
          int frame, offset;
          int i, x, y;
          /* initialize the video environment */
          fg_initpm();
          new_mode = fg_bestmode(320,200,2);
          if (new_mode < 0 || new_mode == 12) {
             printf("This program requires a 320 ");
             printf("x 200 color graphics mode.\n");
             exit(1);
             }
          old_mode = fg_getmode();
          fg_setmode(new_mode);
          fg_allocate(HIDDEN);
          /* draw the background in the upper left corner */
          fg_setpage(HIDDEN);
          fg_setcolor(1);
          fg_rect(0,95,0,49);
          fg_setcolor(15);
          fg_move(48,25);
          fg_ellipse(20,20);
          /* display the animated object against each background */
          fg_setcolor(10);
          offset = -10;                                                       �

280 Fastgraph User's Guide


          for (i = 1; i < 12; i++) {
             x = xmin[i];
             y = ymax[i];
             fg_transfer(0,95,0,49,x,y,HIDDEN,HIDDEN);
             fg_setclip(x,x+95,0,199);
             fg_clprect(x+offset,x+offset+19,y-29,y-20);
             offset += 10;
             }
          /* slide the object across the background three times */
          for (i = 0; i < 36; i++) {
             frame = i % 12;
             x = xmin[frame];
             y = ymax[frame];
             fg_transfer(x,x+95,y-49,y,112,124,HIDDEN,VISUAL);
             fg_waitfor(2);
             }
          /* restore the original video mode and return to DOS */
          fg_freepage(HIDDEN);
          fg_setmode(old_mode);
          fg_reset();
       }



Dynamic Frame Animation

    Dynamic frame animation is similar to static frame animation, but all the

animation frames are built as needed during the animation sequence instead of in advance. When using this method, you must first store a copy of the background on an off-screen video page. Then, to build a frame, create another copy (called the workspace) of the background elsewhere on the off-screen page (or even to a different off-screen page) and display the object on that copy. Finally, transfer the workspace to the visual page. Like static frame animation, this method produces a non-destructive, flicker-free animation sequence.

    Example 12-5 is functionally identical to example 12-4, but it uses

dynamic rather than static frame animation. As before, the program builds the background in the upper left corner of video page 1, but it then uses fg_transfer to copy it to the center of the visual video page. The for loop builds each frame as it is needed and also copies it to the center of the visual page. Again, fg_waitfor creates the necessary pause between frames.

                                Example 12-5.
         #include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
         void main(void);
         #define VISUAL 0                                                     �
                                      Chapter 12:  Animation Techniques   281


         #define HIDDEN 1
         void main()
         {
            int new_mode, old_mode;
            int frame, offset;
            int i;
            /* initialize the video environment */
            fg_initpm();
            new_mode = fg_bestmode(320,200,2);
            if (new_mode < 0 || new_mode == 12) {
               printf("This program requires a 320 ");
               printf("x 200 color graphics mode.\n");
               exit(1);
               }
            old_mode = fg_getmode();
            fg_setmode(new_mode);
            fg_allocate(HIDDEN);
            /* draw the background in the upper left corner */
            fg_setpage(HIDDEN);
            fg_setcolor(1);
            fg_rect(0,95,0,49);
            fg_setcolor(15);
            fg_move(48,25);
            fg_ellipse(20,20);
            /* copy it to the center of the visual page */
            fg_transfer(0,95,0,49,112,124,HIDDEN,VISUAL);
            /* slide the object across the background three times */
            fg_setcolor(10);
            for (i = 0; i < 36; i++) {
               frame  = i % 12;
               offset = 10 * frame - 10;
               fg_transfer(0,95,20,29,112,105,HIDDEN,HIDDEN);
               fg_rect(112+offset,131+offset,96,105);
               fg_transfer(112,207,96,105,112,105,HIDDEN,VISUAL);
               fg_waitfor(2);
               }
            /* restore the original video mode and return to DOS */
            fg_freepage(HIDDEN);
            fg_setmode(old_mode);
            fg_reset();
         }


    Two items in example 12-5 merit further discussion. First, we have chosen

our workspace on page 1 so it uses the same screen space coordinates as the � 282 Fastgraph User's Guide


image area on the visual page. This is not necessary unless you are using fg_restore instead of fg_transfer. Second, the program can use the faster fg_rect routine in place of fg_clprect. It can do this because even though the object will extend beyond the workspace limits, we only transfer the workspace itself. However, for this to function properly, the workspace's horizontal limits must fall on byte boundaries.

    Note too that we do not need to transfer the entire frame during the

animation sequence. In example 12-5, we know the vertical extremes of the moving image are y=96 and y=105, so we only transfer 10 rows instead of the entire frame. We could similarly compute the x extremes for each frame and only transfer the necessary portion. Recall, however, that fg_transfer extends the horizontal coordinates to byte boundaries, so we may copy a few extra pixels as well. This may or may not affect the animation sequence. Again, the problem is eliminated if you align your workspace on byte boundaries.

    When we use dynamic frame animation, it is easy to change the number of

frames in the animation sequence. Suppose we wish to produce a smoother animation by increasing the number of frames from 12 to 24. This means the object will move in increments of five pixels instead of ten. The only changes needed are to double the number of loop iterations, modify the calculations for the frame number and offset values as shown here, and reduce the fg_waitfor pause from 2 to 1.


                          frame  = i % 24;
                          offset = 5 * frame - 10;


Compare this to all the changes that would be necessary if we were using static frame animation.


Page Flipping

    Page flipping is a variation of frame animation in which you construct

images on off-screen video pages and then repetitively make those pages the visual page. We can further divide the page flipping technique into static and dynamic variants, as we did with frame animation.

    In static page flipping, we construct the entire animation sequence in

advance, with one frame per video page. Once this is done, we can display each frame by using fg_setvpage to switch instantly from one video page to another. Although this produces a smooth, flicker-free animation, we cannot carry the sequence very far before running out of video pages (and hence animation frames).

    In dynamic page flipping, we construct each animation frame when it is

needed. As in static page flipping, we construct each frame on a separate video page. However, as example 12-6 demonstrates, we only need three video pages to produce the animation sequence, regardless of the number of frames in the sequence. Two of the three video pages will alternate as the visual page, while the remaining video page keeps a copy of the background.

    Example 12-6, which performs an animation sequence similar to examples

12-4 and 12-5, illustrates dynamic frame animation in the 320x200 EGA graphics �

                                      Chapter 12:  Animation Techniques   283


video mode (mode 13). The program begins by displaying the background on video page 2. Video pages 0 and 1 will alternate as the visual page; the page that is not the visual page is called the hidden page. We start with page 0 as the visual page, and hence page 1 as the hidden page. To build each frame, the program uses fg_transfer to copy the background from page 2 to the hidden page and then uses fg_clprect to display the animated object at the correct position on the hidden page. After this, it displays the next frame by using fg_setvpage to make the hidden page the visual page. Before beginning the next iteration, the program toggles the hidden page number in preparation for the next frame.

                                Example 12-6.
         #include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
         void main(void);
         void main()
         {
            int old_mode;
            int hidden;
            int x;
            /* initialize the video environment */
            fg_initpm();
            if (testmode(fg_13,3) == 0) {
               printf("This program requires EGA.\n");
               exit(1);
               }
            old_mode = fg_getmode();
            fg_setmode(13);
            /* draw the background on page two */
            fg_setpage(2);
            fg_setcolor(1);
            fg_rect(0,319,0,199);
            fg_setcolor(15);
            fg_move(160,100);
            fg_ellipse(20,20);
            /* slide the object across the screen */
            hidden = 1;
            setcolor(10);
            for (x = -10; x < 320; x+=4) {
               fg_setpage(hidden);
               fg_transfer(0,319,0,199,0,199,2,hidden);
               fg_clprect(x,x+19,96,105);
               fg_setvpage(hidden);
               hidden = 1 - hidden;
               fg_waitfor(1);
               }                                                              �

284 Fastgraph User's Guide


            /* restore the original video mode and return to DOS */
            fg_setmode(old_mode);
            fg_reset();
         }


    A problem with either page flipping technique arises if we use virtual

video pages. Page flipping relies on the fact that changing the visual page number occurs instantly, which is exactly what happens when we use physical video pages. However, such is not the case with virtual or logical pages because Fastgraph must copy the entire page contents into video memory. While this occurs quite rapidly, it is not instantaneous, and its effects are immediately apparent on the animation.


An Animation Example: The Fastgraph Fish Tank

    If you installed the example programs when you installed Fastgraph, the

EXAMPLES subdirectory will include a fully-commented program called the fish tank that illustrates dynamic frame animation. The fish tank is an excellent example of multi-object non-destructive animation in which several types of tropical fish swim back and forth against a coral reef background. As a picture is worth 1,024 words, we suggest studying the fish tank source code for some useful techniques in developing a complete animation program. The source code for the fish tank program is in FISHTANK.C, FISHTANK.BAS, FISHTANK.FOR, or FISHTANK.PAS, depending on what language support you've installed with Fastgraph.


Summary of Animation Techniques

    This chapter has presented five animation techniques: simple animation,

XOR animation, static frame animation, dynamic frame animation, and page flipping. The following table summarizes their behavior.

              technique     destructive?        flicker-free?
              simple             yes                 no
              XOR                no                  no
              static frame       no                  yes
              dynamic frame      no                  yes
              page flipping      no                  yes

Simple animation and XOR animation are elementary techniques that are seldom used once you master frame animation and page flipping.

    As stated at the beginning of this chapter, the simple examples presented

here serve as the basis for understanding the mechanics of the animation techniques we have discussed. In "real world" programs, you'll typically want to display an image using the fg_drwimage or fg_drawmap family of routines instead using rudimentary images such as the rectangles in our examples. A helpful rule is to use PCX, GIF, or pixel run files for both backgrounds and moving objects, and then use fg_getimage or fg_getmap to retrieve the moving objects as bitmapped images for later display. Of course, it's desirable to do this "behind the scenes" work on video pages other than the visual page. This �

                                      Chapter 12:  Animation Techniques   285


is precisely the technique used in the Fastgraph fish tank. � 286 Fastgraph User's Guide




Chapter 13



Special Effects � 288 Fastgraph User's Guide


Overview

    This chapter will discuss the Fastgraph routines that help produce

special visual effects. These include the ability to dissolve the screen contents in small increments, scroll areas of the screen, change the physical origin of the screen, and set up a split screen environment. The accompanying example programs illustrate how to use these routines to produce some interesting effects.


Screen Dissolving

    Screen dissolving is the process of replacing the entire screen contents

in random small increments instead of all at once. Fastgraph includes two routines, fg_fadeout and fg_fadein, for this purpose. The fg_fadeout routine incrementally replaces the visual page contents with pixels of the current color, while fg_fadein incrementally replaces the visual page contents with the hidden page contents (that is, the page defined in the most recent call to fg_sethpage). Both routines accept an integer argument that defines the delay between each incremental replacement. A value of zero means to perform the replacement as quickly as possible, while 1 is slightly slower, 2 is slower yet, and so forth. The fg_fadeout and fg_fadein routines have no effect in text video modes and always work with video pages, even if a virtual buffer is active.

    Example 13-1 shows how to use fg_fadeout. The program, which runs in any

graphics video mode, first fills the screen with a rectangle of color 2. After waiting for a keystroke, the program incrementally replaces the screen contents with pixels of color 15 (the current color index when fg_fadeout is called). After another keystroke, the program exits gracefully.

                                Example 13-1.
                 #include <fastgraf.h>
                 void main(void);
                 void main()
                 {
                    int old_mode;
                    fg_initpm();
                    old_mode = fg_getmode();
                    fg_setmode(fg_automode());
                    fg_setcolor(2);
                    fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                    fg_waitkey();
                    fg_setcolor(15);
                    fg_fadeout(0);
                    fg_waitkey();
                    fg_setmode(old_mode);
                    fg_reset();
                 }                                                            �
                                           Chapter 13:  Special Effects   289



    Example 13-2 shows how to use fg_fadein in any 320x200 color graphics

video mode. The program first fills the screen with a rectangle of color 2 and then fills video page 1 with a rectangle of color 1. After waiting for a keystroke, the program incrementally transfers the contents of page 1 to the visual page. After the call to fg_fadein, both page 0 (the visual page) and page 1 (the hidden page) will contain rectangles of color 1 that fill the entire video page. Finally, the program waits for another keystroke before returning to DOS.

                                Example 13-2.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int new_mode, old_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,2);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_allocate(1);
                   fg_sethpage(1);
                   fg_setcolor(2);
                   fg_rect(0,319,0,199);
                   fg_setpage(1);
                   fg_setcolor(1);
                   fg_rect(0,319,0,199);
                   fg_waitkey();
                   fg_fadein(0);
                   fg_waitkey();
                   fg_freepage(1);
                   fg_setmode(old_mode);
                   fg_reset();
                }


    You also can produce some appealing visual effects by replacing the

screen contents in a non-random fashion using the fg_restore or fg_transfer routines. For example, you could copy the hidden page contents to the visual page through a series of concentric rectangular areas, each slightly larger than the previous, until the entire screen is copied. Another interesting effect is to start around the screen perimeter and proceed toward the screen � 290 Fastgraph User's Guide


center, thus producing a "snake-like" effect. Experimenting with such techniques may reveal other effects that suit your application.


Scrolling

    Another useful effect is scrolling, and Fastgraph provides a routine that

performs vertical scrolling within a given region of the active video page. The fg_scroll routine scrolls a region defined in screen space or character space. It can scroll up or down and offers two types of scrolling: circular and end-off. In circular scrolling, rows that scroll off one edge of the defined region appear at its opposite edge. In end-off scrolling, such rows simply wind up above or below the scrolling area. The following diagrams illustrate the two types of scrolling.

                end-off scrolling            circular scrolling
              before         after          before         after
                               C                             B
                 A                             A
                               A                             A
                 B                             B


    In these diagrams, the area bounded by the double lines is the scrolling

region, as specified in the call to fg_scroll. Also, the scrolling direction is assumed to be down (that is, toward the bottom of the screen), and the number of rows to scroll is the height of the area designated B. The number of rows to scroll is often called the scrolling increment.

    For the end-off scrolling example, the scrolling operation transfers

region A downward so part of it is copied into area B. The area C (which is the same size as area B) at the top of the scrolling region is filled with pixels of the current color index (as defined in the most recent call to fg_setcolor), and the original contents of area B are lost. The circular scrolling example also copies region A downward into the original area B. Unlike end-off scrolling, however, circular scrolling preserves the area B by copying it to the opposite edge of the scrolling region.

    The fg_scroll routine takes six arguments. The first four define the

scrolling region in the order minimum x coordinate, maximum x coordinate, minimum y coordinate, and maximum y coordinate. In graphics video modes, the x coordinates are extended to byte boundaries if needed. The fifth argument is the scrolling increment. It specifies the number of rows to scroll. If it is positive, the scrolling direction is toward the bottom of the screen; if it is negative, the scrolling direction is toward the top of the screen. The sixth and final argument specifies the scroll type. If this value is zero, the scroll will be circular; if it is any other value, the scroll will be end-off. If the scroll type is circular, Fastgraph will use the hidden page (as defined in the most recent call to fg_sethpage) as a workspace (more specifically, the area bounded by the scrolling region extremes on the hidden page will be used). The fg_scroll routine is disabled when a virtual buffer is active. �

                                           Chapter 13:  Special Effects   291


    We'll now present three example programs that use the fg_scroll routine.

Example 13-3 runs in any 320x200 graphics video mode. The program displays two lines of text ("line one" and "line two") in the upper left corner of the screen against a white background. It then uses fg_scroll to move the second line down four pixel rows using an end-off scroll. After waiting for a keystroke, the program again uses fg_scroll to move the text back to its original position. Note especially how fg_setcolor is used before the first call to fg_scroll to replace the "scrolled off" rows with pixels of color 15, thus preserving the white background.

                                Example 13-3.
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int new_mode, old_mode;
                   fg_initpm();
                   new_mode = fg_bestmode(320,200,1);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_setcolor(15);
                   fg_rect(0,319,0,199);
                   fg_setcolor(10);
                   fg_text("line one",8);
                   fg_locate(1,0);
                   fg_text("line two",8);
                   fg_waitkey();
                   fg_setcolor(15);
                   fg_scroll(0,63,8,15,4,1);
                   fg_waitkey();
                   fg_scroll(0,63,12,19,-4,1);
                   fg_waitkey();
                   fg_setmode(old_mode);
                   fg_reset();
                }


    Example 13-4 is similar to example 13-3, but it runs in the 80-column

color text mode (mode 3). In text modes, we cannot scroll half a character row as in example 13-3, so the program scrolls the minimum one row instead.

                                Example 13-4.                                 �

292 Fastgraph User's Guide


                         #include <fastgraf.h>
                         void main(void);
                         void main()
                         {
                            int old_mode;
                            fg_initpm();
                            old_mode = fg_getmode();
                            fg_setmode(3);
                            fg_cursor(0);
                            fg_setcolor(7);
                            fg_rect(0,79,0,24);
                            fg_setattr(10,7,0);
                            fg_text("line one",8);
                            fg_locate(1,0);
                            fg_text("line two",8);
                            fg_waitkey();
                            fg_setcolor(7);
                            fg_scroll(0,7,1,1,1,1);
                            fg_waitkey();
                            fg_scroll(0,7,2,2,-1,1);
                            fg_waitkey();
                            fg_setmode(old_mode);
                            fg_reset();
                         }


    Example 13-5, the final scrolling example, demonstrates a circular

scroll. The program runs in any 320x200 color graphics video mode; note the use of video page 1 for the workspace required when fg_scroll performs a circular scroll. The program first fills the screen with a light blue rectangle (cyan in CGA), displays a smaller white rectangle in the center of the screen, and then uses fg_move, fg_draw, and fg_paint to display a light green star (magenta in CGA) within the white rectangle. The program executes a while loop to scroll the star upward in four-pixel increments. Because the scroll is circular, rows of the star that "scroll off" the top edge of the white rectangle (whose height is the same as the scrolling region) reappear at its bottom edge. The use of fg_waitfor within the loop simply slows down the scroll. The scrolling continues until any key is pressed.

                                Example 13-5.
                #include <conio.h>
                #include <fastgraf.h>
                #include <stdio.h>
                #include <stdlib.h>
                void main(void);
                void main()
                {
                   int new_mode, old_mode;                                    �
                                           Chapter 13:  Special Effects   293


                   fg_initpm();
                   new_mode = fg_bestmode(320,200,2);
                   if (new_mode < 0 || new_mode == 12) {
                      printf("This program requires a 320 ");
                      printf("x 200 color graphics mode.\n");
                      exit(1);
                      }
                   old_mode = fg_getmode();
                   fg_setmode(new_mode);
                   fg_allocate(1);
                   fg_sethpage(1);
                   fg_setcolor(9);
                   fg_rect(0,319,0,199);
                   fg_setcolor(15);
                   fg_rect(132,188,50,150);
                   fg_setcolor(10);
                   fg_move(160,67);
                   fg_draw(175,107);
                   fg_draw(140,82);
                   fg_draw(180,82);
                   fg_draw(145,107);
                   fg_draw(160,67);
                   fg_paint(160,77);
                   fg_paint(150,87);
                   fg_paint(160,87);
                   fg_paint(170,87);
                   fg_paint(155,97);
                   fg_paint(165,97);
                   while (kbhit() == 0) {
                      fg_waitfor(1);
                      fg_scroll(136,184,50,150,-4,0);
                      }
                   fg_waitkey();
                   fg_freepage(1);
                   fg_setmode(old_mode);
                   fg_reset();
                }


Changing the Screen Origin

    Fastgraph includes two routines for changing the screen origin. By

changing the screen origin, we simply mean defining the (x,y) coordinate of the upper left corner of the display area. The fg_pan routine performs this function in screen space, while the fg_panw routine does in world space. Neither routine changes the graphics cursor position. Because the function of fg_pan and fg_panw is to change the screen origin, these routines are not applicable to virtual buffers. � 294 Fastgraph User's Guide


    Each of these routines has two arguments that specify the x and y

coordinates of the screen origin. For fg_pan, the arguments are integer quantities. For fg_panw, they are floating point quantities.

    In the EGA, VGA, MCGA, XVGA, and SVGA graphics modes (modes 13 to 29),

you can set the screen origin to any (x,y) coordinate position (that is, to any pixel). In the other graphics modes, certain restrictions exist, as imposed by specific video hardware. These constraints limit the coordinate positions that can be used as the screen origin. Fastgraph compensates for these restrictions by reducing the specified x and y coordinates to values that are acceptable to the current video mode, as shown in the following table.

                          x will be reduced   y will be reduced
         video mode       to a multiple of:   to a multiple of:
             4-5                  8                   2
              6                  16                   2
              9                   4                   4
             11                   8                   4
             12                   4                2 or 3

In modes 4 and 5, for instance, the x coordinate will be reduced to a multiple of 8 pixels, and the y coordinate will be reduced to a multiple of 2 pixels. In the Hercules low resolution mode (mode 12), the y coordinate reduction depends on whether or not the specified pixel row is scan doubled.

    Example 13-6 shows a useful effect that can be made with fg_pan or

fg_panw. This program uses fg_automode to select a video mode and then draws an unfilled white rectangle. The top and bottom sides of the rectangle are intentionally drawn just smaller than the physical screen size. After waiting for a keystroke, the program uses a for loop to make the rectangle jiggle up and down. The rectangle moves because fg_pan is called inside the loop to switch the screen origin between the rectangle's upper left corner and the original origin. Note also the use of fg_waitfor to cause slight delays after each call to fg_pan. If we didn't use fg_waitfor, the changing of the origin would occur so rapidly we wouldn't notice the effect. Finally, the program restores the original video mode and screen attributes before returning to DOS.

                                Example 13-6.
                 #include <fastgraf.h>
                 #include <stdio.h>
                 #include <stdlib.h>
                 void main(void);
                 #define DELAY 2
                 #define JUMP  4
                 void main()
                 {
                    int i;
                    int old_mode;
                    fg_initpm();                                              �
                                           Chapter 13:  Special Effects   295


                    old_mode = fg_getmode();
                    fg_setmode(fg_automode());
                    fg_setcolor(15);
                    fg_move(0,JUMP);
                    fg_draw(fg_getmaxx(),JUMP);
                    fg_draw(fg_getmaxx(),fg_getmaxy()-JUMP);
                    fg_draw(0,fg_getmaxy()-JUMP);
                    fg_draw(0,JUMP);
                    fg_waitkey();
                    for (i = 0; i < 6; i++) {
                       fg_pan(0,JUMP);
                       fg_waitfor(DELAY);
                       fg_pan(0,0);
                       fg_waitfor(DELAY);
                       }
                    fg_setmode(old_mode);
                    fg_reset();
                 }


    The real power of fg_pan becomes clear when it is used with fg_resize to

perform smooth panning. Recall from Chapter 8 that fg_resize changes the video page dimensions in native EGA and VGA graphics modes (modes 13 to 18), the extended VGA graphics modes (20 to 23), and the SVGA graphics modes (24 to 29). We'll now present an example that shows how to use these two routines to perform panning in the low-resolution EGA graphics mode (mode 13). The method it uses also would work in any mode that supports video page resizing.

    Example 13-7 begins by establishing the video mode and then immediately

calls fg_resize to increase the video page size to 640x400 pixels. Thus, the video page is now four times its original size. Following this, the program fills the page (the entire page, not just what is displayed) with a bright green rectangle with a white border around it. It then displays the message "Press arrow keys to pan" in the center of the 640x400 page.

    The main part of the program is a loop that accepts keystrokes and calls

fg_pan to perform the panning one pixel at a time. When you press any of the four arrow keys, the program adjusts the x and y coordinates for the screen origin as directed. For example, pressing the up arrow key scrolls the screen upward one pixel. When we reach the edge of the video page, the program prevents further scrolling in that direction. This process continues until you press the Escape key, at which time the program restores the original video mode and screen attributes before exiting.

                                Example 13-7.
                 #include <fastgraf.h>
                 void main(void);
                 void main()
                 {
                    unsigned char key, aux;
                    int old_mode;                                             �

296 Fastgraph User's Guide


                    int x, y;
                    fg_initpm();
                    old_mode = fg_getmode();
                    fg_setmode(13);
                    fg_resize(640,400);
                    fg_setcolor(2);
                    fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                    fg_setcolor(15);
                    fg_box(0,fg_getmaxx(),0,fg_getmaxy());
                    fg_justify(0,0);
                    fg_move(320,200);
                    fg_print("Press arrow keys to pan.",24);
                    x = 0;
                    y = 0;
                    do {
                       fg_getkey(&key,&aux);
                       if (aux == 72 && y < 200)
                          y++;
                       else if (aux == 75 && x < 320)
                          x++;
                       else if (aux == 77 && x > 0)
                          x--;
                       else if (aux == 80 && y > 0)
                          y--;
                       fg_pan(x,y);
                    } while (key != 27);
                    fg_setmode(old_mode);
                    fg_reset();
                 }


Panning With Virtual Buffers

    The fg_pan routine is not suitable for panning a large image through a

small window because it affects the entire screen. However, you can achieve this type of panning by storing the large image on an off-screen video page or in a virtual buffer and then copy the appropriate portions of it to the fixed window on the visual page. Example 13-8 illustrates this technique using a virtual buffer.

                                Example 13-8.
                 #include <fastgraf.h>
                 void main(void);
                 #ifdef FG32
                 char buffer[64000];
                 #else
                 char huge buffer[64000];
                 #endif                                                       �
                                           Chapter 13:  Special Effects   297


                 void main()
                 {
                    unsigned char key, aux;
                    int handle;
                    int old_mode;
                    int x, y;
                    fg_initpm();
                    old_mode = fg_getmode();
                    fg_setmode(19);
                    fg_vbinit();
                    handle = fg_vbdefine(buffer,320,200);
                    fg_vbopen(handle);
                    fg_loadpcx("CORAL.PCX",0);
                    fg_vbclose();
                    fg_setcolor(2);
                    fg_fillpage();
                    fg_setcolor(15);
                    fg_box(111,208,69,130);
                    fg_locate(3,8);
                    fg_text("Press arrow keys to pan.",24);
                    x = 112;
                    y = 129;
                    fg_vbpaste(x,x+95,y-59,y,112,129);
                    do {
                       fg_getkey(&key,&aux);
                       if (aux == 72 && y < 199)
                          y++;
                       else if (aux == 75 && x < 223)
                          x++;
                       else if (aux == 77 && x > 0)
                          x--;
                       else if (aux == 80 && y > 59)
                          y--;
                       fg_vbpaste(x,x+95,y-59,y,112,129);
                    } while (key != 27);
                    fg_setmode(old_mode);
                    fg_reset();
                 }


    Example 13-8 loads our familiar CORAL.PCX image into a 320x200 virtual

buffer. It then sets up a 96x60 region in the middle of the visual page that will serve as a window into the larger CORAL.PCX image (this region is bounded horizontally by x=112 and x=207 and vertically by y=70 and y=129). The first call to fg_vbpaste copies the 96x60 center portion of the virtual buffer to the visual page window. The panning loop is similar to that of example 13-7, except it uses fg_vbpaste to update the window contents. Pressing the arrow keys increments or decrements the coordinates defining the source region in � 298 Fastgraph User's Guide


the virtual buffer. Also, note how we've adjusted the if statements to prevent fg_vbpaste from accessing pixels outside the virtual buffer.


Split Screen

    Fastgraph provides split screen support for EGA, VGA, MCGA, and XVGA

graphics modes (modes 13 through 23) for applications running on VGA or SVGA systems. When a split screen is enabled, the top portion of the screen (rows 0 through n-1, where n is the pixel row at which the split screen takes effect) will contain a subset of the visual video page. The bottom portion (starting at row n) will contain the first fg_getmaxy()-n+1 rows of video page 0. For example, suppose we're using a 200-line graphics mode and we enable a split screen at row 180. If page 1 is the visual video page, the first 180 lines of the screen would be displayed from rows 0 to 179 from page 1, and the last 20 lines would be displayed from rows 0 to 19 of page 0. A split screen environment is useful for maintaining a static image, such as a scoreboard or status box, at the bottom of the screen while scrolling the top portion.

    Example 13-9 demonstrates a typical split screen operation in the 320x200

XVGA graphics mode (mode 20). In this example, we'll assume we want to have a status box occupying the last 20 rows (rows 180 to 199) of the screen, while the upper 180 rows (0 to 179) will be scrolled vertically. The program begins by setting the video mode and then calling fg_measure to compute a processor- dependent delay value for slowing down the scrolling (this technique is further explained in Chapter 16).

    In mode 20, video memory is structured as four 320x200 physical pages.

Page 1 is not visible when we draw the blue box with the white border, so we don't see it until call fg_setvpage to make page 1 the visual page. This of course also makes page 0 invisible, so we don't see the 20-pixel high red hollow box when we draw it on page 0.

    Once we've drawn what we've needed on pages 0 and 1, we activate the

split screen by calling fg_split. The single parameter passed to fg_split is the screen row at which the split screen takes effect, or put another way, the number of rows in the top portion of the screen. In example 13-9 we call fg_split(180), so the first 180 rows of page 1 will appear at the top of the screen, and the first 20 rows of page 0 will appear at the bottom.

    Now we're ready to scroll the upper part of the screen (which is now page

1). Fastgraph's fg_pan routine is suitable for this purpose. We achieve the upward scrolling by incrementing the fg_pan y coordinate in a loop. We achieve the downward scrolling by decrementing the y coordinate. We must call fg_stall (or use another similar method) to force a brief delay between iterations. If we didn't do this, the full 20-row scrolling would appear almost instantly, thus losing the scrolling effect. Note that we couldn't use fg_pan to scroll the upper part of the screen in this manner without setting up a split screen environment. That's because by default fg_pan applies to the entire screen. Using the split screen provides us with two independent video pages, and when page 1 is the active video page, fg_pan doesn't touch page 0.

                                Example 13-9.
   #include <fastgraf.h>
   void main(void);                                                           �
                                           Chapter 13:  Special Effects   299


   void main()
   {
      int delay, y;
      /* initialize the video environment */
      fg_initpm();
      fg_setmode(20);
      /* define a processor-dependent panning delay */
      delay = fg_measure() / 16;
      /* draw a blue box with a white border on page 1 */
      fg_setpage(1);
      fg_setcolor(9);
      fg_fillpage();
      fg_setcolor(15);
      fg_box(0,319,0,199);
      fg_move(160,100);
      fg_justify(0,0);
      fg_print("This is page 1",14);
      /* display what we just drew on page 1 */
      fg_setvpage(1);
      fg_waitkey();
      /* draw a red hollow box at the top of page 0 (now invisible) */
      fg_setpage(0);
      fg_setcolor(12);
      fg_box(0,319,0,19);
      fg_setcolor(15);
      fg_move(160,10);
      fg_print("SPLIT SCREEN",12);
      /* activate the split screen environment, making the first    */
      /* 20 lines of page 0 appear at the bottom of the screen,     */
      /* and making the first 180 lines of page 1 appear at the top */
      fg_split(180);
      fg_waitkey();
      /* pan upward in one-line increments, displaying the rest of */
      /* page 1                                                    */
      fg_setpage(1);
      for (y = 0; y <= 20; y++)
      {
         fg_pan(0,y);
         fg_stall(delay);
      }
      fg_waitkey();                                                           �

300 Fastgraph User's Guide


      /* pan back down in one-line increments to the original position */
      for (y = 20; y >= 0; y--)
      {
         fg_pan(0,y);
         fg_stall(delay);
      }
      fg_waitkey();
      /* restore 80x25 text mode and exit */
      fg_setmode(3);
      fg_reset();
   }


    To switch from a split screen environment back to a "single page"

environment, call fg_split with a row parameter equal to the vertical screen resolution for the current video mode.


Summary of Special Effects Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_FADEIN incrementally replaces the visual page contents with the hidden

page contents. This routine has no effect in text video modes and is not applicable to virtual buffers.

    FG_FADEOUT incrementally replaces the visual page contents with pixels of

the current color. This routine has no effect in text video modes and is not applicable to virtual buffers.

    FG_PAN changes the screen origin (the upper left corner of the screen) to

the specified screen space coordinates. This routine has no effect in text video modes and is not applicable to virtual buffers.

    FG_PANW is the world space version of the fg_pan routine.
    FG_RESIZE changes the dimensions of a video page in EGA and VGA graphics

modes. This routine is disabled when a virtual buffer is active.

    FG_SCROLL vertically scrolls a region of the active video page. The

scrolling may be done either up or down, using either an end-off or circular method. Circular scrolling uses part of the hidden page as a temporary workspace. This routine is not functional when a virtual buffer is active.

    FG_SPLIT enables or disables a split screen environment in EGA, VGA,

MCGA, and XVGA graphics modes.




Chapter 14



Input Device Support � 302 Fastgraph User's Guide


Overview

    The selection of application input devices is an important part of

designing a program for the IBM PC and PS/2 family of systems. The keyboard and mouse are the most popular, and in fact more and more applications, especially those that use a graphical interface, actually require a mouse to use the product. Another input device, primarily used in entertainment software, is the joystick. Although not as popular as the mouse, joysticks nevertheless can simplify the use of certain applications. Fastgraph provides support for these three types of input devices, and this chapter will discuss this in detail.


Keyboard Support

    Fastgraph's keyboard support includes routines to read keystrokes, check

the state of certain keys, and set the state of these keys. In addition, Fastgraph provides a low-level keyboard handler that replaces the BIOS keyboard handler to increase keyboard responsiveness. These routines are independent of the other parts of Fastgraph and thus do not require that you call fg_setmode. All keyboard-related routines work in text and graphics video modes.

    The IBM PC and PS/2 keyboards produce two types of character codes --

standard codes and extended codes (extended codes are sometimes called auxiliary codes). The standard codes correspond to the 128 characters in the ASCII character set. In general, pressing keys on the main part of the keyboard, or on the numeric keypad with NumLock turned on, will generate a standard code. The 128 extended codes are specific to the IBM PC and PS/2 keyboards. Some common keystrokes that produce extended codes are keys on the numeric keypad with NumLock turned off, the function keys, or pressing Alt with another key. The following tables show the standard and extended keyboard codes.

                      Table of standard keyboard codes
          key     code   key     code   key     code   key     code
          (none)    0    space    32    @        64    `        96
          Ctrl+A    1    !        33    A        65    a        97
          Ctrl+B    2    "        34    B        66    b        98
          Ctrl+C    3    #        35    C        67    c        99
          Ctrl+D    4    $        36    D        68    d       100
          Ctrl+E    5    %        37    E        69    e       101
          Ctrl+F    6    &        38    F        70    f       102
          Ctrl+G    7    '        39    G        71    g       103
          Ctrl+H    8    (        40    H        72    h       104
          Ctrl+I    9    )        41    I        73    i       105
          Ctrl+J   10    *        42    J        74    j       106
          Ctrl+K   11    +        43    K        75    k       107
          Ctrl+L   12    ,        44    L        76    l       108
          Ctrl+M   13    -        45    M        77    m       109
          Ctrl+N   14    .        46    N        78    n       110
          Ctrl+O   15    /        47    O        79    o       111
          Ctrl+P   16    0        48    P        80    p       112            �
                                      Chapter 14:  Input Device Support   303


          Ctrl+Q   17    1        49    Q        81    q       113
          Ctrl+R   18    2        50    R        82    r       114
          Ctrl+S   19    3        51    S        83    s       115
          Ctrl+T   20    4        52    T        84    t       116
          Ctrl+U   21    5        53    U        85    u       117
          Ctrl+V   22    6        54    V        86    v       118
          Ctrl+W   23    7        55    W        87    w       119
          Ctrl+X   24    8        56    X        88    x       120
          Ctrl+Y   25    9        57    Y        89    y       121
          Ctrl+Z   26    :        58    Z        90    z       122
          Ctrl+[   27    ;        59    [        91    {       123
          Ctrl+\   28    <        60    \        92    |       124
          Ctrl+]   29    =        61    ]        93    }       125
          Ctrl+^   30    >        62    ^        94    ~       126
          Ctrl+-   31    ?        63    _        95    Ctrl+BS 127


                      Table of extended keyboard codes
             code        key
              3          Ctrl+@
             15          Shift+Tab (back tab)
             16-25       Alt+Q to Alt+P (top row of letters)
             30-38       Alt+A to Alt+L (middle row of letters)
             44-50       Alt+Z to Alt+M (bottom row of letters)
             59-68       F1 to F10
             71          Home
             72          up arrow
             73          PgUp
             75          left arrow
             77          right arrow
             79          End
             80          down arrow
             81          PgDn
             82          Ins
             83          Del
             84-93       Shift+F1 to Shift+F10
             94-103      Ctrl+F1 to Ctrl+F10
             104-113     Alt+F1 to Alt+F10
             114         Ctrl+PrtSc
             115         Ctrl+left arrow
             116         Ctrl+right arrow
             117         Ctrl+End
             118         Ctrl+PgDn
             119         Ctrl+Home
             120-131     Alt+1 to Alt+= (top row of keys)
             132         Ctrl+PgUp


In addition, four keys generate the same standard codes as other control key combinations. These keys are:

                        key          same as   code
                        Backspace    Ctrl+H      8                            �

304 Fastgraph User's Guide


                        Tab          Ctrl+I      9
                        Enter        Ctrl+M     13
                        Escape       Ctrl+[     27
    The CapsLock, NumLock, and ScrollLock keys do not generate a standard or

extended code when pressed. Instead, they toggle between off and on states.


Reading Keystrokes

    When you press a key or key combination, the standard or extended code

representing that keystroke is stored in the ROM BIOS keyboard buffer. This buffer can hold up to 16 keystrokes and thus provides a type-ahead capability. Fastgraph includes three routines for reading keystroke information from the keyboard buffer. The fg_getkey routine reads the next item in the keyboard buffer if one is available (that is, if a key has been pressed). If the keyboard buffer is empty (meaning no key has been pressed), fg_getkey waits for a keystroke and then reports information about it. Another routine, fg_intkey, reads the next keystroke from the keyboard buffer if one is available. If the keyboard buffer is empty, fg_intkey immediately returns and reports this condition. The fg_intkey routine is useful when a program must continue performing a task until a key is pressed. We've already seen the third routine, fg_waitkey, which flushes the keyboard buffer and then waits for another keystroke. Unlike fg_getkey and fg_intkey, fg_waitkey does not return any keystroke information. It is most useful in "press any key to continue" situations.

    Both fg_getkey and fg_intkey require two one-byte arguments passed by

reference. If the keystroke is represented by a standard keyboard code, fg_getkey and fg_intkey return its code in the first argument and set the second argument to zero. Similarly, if the keystroke generates an extended code, the routines return its code in the second argument and set the first argument to zero. If fg_intkey detects an empty keyboard buffer, it sets both arguments to zero.

    Example 14-1 is a simple program that uses fg_getkey. It solicits

keystrokes and then displays the two values returned by fg_getkey, one of which will always be zero. The variable key receives the key's standard code, while aux receives its extended code. Note that fg_initpm and fg_getkey are the only Fastgraph routines in the program; this can be done because the keyboard support routines are logically independent from the rest of Fastgraph. The program returns to DOS when you press the Escape key.

                                Example 14-1.
               #include <fastgraf.h>
               #include <stdio.h>
               void main(void);
               #define ESC 27
               void main()
               {
                  unsigned char key, aux;
                  fg_initpm();                                                �
                                      Chapter 14:  Input Device Support   305


                  do {
                     fg_getkey(&key,&aux);
                     printf("key = %3d  aux = %3d\n",key,aux);
                     }
                  while (key != ESC);
               }


    Example 14-2 reads keystrokes using fg_intkey at half-second intervals

(18.2 fg_waitfor units equal one second). As in the previous example, the program displays the standard and extended codes for each keystroke. However, example 14-2 will continuously execute the while loop even if no keystrokes are available, in which case the key and aux values will both be zero. The program returns to DOS when you press the Escape key.

                                Example 14-2.
               #include <fastgraf.h>
               #include <stdio.h>
               void main(void);
               #define ESC 27
               void main()
               {
                  unsigned char key, aux;
                  fg_initpm();
                  do {
                     fg_waitfor(9);
                     fg_intkey(&key,&aux);
                     printf("key = %3d  aux = %3d\n",key,aux);
                     }
                  while (key != ESC);
               }


    When you use fg_intkey in a "tight" loop that does little else, you

should force a small delay within the loop by calling fg_waitfor as in example 14-2. Typically a delay of one or two clock ticks is enough. Without this delay, the BIOS may not be able to handle all keyboard activity, and thus some keystrokes may not be available to your program.


Testing and Setting Key States

    As mentioned earlier, the CapsLock, NumLock, and ScrollLock keys do not

generate a standard or extended code when pressed but instead toggle between off and on states. Fastgraph includes routines for checking the state of these keys, as well as setting the state of the CapsLock and NumLock keys.

    The Fastgraph routines fg_capslock, fg_numlock, and fg_scrlock

respectively read the state of the CapsLock, NumLock, and ScrollLock keys. Each routine has no arguments and returns the key state as its function value. A return value of 0 means the associated key is in the off state, while 1 � 306 Fastgraph User's Guide


indicates the key is in the on state. If the keyboard does not have a ScrollLock key, fg_scrlock considers the key off and returns a value of zero.

    Example 14-3 is a simple program that uses fg_capslock, fg_numlock, and

fg_scrlock to print messages describing the current state of these three keys.

                                Example 14-3.
                    #include <fastgraf.h>
                    #include <stdio.h>
                    void main(void);
                    void main()
                    {
                       fg_initpm();
                       if (fg_capslock())
                          printf("CapsLock is on.\n");
                       else
                          printf("CapsLock is off.\n");
                       if (fg_numlock())
                          printf("NumLock is on.\n");
                       else
                          printf("NumLock is off.\n");
                       if (fg_scrlock())
                          printf("ScrollLock is on.\n");
                       else
                          printf("ScrollLock is off.\n");
                    }


    You also can set the state of the CapsLock and NumLock keys within a

program. Fastgraph includes two routines, fg_setcaps and fg_setnum, for this purpose. Each routine requires an integer argument that specifies the new key state. If the argument value is 0, the key will be turned off; if the value is 1, the key will be turned on. Example 14-4 uses fg_setcaps and fg_setnum to turn off CapsLock and NumLock.

                                Example 14-4.
                            #include <fastgraf.h>
                            void main(void);
                            void main()
                            {
                               fg_initpm();
                               fg_setcaps(0);
                               fg_setnum(0);
                            }


    On most keyboards, changing key states with fg_setcaps or fg_setnum also

will change the keyboard state light to reflect the new key state. However, some older keyboards, especially when used on PC, PC/XT, or Tandy 1000 �

                                      Chapter 14:  Input Device Support   307


systems, do not update the state light. This makes the state light inconsistent with the true key state.


Low-Level Keyboard Handler

    Fastgraph includes a low-level keyboard handler that replaces the BIOS

keyboard handler. The replacement handler intercepts keystrokes ahead of the BIOS and thus eliminates the annoying beep that sounds upon filling the BIOS keyboard buffer. Fastgraph's keyboard handler is especially well-suited to game development because it increases keyboard responsiveness in high-speed action games. However, when the low-level keyboard handler is enabled, it is not possible to use fg_getkey, fg_intkey, fg_waitkey, or any third party functions that use BIOS or DOS services for keyboard activity. For this reason, a program that enables the low-level keyboard handler must disable it before exiting to DOS.

    The low-level keyboard handler can be enabled and disabled at any time.

The fg_kbinit routine is provided for this purpose. To enable Fastgraph's low- level keyboard handler, pass the value 1 to fg_kbinit. To disable Fastgraph's handler and re-enable the BIOS keyboard handler, pass the value zero. No harm is caused if you try to enable Fastgraph's keyboard handler when it is already active, or if you try to disable it when the BIOS handler is active.

    When the low-level keyboard handler is enabled, you can use fg_kbtest to

check if keys are currently pressed or released. This routine provides the only mechanism for accessing the keyboard when the low-level handler is enabled. It specifies the keys through scan codes. If the corresponding key is pressed, fg_kbtest returns 1. If it is released, the routine returns zero. The fg_kbtest routine can test if any key is pressed if you pass it the value 0 instead of a specific scan code. The following table lists the scan codes corresponding to the keys on a standard PC keyboard.

                             Table of scan codes
                  scan           scan           scan           scan
          key     code   key     code   key     code   key     code
          Esc       1    I        23    X        45    F9       67
          1         2    O        24    C        46    F10      68
          2         3    P        25    V        47    NumLock  69
          3         4    [        26    B        48    ScrLock  70
          4         5    ]        27    N        49    Home     71
          5         6    Enter    28    M        50    Up arrow 72
          6         7    Ctrl     29    ,        51    PgUp     73
          7         8    A        30    .        52    KP-      74
          8         9    S        31    /        53    L arrow  75
          9        10    D        32    R shift  54    KP5      76
          0        11    F        33    KP*      55    R arrow  77
          -        12    G        34    Alt      56    KP+      78
          =        13    H        35    Space    57    End      79
          BS       14    J        36    CapsLock 58    Dn arrow 80
          Tab      15    K        37    F1       59    PgDn     81
          Q        16    L        38    F2       60    Ins      82
          W        17    ;        39    F3       61    Del      83
          E        18    '        40    F4       62    (unused) 84            �

308 Fastgraph User's Guide


          R        19    `        41    F5       63    (unused) 85
          T        20    L shift  42    F6       64    (unused) 86
          Y        21    \        43    F7       65    F11      87
          U        22    Z        44    F8       66    F12      88


    There are actually more scan codes defined for PC keyboards than listed

in this table. Such scan codes are generated when a key is pressed as a combination of one or more keys, such as when the shift and slash keys are pressed together to produce a question mark (?) character. Fastgraph's low- level keyboard handler is designed to report the pressing or releasing of keys themselves, as opposed to reporting the actual characters so produced. It is thus not possible for the keyboard handler to report the scan code for a multi-key character. If needed, such characters can be identified by the scan codes generated for each key in the sequence. For example, a question mark character would be reported as a forward slash (scan code 53) generated while pressing the left shift (42) or right shift (54) keys.

    Example 14-5 illustrates the use of Fastgraph's low-level keyboard

handler. It first uses fg_kbinit to enable Fastgraph's keyboard handler and displays a message stating this. Then, at approximately one second intervals, the program calls fg_kbtest to check which of the four arrow keys are pressed and displays an appropriate message. Pressing Escape restores the BIOS keyboard handler and exits to DOS.

                                Example 14-5.
               #include <fastgraf.h>
               #include <stdio.h>
               void main(void);
               #define ESC    1
               #define LEFT  75
               #define RIGHT 77
               #define UP    72
               #define DOWN  80
               void main()
               {
                  fg_initpm();
                  fg_kbinit(1);
                  printf("Keyboard handler enabled.\n");
                  do {
                     printf("keys pressed:  ");
                     if (fg_kbtest(LEFT))   printf("Left ");
                     if (fg_kbtest(RIGHT))  printf("Right ");
                     if (fg_kbtest(UP))     printf("Up ");
                     if (fg_kbtest(DOWN))   printf("Down ");
                     printf("\n");
                     fg_waitfor(18);
                  } while (fg_kbtest(ESC) == 0);
                  fg_kbinit(0);
                  printf("Keyboard handler disabled.\n");
               }                                                              �
                                      Chapter 14:  Input Device Support   309



    Fastgraph includes two other routines for the low-level keyboard handler.

The fg_kblast function returns the scan code for the most recent keypress processed by the low-level keyboard handler. If there have been no key presses since calling fg_kbinit, the return value will be zero. The fg_kbreset routine resets the state of Fastgraph's low-level keyboard handler to what it was after being initialized with fg_kbinit(1). This has the effect of "flushing" the keyboard handler. Neither of these two functions has any arguments.


Mouse Support

    The mouse is a very popular input and pointing device, especially in

graphically-oriented programs. Fastgraph contains several routines to support mice. These routines perform such tasks as mouse initialization, controlling and defining the mouse cursor, and reporting information about the mouse position and button status.

    The underlying software that controls the mouse is called the mouse

driver. Fastgraph's mouse support routines provide a high-level interface to this driver. The Microsoft Mouse and its accompanying mouse driver have become an industry standard, and other manufacturers of mice have also made their mouse drivers Microsoft compatible. For this reason, the Fastgraph mouse support routines assume you are using a Microsoft or compatible mouse driver.

    Unfortunately, not all mouse drivers are created equal. That is, some

drivers are not Microsoft compatible, even though they may be advertised as such. In some cases, these incompatibilities are rather trivial, but others are significant. For example, early versions of some third party mouse drivers had real problems in the EGA graphics modes. The Microsoft mouse driver, the Logitech mouse driver (version 3.2 or above), and the DFI mouse driver (version 3.00 or above) are known to work well with Fastgraph's mouse support routines. Any other Microsoft compatible mouse driver also should work properly.


Initializing the Mouse

    There are two steps required to use Fastgraph's mouse support routines

within an application program. First, you must install the mouse driver. This is done before running the application, typically by entering the command MOUSE at the DOS command prompt. Second, you must use Fastgraph's fg_mouseini function to initialize the mouse within the program.

    The fg_mouseini function has no arguments and returns a "success or

failure" indicator as its function value. If the return value is -1, it means fg_mouseini could not initialize the mouse (either because the mouse driver is not installed, or the driver is installed but the mouse is physically disconnected). The return value will also be -1 if fg_mouseini is called when a virtual buffer is active. If fg_mouseini returns a positive integer value, the mouse initialization was successful. The value itself indicates the number of buttons (either 2 or 3) on the mouse. If you don't call fg_mouseini, or if � 310 Fastgraph User's Guide


fg_mouseini can't initialize the mouse, none of Fastgraph's other mouse support routines will have any effect.3

    Example 14-6 illustrates how to initialize the mouse. Unlike the keyboard

support routines, Fastgraph's mouse support routines require that fg_setmode be called first. In this example, we simply pass fg_setmode the value -1 to initialize Fastgraph for whatever video mode is in effect when we run the program. The program then calls fg_mouseini and prints a message indicating whether or not the initialization was successful. If it was, the message includes the number of buttons on the mouse.

                                Example 14-6.
              #include <fastgraf.h>
              #include <stdio.h>
              void main(void);
              void main()
              {
                 int status;
                 fg_initpm();
                 fg_setmode(-1);
                 status = fg_mouseini();
                 if (status < 0)
                    printf("Mouse not available.\n");
                 else
                    printf("%d button mouse found.\n",status);
              }


    You should be aware that certain mouse drivers do not fully initialize

the mouse when a program changes video modes. This problem most frequently occurs when you restore the original video mode at the end of a program that has called fg_mouseini. When changing video modes, you must first make the mouse cursor invisible (this is described in the next section), change the video mode, and then call fg_mouseini again to initialize the mouse for the new video mode.


XVGA and SVGA Mouse Considerations

    Mouse drivers cannot directly display the mouse cursor in XVGA and SVGA

graphics modes (modes 20 to 29). Hence, Fastgraph must display the mouse cursor through an interrupt handler that is activated whenever the mouse moves. The handler is automatically installed when you call fg_mouseini in modes 20 to 29.


____________________

  (3) If you use another mouse library or communicate directly with the mouse

driver, you must still call fg_mouseini if your program runs in modes 13 through 18. Otherwise, Fastgraph won't know that your program is using a mouse and may display graphics incorrectly. �

                                      Chapter 14:  Input Device Support   311


    If you do not disable this handler before your program exits, it will

remain "hooked" to the mouse driver. This will most likely hang your system the next time you try doing anything of consequence. The fg_mousefin routine removes Fastgraph's mouse interrupt handler from the mouse driver. In XVGA and SVGA graphics modes, you should call fg_mousefin just before restoring the original video mode, as shown here:


                            fg_mousefin();
                            fg_setmode(old_mode);
                            fg_reset();


Again, calling fg_mousefin is required only in XVGA and SVGA graphics modes. Calling it in other video modes is not applicable, though it causes no problems.

    In the standard VGA/MCGA 256-color mode (mode 19), white pixels in the

mouse cursor are displayed in color 15. This is inconsistent with other graphics modes, where the mouse cursor's white pixels are displayed in the highest-numbered color value available in that mode. Fastgraph corrects this inconsistency in XVGA and SVGA 256-color graphics modes by displaying white mouse cursor pixels in color 255. Like color 15, color 255 is white by default. This allows you to redefine color 15 in your 256-color applications without interfering with the mouse cursor colors.


Controlling the Mouse Cursor

    The mouse cursor indicates the current position of the mouse. By default,

the cursor is a small white arrow in graphics modes and a one-character rectangle in text modes. After you use fg_mouseini to initialize the mouse, the mouse cursor is invisible. To make it visible, you must use fg_mousevis. This routine has a single integer argument that defines the mouse cursor visibility. If it is 0, the mouse cursor will be invisible; if it is 1, the mouse cursor becomes visible. If the mouse cursor is already in the requested state, fg_mousevis does nothing.

    If the mouse cursor is in an area of the screen being updated, or if it

moves into this area during the update process, you must make the mouse cursor invisible or freeze it at its current position. You must also do this when performing any video output in the native EGA and VGA graphics modes (modes 13 through 18). Instead of checking for these conditions, it is often more convenient and efficient to make the mouse cursor invisible during all screen updates and then make it visible again when the updating is finished. An alternative to making the mouse cursor invisible is freezing it at its current position using fg_mousepos and fg_mouselim (these routines will be described shortly) during screen updates and then restoring the default mouse limits. Note, however, that this method only works if the mouse cursor is outside the area being updated. You must also make the mouse cursor invisible when changing the visual page number with fg_setvpage.

    After you initialize the mouse, the cursor is positioned in the center of

the screen. Moving the mouse of course changes the cursor position, but you also can position the mouse cursor with the Fastgraph routine fg_mousemov. This routine has two arguments that specify the new horizontal and vertical � 312 Fastgraph User's Guide


cursor position. The position is expressed in screen space units for graphics modes, while it is expressed in character cells for text modes. The fg_mousemov routine moves the cursor whether or not it is visible.

    Sometimes it is useful to restrict the mouse cursor to a specific area of

the screen. The Fastgraph routine fg_mouselim prevents the mouse cursor from moving outside the specified rectangular area. It requires four arguments that specify the minimum horizontal coordinate, maximum horizontal coordinate, minimum vertical coordinate, and maximum vertical coordinate of this area. Again, the coordinates are expressed in screen space units for graphics modes and character cells for text modes.

    One of the most important functions of the mouse driver is to translate

the horizontal and vertical mouse movements into a position on the screen. The mouse reports these movements to the mouse driver in units called mickeys (one mickey is about 1/200 of an inch, though for some mouse drivers it is 1/400 of an inch). By default, moving the mouse 8 mickeys in the horizontal direction moves the mouse cursor one horizontal pixel. Similarly, moving the mouse 16 mickeys vertically moves the cursor one vertical pixel. Fastgraph provides a routine named fg_mousespd that can change these values, which effectively allows you to control the speed at which the mouse cursor moves relative to the movement of the mouse itself. The fg_mousespd routine requires two arguments that define the number of mickeys required for eight pixels of mouse cursor movement. The first argument specifies this for the horizontal direction, and the second for the vertical direction.

    Example 14-7, which runs in any graphics mode, demonstrates fg_mousevis,

fg_mousemov, fg_mouselim, and fg_mousespd. The program first establishes the video mode, initializes the mouse, and fills the screen with a white rectangle. Next, the program calls fg_mousevis to make the mouse cursor visible and then calls fg_mouselim to restrict the mouse cursor to an area one-fourth the size of the screen, centered in the middle of the screen. At this point you should move the mouse cursor around the screen to see the effect of fg_mouselim and note the speed at which the cursor moves relative to the mouse itself. The program continues when you press any key.

    The program then uses fg_mousemov to move the mouse cursor to each corner

of the region established by fg_mouselim. The call to fg_waitfor keeps the cursor in each corner for two seconds, unless you move the mouse. Note how the program tries to move the mouse cursor to each corner of the screen, but since doing so would move the cursor outside the defined region of movement, fg_mousemov just positions the cursor at the nearest point possible within this region. The last call to fg_mousemov moves the cursor back to the middle of the screen. After doing this, the program calls fg_mousespd to change the mouse cursor speed. The values passed to fg_mousespd (16 and 32) are twice the defaults and therefore make you move the mouse twice as far as before to move the mouse cursor the same distance. When you run the program, compare the mouse sensitivity to the original speed. After a keystroke, the program returns to DOS.

                                Example 14-7.
              #include <fastgraf.h>
              #include <stdio.h>
              #include <stdlib.h>
              void main(void);                                                �
                                      Chapter 14:  Input Device Support   313


              void main()
              {
                 int maxx, maxy;
                 int old_mode;
                 fg_initpm();
                 old_mode = fg_getmode();
                 fg_setmode(fg_automode());
                 if (fg_mouseini() < 0) {
                    fg_setmode(old_mode);
                    fg_reset();
                    exit(1);
                    }
                 maxx = fg_getmaxx();
                 maxy = fg_getmaxy();
                 fg_setcolor(15);
                 fg_rect(0,maxx,0,maxy);
                 fg_mousevis(1);
                 fg_mouselim(maxx/4,3*maxx/4,maxy/4,3*maxy/4);
                 fg_waitkey();
                 fg_mousemov(0,0);
                 fg_waitfor(36);
                 fg_mousemov(maxx,0);
                 fg_waitfor(36);
                 fg_mousemov(maxx,maxy);
                 fg_waitfor(36);
                 fg_mousemov(0,maxy);
                 fg_waitfor(36);
                 fg_mousemov(maxx/2,maxy/2);
                 fg_mousespd(16,32);
                 fg_waitkey();
                 fg_setmode(old_mode);
                 fg_reset();
              }


Reporting the Mouse Status

    It is obviously important to be able to track the mouse position and

button status. The Fastgraph routines fg_mousepos and fg_mousebut enable you to do this.

    The fg_mousepos routine returns information about the current mouse

cursor position and button status. It requires three integer arguments, all passed by reference. The first two arguments respectively receive the horizontal and vertical coordinates of the mouse cursor. These values are expressed in screen space units for graphics modes and character cells for text modes. The third argument receives a three-bit mask containing the button status as shown here: � 314 Fastgraph User's Guide


                  bit
                number  meaning
                   0    1 if left button pressed, 0 if not
                   1    1 if right button pressed, 0 if not
                   2    1 if middle button pressed, 0 if not

For example, if both the left and right buttons are pressed, the button status will be set to 3. If the mouse only has two buttons, bit 2 will always be zero.

    Another routine, fg_mousebut, is available for returning the number of

button press or release counts that have occurred since the last check, or since calling fg_mouseini. Each mouse button maintains its own separate counters, so fg_mousebut returns this information for a specific button. Additionally, fg_mousebut returns the horizontal and vertical position of the mouse cursor at the time the specified button was last pressed or released.

    The fg_mousebut routine takes four integer arguments, of which the last

three are passed by reference. The absolute value of first argument specifies the button of interest (1 means the left button, 2 is the right button, and 3 is the middle button), while its actual value determines if we're checking presses or releases. If the value is positive, button press counts will be reported. If it is negative, release counts will be reported. The second, third, and fourth arguments respectively receive the press or release count, the horizontal mouse cursor position at the time of the last press or release, and the vertical position at that same time. If the press or release count is zero, the mouse cursor position is returned as (0,0). The coordinate positions are expressed in screen space units for graphics modes and character cells for text modes.

    Example 14-8 runs in any graphics video mode and illustrates the use of

fg_mousepos and fg_mousebut. The program first establishes the video mode and then initializes the mouse (the program exits if the initialization fails). It next fills the entire screen with a white rectangle and then calls fg_mousevis to make the mouse cursor visible.

    The main part of example 14-8 is a while loop that polls the mouse at

three-second intervals (the call fg_waitfor(54) delays the program for three seconds). Within the loop, the program first uses fg_mousebut to get the number of times the left mouse button was pressed in the last three seconds. Following this, the fg_mousepos routine gets the current mouse position. The program then displays this information in the upper left corner of the screen; note how fg_mousevis is used to make the cursor invisible during graphics operations. The program continues until you press the right mouse button, checked by the call to fg_mousebut at the end of the loop.

                                Example 14-8.
         #include <fastgraf.h>
         #include <stdio.h>
         #include <stdlib.h>
         void main(void);
         void main()                                                          �
                                      Chapter 14:  Input Device Support   315


         {
            int old_mode;
            int buttons, count;
            int x, y;
            char string[25];
            fg_initpm();
            old_mode = fg_getmode();
            fg_setmode(fg_automode());
            if (fg_mouseini() < 0) {
               fg_setmode(old_mode);
               fg_reset();
               exit(1);
               }
            fg_setcolor(15);
            fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
            fg_mousevis(1);
            do {
               fg_waitfor(54);
               fg_mousebut(1,&count,&x,&y);
               fg_mousepos(&x,&y,&buttons);
               sprintf(string,"X=%3d  Y=%3d  count=%4d",x,y,count);
               fg_mousevis(0);
               fg_setcolor(15);
               fg_rect(0,fg_xconvert(25),0,fg_yconvert(1));
               fg_setcolor(0);
               fg_locate(0,0);
               fg_text(string,24);
               fg_mousevis(1);
               fg_mousebut(2,&count,&x,&y);
               }
            while (count == 0);
            fg_setmode(old_mode);
            fg_reset();
         }


Defining the Mouse Cursor

    By default, the mouse cursor is a small white arrow in graphics modes and

a one-character rectangle in text modes. In graphics modes, you can change the mouse cursor to any 16 by 16 pixel image with the Fastgraph routine fg_mouseptr (in the CGA four-color graphics modes, the cursor size is 8 by 16 pixels). You cannot change the mouse cursor shape in text modes, but you can use the Fastgraph routine fg_mousecur to define how it interacts with existing characters on the screen. � 316 Fastgraph User's Guide


Text Modes

    To change the mouse cursor in text modes, you must first define two 16-

bit quantities called the screen mask and cursor mask. The following figure defines the format of each mask.

                   bits           meaning
                   0 to 7         ASCII character value
                   8 to 11        foreground color
                   12 to 14       background color
                   15             blink

Notice how this structure parallels the character and attribute bytes associated with each character cell. The default screen mask is 77FF hex, and the default cursor mask is 7700 hex.

    When you position the mouse over a specific character cell, the mouse

driver uses the current screen and cursor masks to determine the mouse cursor's appearance. First, the mouse driver logically ANDs the screen mask with the existing contents of that character cell. It then XORs that result with the cursor mask to display the mouse cursor.

    For example, consider how the mouse cursor is produced in the 80-column

color text mode (mode 3). Suppose a specific character cell contains the ASCII character 0 (48 decimal, 30 hex) and an attribute byte that specifies a white (color 15) foreground on a blue background (color 1) and does not blink (blink bit 0). The binary structure of the character and its attribute are:

                            attribute    character
                            0 001 1111   00110000


Now let's see what happens when we apply the screen and cursor masks to the character and its attribute.


           attribute/character   0001 1111 0011 0000   (1F30 hex)
           default screen mask   0111 0111 1111 1111   (77FF hex)
                                 -------------------
           result of AND         0001 0111 0011 0000   (1730 hex)
           default cursor mask   0111 0111 0000 0000   (7700 hex)
                                 -------------------
           result of XOR         0110 0000 0011 0000   (6030 hex)


The resulting character (30 hex) is the original character, but the new attribute (60 hex) represents a black foreground with a brown background and does not blink. As long as the mouse cursor remains positioned on this character cell, it would appear black on brown.

    When we use the default screen and cursor masks, the mouse cursor will

always display the original character and it will not blink. The cursor foreground color will be 15-F, where F is the displayed character's foreground color. Similarly, the cursor background color will be 7-B, where B is the �

                                      Chapter 14:  Input Device Support   317


displayed character's background color. The default masks will virtually always produce a satisfactory mouse cursor.

    It is possible, however, to change the appearance of the mouse cursor in

text modes by using your own screen and cursor masks. The Fastgraph routine fg_mousecur does just that. It expects two arguments, the first being the cursor mask and the second the screen mask. Example 14-9 demonstrates the use of fg_mousecur. The program displays some text and uses the default mouse cursor. After waiting for a keystroke, the program calls fg_mousecur to define a new mouse cursor. The new cursor is similar to the default cursor, but it displays the foreground colors in the opposite intensity as the default cursor. The program then waits for another keystroke before returning to DOS.

                                Example 14-9.
                 #include <fastgraf.h>
                 #include <stdio.h>
                 #include <stdlib.h>
                 void main(void);
                 void main()
                 {
                    int old_mode;
                    int row;
                    fg_initpm();
                    old_mode = fg_getmode();
                    fg_setmode(3);
                    if (fg_mouseini() < 0) {
                       fg_setmode(old_mode);
                       fg_reset();
                       exit(1);
                       }
                    fg_setattr(7,0,0);
                    fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                    fg_setattr(12,7,0);
                    for (row = 0; row < 25; row++) {
                       fg_locate(row,34);
                       fg_text("example 14-9",12);
                       }
                    fg_mousevis(1);
                    fg_waitkey();
                    fg_mousecur(0x7FFF,0x7F00);
                    fg_waitkey();
                    fg_setmode(old_mode);
                    fg_reset();
                 }                                                            �

318 Fastgraph User's Guide


Graphics Modes

    Defining the mouse cursor in graphics video modes also requires creating

a screen mask and cursor mask, but as one might expect, the structure of these masks is vastly different from text modes. In fact, it closely resembles the mode-independent bitmap format used by fg_drawmap. Although their structure differs, the way the mouse driver applies the masks is the same as in the text modes. That is, the driver displays the mouse cursor by first logically ANDing video memory with the screen mask, and then XORing that result with the cursor mask.

    Let's begin by looking at the masks for the default mouse cursor in

graphics modes. The size of each mask (and hence the mouse cursor) is 16 pixels wide and 16 pixels high. As mentioned earlier, the default cursor is a small white arrow with a black outline around it. Here are its screen and cursor masks expressed as binary values.

             screen                cursor                cursor
              mask                  mask               appearance
        1001111111111111      0000000000000000       **
        1000111111111111      0010000000000000       *x*
        1000011111111111      0011000000000000       *xx*
        1000001111111111      0011100000000000       *xxx*
        1000000111111111      0011110000000000       *xxxx*
        1000000011111111      0011111000000000       *xxxxx*
        1000000001111111      0011111100000000       *xxxxxx*
        1000000000111111      0011111110000000       *xxxxxxx*
        1000000000011111      0011111111000000       *xxxxxxxx*
        1000000000001111      0011111000000000       *xxxxx*****
        1000000011111111      0011011000000000       *xx*xx*
        1000100001111111      0010001100000000       *x* *xx*
        1001100001111111      0000001100000000       **  *xx*
        1111110000111111      0000000110000000            *xx*
        1111110000111111      0000000110000000            *xx*
        1111111000111111      0000000000000000             ***
    The mouse driver first ANDs the screen mask with video memory at the

mouse cursor position. This means the screen mask 1 bits leave video memory intact, while the 0 bits change the corresponding pixels to black. Next, the mouse driver XORs the result with the cursor mask. This time the cursor mask 0 bits leave video memory unchanged, while the 1 bits change the corresponding pixels to white. This produces a mouse cursor as shown above on the right, where a dot ( ) represents an unchanged pixel, an asterisk (*) a black pixel, and an x a white pixel. The following table summarizes the cursor appearance for all possible combinations of mask bits.

            screen mask bit  cursor mask bit    resulting cursor pixel
                   0                0                    black
                   0                1                    white
                   1                0                  unchanged
                   1                1                  inverted
    The color of an "inverted" pixel is n-k, where n is the maximum color

number in the current video mode, and k is the color of the pixel being �

                                      Chapter 14:  Input Device Support   319

replaced. Also, "black" and "white" pixels are not necessarily these colors in 16-color and 256-color modes. More correctly, "black" pixels are displayed in the color assigned to palette 0, and "white" pixels are the displayed in the color assigned to palette 15 (255 in XVGA and SVGA 256-color modes). If you're using the CGA color modes, "black" pixels are displayed in the background color, and "white" pixels appear in color 3 (whose actual color is determined by the selected CGA palette).

    With an understanding of the way the default mouse cursor works in

graphics modes, we're now ready to define our own mouse cursor. Shown here are the screen mask, cursor mask, and resulting appearance for a solid plus-shaped cursor. The hexadecimal equivalents of the binary mask values are also given.

  ----- screen mask ----      ----- cursor mask ----
                                                               cursor
       binary       hex            binary       hex          appearance
  1110000000111111  E03F      0000000000000000  0000      ...*******......
  1110000000111111  E03F      0000111110000000  0F80      ...*xxxxx*......
  1110000000111111  E03F      0000111110000000  0F80      ...*xxxxx*......
  0000000000000111  0007      0000111110000000  0F80      ****xxxxx****...
  0000000000000111  0007      0111111111110000  7FF0      *xxxxxxxxxxx*...
  0000000000000111  0007      0111111111110000  7FF0      *xxxxxxxxxxx*...
  0000000000000111  0007      0111111111110000  7FF0      *xxxxxxxxxxx*...
  0000000000000111  0007      0111111111110000  7FF0      *xxxxxxxxxxx*...
  0000000000000111  0007      0111111111110000  7FF0      *xxxxxxxxxxx*...
  0000000000000111  0007      0000111110000000  0F80      ****xxxxx****...
  1110000000111111  E03F      0000111110000000  0F80      ...*xxxxx*......
  1110000000111111  E03F      0000111110000000  0F80      ...*xxxxx*......
  1110000000111111  E03F      0000000000000000  0000      ...*******......
  1111111111111111  FFFF      0000000000000000  0000      ................
  1111111111111111  FFFF      0000000000000000  0000      ................
  1111111111111111  FFFF      0000000000000000  0000      ................

If we wanted to make the mouse cursor hollow rather than solid, the masks and resulting cursor appearance would look like this.

  ----- screen mask ----      ----- cursor mask ----
                                                               cursor
       binary       hex            binary       hex          appearance
  1110000000111111  E03F      0000000000000000  0000      ...*******......
  1110111110111111  EFBF      0000000000000000  0000      ...*.....*......
  1110111110111111  EFBF      0000000000000000  0000      ...*.....*......
  0000111110000111  0F87      0000000000000000  0000      ****.....****...
  0111111111110111  7FF7      0000000000000000  0000      *...........*...
  0111111111110111  7FF7      0000000000000000  0000      *...........*...
  0111111111110111  7FF7      0000001000000000  0200      *.....x.....*...
  0111111111110111  7FF7      0000000000000000  0000      *...........*...
  0111111111110111  7FF7      0000000000000000  0000      *...........*...
  0000111110000111  0F87      0000000000000000  0000      ****.....****...
  1110111110111111  EFBF      0000000000000000  0000      ...*.....*......
  1110111110111111  EFBF      0000000000000000  0000      ...*.....*......
  1110000000111111  E03F      0000000000000000  0000      ...*******......
  1111111111111111  FFFF      0000000000000000  0000      ................
  1111111111111111  FFFF      0000000000000000  0000      ................
  1111111111111111  FFFF      0000000000000000  0000      ................    �

320 Fastgraph User's Guide


Note that the center bit defined in the cursor mask causes the corresponding pixel in video memory to be inverted.

    There is one more item needed to define a graphics mode mouse cursor

completely. That item is the hot spot, or the actual screen position used or reported by the mouse driver. For the plus-shaped cursors just constructed, it would make sense to define the hot spot in the center of the plus. The hot spot is specified relative to the upper left corner of the cursor, so its position within the cursor would be (6,6) -- that is, six pixels to the right and six pixels below the upper left corner. You can specify the hot spot offsets using negative values or values above 15 to position it outside the mouse cursor matrix if desired.

    The Fastgraph routine fg_mouseptr defines a mouse cursor in graphics

modes. The first of its three arguments is a 32-element 16-bit integer array, passed by reference. The array's first 16 elements contain the screen mask, and its second 16 elements contain the cursor mask. The remaining two arguments respectively specify the horizontal and vertical offsets for the hot spot. The fg_mouseptr routine has no effect in a text video mode. In C or C++ programs, we recommend using the short data type for the mask array because short means a 16-bit integer for both 16-bit and 32-bit environments. Similarly, FORTRAN programmers should define the mask array as an INTEGER*2 item.

    Example 14-10 is similar to example 14-9. It shows how to define a

graphics mode mouse cursor using fg_mouseptr. The values stored in the solid and hollow arrays define the screen and cursor masks for the solid and hollow plus-shaped mouse cursors discussed earlier. After making the mouse cursor visible, the program uses the default mouse cursor until a key is pressed. Following this, it changes to the solid cursor. After another keystroke, the program changes to the hollow cursor. When you run example 14-10, compare the differences between the three mouse cursors.

                               Example 14-10.
               #include <fastgraf.h>
               #include <stdio.h>
               #include <stdlib.h>
               void main(void);
               short solid[]  = {0xE03F,0xE03F,0xE03F,0x0007,
                                 0x0007,0x0007,0x0007,0x0007,
                                 0x0007,0x0007,0xE03F,0xE03F,
                                 0xE03F,0xFFFF,0xFFFF,0xFFFF,
                                 0x0000,0x0F80,0x0F80,0x0F80,
                                 0x7FF0,0x7FF0,0x7FF0,0x7FF0,
                                 0x7FF0,0x0F80,0x0F80,0x0F80,
                                 0x0000,0x0000,0x0000,0x0000};
               short hollow[] = {0xE03F,0xEFBF,0xEFBF,0x0F87,
                                 0x7FF7,0x7FF7,0x7FF7,0x7FF7,
                                 0x7FF7,0x0F87,0xEFBF,0xEFBF,
                                 0xE03F,0xFFFF,0xFFFF,0xFFFF,
                                 0x0000,0x0000,0x0000,0x0000,                 �
                                      Chapter 14:  Input Device Support   321


                                 0x0000,0x0000,0x0200,0x0000,
                                 0x0000,0x0000,0x0000,0x0000,
                                 0x0000,0x0000,0x0000,0x0000};
               void main()
               {
                  int old_mode;
                  int column, row, last_row;
                  fg_initpm();
                  old_mode = fg_getmode();
                  fg_setmode(fg_automode());
                  if (fg_mouseini() < 0)
                  {
                     fg_setmode(old_mode);
                     fg_reset();
                     exit(1);
                  }
                  fg_setcolor(15);
                  fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
                  fg_setcolor(12);
                  column = fg_xalpha(fg_getmaxx()/2) - 6;
                  last_row = fg_yalpha(fg_getmaxy()) + 1;
                  for (row = 0; row < last_row; row++)
                  {
                     fg_locate(row,column);
                     fg_text("example 14-10",13);
                  }
                  fg_mousevis(1);
                  fg_waitkey();
                  fg_mouseptr(solid,6,6);
                  fg_waitkey();
                  fg_mouseptr(hollow,6,6);
                  fg_waitkey();
                  fg_setmode(old_mode);
                  fg_reset();
               }


CGA Considerations

    The mouse driver treats the screen and cursor masks differently in the

CGA four-color graphics modes (modes 4 and 5) than in the other graphics modes. In the CGA modes, each pair of mask bits corresponds to one pixel. This means the masks more closely resemble the mode-specific format used by fg_drwimage instead of the mode-independent format of fg_drawmap.

    Fastgraph uses a different default mouse cursor for modes 4 and 5. Its

screen and cursor masks, as well as the resulting cursor appearance, are shown in the following diagram. � 322 Fastgraph User's Guide


               screen                  cursor              cursor
                mask                    mask             appearance
          0000111111111111        0000000000000000        **
          0000001111111111        0011000000000000        ***
          0000000011111111        0011110000000000        ****
          0000000000111111        0011111100000000        *****
          0000000000001111        0011111111000000        ******
          0000000000000011        0011111111110000        *******
          0000000000000011        0011111100000000        *******
          0000000000111111        0011111110000000        *****
          0000000000001111        0011000011000000        ******
          0000110000001111        0000000011000000        ** ***
          1111111100000011        0000000000110000            ***
          1111111100000011        0010000000110000            ***
          1111111111000011        0000000000000000             **
          1111111111111111        0000000000000000
          1111111111111111        0000000000000000
          1111111111111111        0000000000000000

As you can see, the resulting mouse cursor is eight pixels wide instead of 16.

    Another important point concerning mouse cursors in modes 4 and 5 is the

chance of pixel bleeding, or the changing of colors within the mouse cursor as it moves horizontally. Bleeding will occur if you use the bit pairs 01 or 10 in either mask to represent a pixel. In the default masks for modes 4 and 5, note that only the binary values 00 and 11 appear as bit pairs. Keep this in mind if you create your own masks in these video modes.

XVGA and SVGA Considerations

    In XVGA graphics modes and 256-color SVGA graphics modes (20 to 27), it's

possible to create a multicolored mouse cursor. To do this, use fg_mouse256 instead of fg_mouseptr to define the mouse cursor's shape and appearance. The fg_mouse256 routine uses the same arguments as fg_mouseptr, but the masks are passed in a 512-byte array consisting of a 256-byte screen mask followed by a 256-byte cursor mask. As with fg_mouseptr, each mask is structured as a 16x16 pixel grid, but each pixel is represented by a byte value rather than a single bit.

    The mouse driver displays the mouse cursor by logically ANDing video

memory with the screen mask, and then XORing that result with the cursor mask. This normally means the screen mask values are either 0 or 255, while cursor mask values are between 0 and 255. For example, consider again the default graphics mode mouse cursor (the arrow). If we wanted to display the cursor in yellow (color 14) instead of its default white, you would expand the screen mask from 16 to 256 bytes, replacing the zero bits in the "standard" mask with zero bytes and replacing the one bits with the value 255. You would similarly expand the cursor mask, replacing the zero bits with zero bytes and the one bits with the value 14. �

                                      Chapter 14:  Input Device Support   323


Joystick Support

    The third type of input device supported by Fastgraph is the joystick.

Although joysticks are not as popular as mice, they are often preferable when a user's reactions are critical, such as in an arcade-style game. Fastgraph includes routines for initializing a joystick, reading a joystick's position or button status, and making a joystick behave analogously to the keyboard. These routines are independent of the rest of Fastgraph and thus do not require that you first call fg_setmode.

    Joysticks are connected to a system through a game port. The PCjr and

Tandy 1000 systems come equipped with two game ports, and hence support two joysticks. On other systems in the IBM family, you can install a game card with one or two game ports. If the card only has one game port, you can use a splitter cable to fork two joysticks into the port.


Initializing Joysticks

    Before you can use any of Fastgraph's joystick support routines with a

specific joystick, you must initialize that joystick. The fg_initjoy routine performs this task. This routine requires a single integer argument that specifies which joystick to initialize, either 1 or 2. If successful, fg_initjoy returns 0 as the function value. If the machine has no game port, or if the requested joystick is not connected to the game port, fg_initjoy returns -1. When you use fg_initjoy, the joystick being initialized must be centered (that is, the stick itself must not be tilted in either direction).

    Example 14-11 uses the fg_initjoy routine to try to initialize both

joysticks. For each joystick, the program prints a message stating whether or not the initialization was successful.

                               Example 14-11.
                #include <fastgraf.h>
                #include <stdio.h>
                void main(void);
                void main()
                {
                   fg_initpm();
                   if (fg_initjoy(1) < 0)
                      printf("Joystick 1 not available.\n");
                   else
                      printf("Joystick 1 found.\n");
                   if (fg_initjoy(2) < 0)
                      printf("Joystick 2 not available.\n");
                   else
                      printf("Joystick 2 found.\n");
                }                                                             �

324 Fastgraph User's Guide


Reporting Joystick Status

    Each joystick can report three items: its horizontal position, its

vertical position, and the button status. Fastgraph includes routines for obtaining each of these quantities.

    The fg_getxjoy and fg_getyjoy routines respectively return the horizontal

and vertical position of the indicated joystick. Both routines require a single integer argument, whose value is either 1 or 2, to identify the joystick. The requested position is returned as the function value. Horizontal coordinates increase as the joystick moves to the right, while vertical coordinates increase as the joystick moves downward. If fg_initjoy did not initialize the specified joystick, or if your program hasn't yet called fg_initjoy, both fg_getxjoy and fg_getyjoy will return -1.

    Joystick characteristics vary more than those of any other input device.

The values returned by fg_getxjoy and fg_getyjoy depend on the system's processor speed and the brand of joystick used. It often suffices to know the joystick position relative to its previous position, in which case the actual coordinate values do not matter. However, if you must rely on specific coordinate values, your program must perform some type of manual joystick calibration and then scale the coordinates reported by fg_getxjoy and fg_getyjoy as needed.

    The other piece of information joysticks provide is the button status.

Most joysticks have two buttons, called the top and bottom buttons. Others have three buttons, but one of them duplicates the functionality of another (for example, a joystick might have one bottom button on its left side and another on its right side). The Fastgraph routine fg_button returns the joystick button status as its function value. Like fg_getxjoy and fg_getyjoy, fg_button requires a single argument that specifies the joystick number. The meaning of the return value is shown here:

                           value meaning
                             0   neither button pressed
                             1   top button pressed
                             2   bottom button pressed
                             3   top and bottom buttons pressed
    You don't need to call fg_initjoy before using fg_button. If the

specified joystick is not present, fg_button will return a value of 0.

    Example 14-12 uses fg_getxjoy, fg_getyjoy, and fg_button to poll both

joysticks at half-second intervals. It then displays the joystick number (1 or 2), horizontal position, vertical position, and button status for each joystick. As the program runs, you can move the joysticks and watch how the movements affect the displayed coordinate values. The program continues doing this until you press Ctrl/C or Ctrl/Break to stop it.

                               Example 14-12.
                 #include <fastgraf.h>
                 #include <stdio.h>
                 void main(void);                                             �
                                      Chapter 14:  Input Device Support   325


                 void main()
                 {
                    int b, x, y;
                    fg_initpm();
                    fg_initjoy(1);
                    fg_initjoy(2);
                    while (1) {
                       x = fg_getxjoy(1);
                       y = fg_getyjoy(1);
                       b = fg_button(1);
                       printf("1:  %3d %3d %1d\n",x,y,b);
                       x = fg_getxjoy(2);
                       y = fg_getyjoy(2);
                       b = fg_button(2);
                       printf("2:  %3d %3d %1d\n\n",x,y,b);
                       fg_waitfor(9);
                       }
                 }


    There are two ways of effectively monitoring joystick button status. One

is to call fg_button at many places in your program and then take the necessary action depending on the button status. However, the preferable method is to extend the BIOS time-of-day interrupt to check the button status at each clock tick (there are 18.2 clock ticks per second), set a flag if a button is pressed, and then check the flag as needed in your program. Information on changing the BIOS time-of-day interrupt appears in Appendix C.


Keyboard Emulation

    Although we can use fg_getxjoy and fg_getyjoy to monitor relative

joystick movements, it is usually easier to do this with another Fastgraph routine, fg_intjoy. This routine is similar to fg_intkey in that it returns two values equivalent to the standard or extended keyboard codes for analogous keystrokes.

    The fg_intjoy routine needs three arguments. The first argument specifies

the joystick number, either 1 or 2. The second and third arguments, both one- byte quantities passed by reference, receive the standard and extended keyboard codes analogous to the joystick movement and button status. The second argument receives a value of 13 (the standard keyboard code for the Enter key) if any joystick button is pressed; it receives a value of 0 if not. The third argument receives a value corresponding to the extended keyboard code for one of the directional keys on the numeric keypad, as summarized in the following table.

           joystick position   corresponding key   extended key code
              up and left            Home                 71
                  up               up arrow               72
             up and right            PgUp                 73
                 left             left arrow              75                  �

326 Fastgraph User's Guide


               centered           (no action)              0
                 right            right arrow             77
             down and left            End                 79
                 down             down arrow              80
            down and right           PgDn                 81

The fg_intjoy routine will set both key code arguments to zero if the specified joystick has not yet been initialized.

    Example 14-13 is similar to example 14-11, but it uses fg_intjoy in place

of fg_getxjoy and fg_getyjoy to report relative joystick position. This program does not report the joystick button status as example 14-11 does, but you could readily add this feature to it.

                               Example 14-13.
                   #include <fastgraf.h>
                   #include <stdio.h>
                   void main(void);
                   void main()
                   {
                      char key, aux;
                      fg_initpm();
                      fg_initjoy(1);
                      fg_initjoy(2);
                      while (1) {
                         fg_intjoy(1,&key,&aux);
                         printf("1: %2d %2d\n",key,aux);
                         fg_intjoy(2,&key,&aux);
                         printf("2: %2d %2d\n\n",key,aux);
                         fg_waitfor(9);
                         }
                   }


Special Joystick Considerations

    If you develop a program that supports only one joystick, you should use

joystick 1. The reasons for this are twofold. First, it will make your program consistent with most other products that support joysticks. Second, many Tandy 1000 series machines cannot determine if joystick 2 is present when neither joystick is connected. This means if you use joystick 2 instead of joystick 1 in a single joystick program, you won't be able to tell if a joystick is available when running on a Tandy 1000.


Summary of Input Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual. �

                                      Chapter 14:  Input Device Support   327


    FG_BUTTON returns information about the state of either joystick's

buttons.

    FG_CAPSLOCK determines the state of the CapsLock key.
    FG_GETKEY waits for a keystroke (or reads the next entry from the BIOS

keyboard buffer). It returns the keystroke's standard or extended keyboard code.

    FG_GETXJOY and FG_GETYJOY return the horizontal and vertical coordinate

position of the specified joystick. The actual coordinates depend on the processor speed and brand of joystick used.

    FG_INITJOY initializes joystick 1 or 2 and must be called before using

fg_getxjoy, fg_getyjoy, or fg_intjoy. It returns a status code indicating whether or not the initialization was successful.

    FG_INTJOY returns the standard and extended keyboard codes analogous to

the current position and button status of the specified joystick.

    FG_INTKEY reads the next entry from the BIOS keyboard buffer and returns

the keystroke's standard or extended keyboard code. It is similar to fg_getkey, but it does not wait for a keystroke if the keyboard buffer is empty.

    FG_KBINIT enables or disables Fastgraph's low-level keyboard handler. If

the keyboard handler is already in the requested state, nothing happens.

    FG_KBLAST returns the scan code for the most recent keypress processed by

Fastgraph's low-level keyboard handler.

    FG_KBRESET resets the state of Fastgraph's low-level keyboard handler to

what it was after being enabled with fg_kbinit.

    FG_KBTEST determines if the key having the specified scan code is now

pressed or released. The low-level keyboard handler must be enabled for this routine to work properly.

    FG_MOUSE256 defines the shape and appearance of a multicolored mouse

cursor in XVGA and 256-color SVGA graphics modes.

    FG_MOUSEBUT returns information about mouse button press or release

counts, as well as the mouse cursor position at the time of the last button press or release.

    FG_MOUSECUR defines the appearance of the mouse cursor in text video

modes.

    FG_MOUSEFIN unhooks Fastgraph's XVGA or SVGA mouse handler from the mouse

driver. This routine should be used just before reverting to text mode in programs that have called fg_mouseini in XVGA or SVGA graphics modes. It has no effect in other video modes.

    FG_MOUSEINI initializes the mouse and must be called before any of

Fastgraph's other mouse support routines. It returns an error status if the � 328 Fastgraph User's Guide


mouse driver has not been loaded, if the mouse is not connected, or if a virtual buffer is active.

    FG_MOUSELIM defines the rectangular area in which the mouse cursor may

move.

    FG_MOUSEMOV moves the mouse cursor to the specified character cell (in

text modes) or screen space position (in graphics modes).

    FG_MOUSEPOS returns the current mouse position and button status.
    FG_MOUSEPTR defines the shape and appearance of the mouse cursor in

graphics video modes.

    FG_MOUSESPD defines the number of mickey units per eight pixels of cursor

movement. This effectively controls the speed at which the mouse cursor moves relative to the movement of the mouse itself.

    FG_MOUSEVIS makes the mouse cursor visible or invisible.
    FG_NUMLOCK determines the state of the NumLock key.
    FG_SCRLOCK determines the state of the ScrollLock key (which is not

present on some keyboards).

    FG_SETCAPS controls the state of the CapsLock key.
    FG_SETNUM controls the state of the NumLock key.
    FG_WAITKEY flushes the BIOS keyboard buffer (that is, removes any type-

ahead characters) and then waits for another keystroke.




Chapter 15



Sound Effects � 330 Fastgraph User's Guide


Overview

    In the realm of the IBM PC and PS/2 family of systems, a sound is defined

by its frequency, duration, and volume. The frequency of a sound is measured in units called Hertz. While the PC and PS/2 can produce sounds ranging from 18 to more than one million Hertz, the average human can hear sounds between 20 and about 20,000 Hertz. The length of a sound, called its duration, is expressed in clock ticks; there are either 18.2 of 72.8 clock ticks per second, depending on the method used to produce the sound. Finally, the volume determines the loudness of the sound. As we'll see in this chapter, we can control a sound's volume only on the PCjr and Tandy 1000 systems.

    Fastgraph offers several different methods for producing sound effects.

These include single tones, a series of tones expressed numerically, or a series of tones expressed as musical notes. The sound effects may be discrete, continuous, or performed at the same time as other activity. The sound-related routines are independent of the other parts of Fastgraph and do not require any initialization routines be called.


Sound Sources

    All members of the PC and PS/2 families can produce sounds using the

8253-5 programmable timer chip and the internal speaker. This method is limited to producing single sounds of given frequencies and durations, although we can combine these sounds to create interesting audio effects or play music. When we use this technique, we have no control over the sound volume. In fact, sound volumes often vary slightly on different systems because the physical properties of the speaker and its housing are not always the same.

    The PCjr and Tandy 1000 systems have an additional, more powerful chip

for producing sounds. This is the Texas Instruments SN76496A sound chip, called the TI sound chip for short. The TI sound chip has three independent voice channels for producing pure tones, and a fourth channel for generating periodic or white noise. Each voice channel has a separate volume control that allows us to control the loudness of the sound it emits.


Synchronous Sound

    A sound effect is said to be synchronous if it is produced while no other

activity is being performed. In other words, a program makes a synchronous sound by starting the sound, waiting for a specified duration, and then stopping the sound. The program must wait for the sound to complete before doing anything else. As long as the duration is relatively short, the fact that the sound is synchronous has little or no effect on the program's execution speed. Fastgraph includes routines for producing synchronous sound using either the 8253-5 programmable timer or the TI sound chip.

    The fg_sound routine uses the programmable timer to produce a sound of a

given frequency and duration. The frequency, defined by the first argument, is expressed in Hertz and must be an integer value between 18 and 32,767. The second argument defines the duration and is expressed in clock ticks; there �

                                             Chapter 15:  Sound Effects   331


are 18.2 clock ticks per second. If the duration is zero or negative, the sound will continue until it is stopped with fg_quiet.

    Example 15-1 uses fg_sound to create different sound effects, pausing for

one second between each. It first produces three distinct sounds of 20, 100, and 1,000 Hertz. Each of these sounds lasts for approximately 1/6 of a second (three clock ticks). The program then makes a warbling noise by quickly alternating sounds of similar frequencies. Finally, the program creates a sliding tone of increasing frequencies between 100 and 500 Hertz. Each tone in this sequence lasts for two clock ticks, so it takes about 4.5 seconds to play the entire sequence. In all cases, example 15-1 displays an identifying message just before each sound.

                                Example 15-1.
             #include <fastgraf.h>
             #include <stdio.h>
             void main(void);
             void main()
             {
                int freq;
                fg_initpm();
                printf("20 Hz tone...\n");
                fg_sound(20,3);
                fg_waitfor(18);
                printf("100 Hz tone...\n");
                fg_sound(100,3);
                fg_waitfor(18);
                printf("1000 Hz tone...\n");
                fg_sound(1000,3);
                fg_waitfor(18);
                printf("warble...\n");
                fg_sound(400,1);
                fg_sound(410,1);
                fg_sound(400,1);
                fg_sound(410,1);
                fg_waitfor(18);
                printf("sliding tone from 100 to 500 Hz...\n");
                for (freq = 100; freq <= 500; freq+=10)
                   fg_sound(freq,2);
             }


    The fg_voice routine is analogous to fg_sound, but it uses the TI sound

chip rather than the programmable timer to create sound. For this reason, fg_voice can only be used on the PCjr or Tandy 1000 systems. The TI sound chip allows us to control the volume of a sound, and it also offers four distinct voice channels. Thus, fg_voice requires two additional arguments besides frequency and duration to define the voice channel and sound volume. � 332 Fastgraph User's Guide


    The first argument to fg_voice defines the voice channel, as shown here:
                           value meaning
                             1   voice channel #1
                             2   voice channel #2
                             3   voice channel #3
                             4   voice channel #4, periodic noise
                             5   voice channel #4, white noise

If we use voice channels 1, 2, or 3, the second argument defines the sound frequency in Hertz, between 18 and 32,767. If we use voice channel 4, however, the second argument instead is a value that represents a specific frequency, as shown in this table:

                                  value frequency
                                    0   512 Hertz
                                    1  1024 Hertz
                                    2  2048 Hertz

The third argument defines the sound volume. It must be between 0 and 15, where 0 is silent and 15 is loudest. The fourth argument defines the sound duration in clock ticks. As with fg_sound, there are 18.2 clock ticks per second, and if the duration is zero or negative, the sound will continue until stopped with fg_quiet.

    Example 15-2 uses fg_voice to create different sound effects using the TI

sound chip. As in example 15-1, there is a pause of one second between each. The program first calls fg_testmode to be sure it is running on a PCjr or Tandy 1000 system (video mode 9 is only available on these systems). If so, the program uses voice channel #4 to produce a 2,048 Hertz periodic noise, followed by white noise of the same frequency. Both sounds are emitted at the maximum volume level (15) and last for about 1/6 of a second each (three clock ticks). After these noises, example 15-2 produces a 500 Hertz tone of increasing volume. In all cases, the program displays an identifying message just before each sound.

                                Example 15-2.
             #include <fastgraf.h>
             #include <stdio.h>
             #include <stdlib.h>
             void main(void);
             void main()
             {
                int volume;
                fg_initpm();
                if (fg_testmode(9,0) == 0) {
                   printf("This program requires a PCjr or ");
                   printf("a Tandy 1000 system.\n");
                   exit(1);
                   }                                                          �
                                             Chapter 15:  Sound Effects   333


                printf("2048 Hz periodic noise...\n");
                fg_voice(4,2,15,3);
                fg_waitfor(18);
                printf("2048 Hz white noise...\n");
                fg_voice(5,2,15,3);
                fg_waitfor(18);
                printf("500 Hz tone of increasing volume...\n");
                for (volume = 1; volume <= 15; volume++) {
                   fg_voice(1,500,volume,0);
                   fg_waitfor(4);
                   }
                fg_quiet();
             }


    Note how example 15-2 uses a duration of zero (continuous sound) and

fg_waitfor to specify the duration for each volume level the 500 Hertz tone sequence. This causes the transition between changes in volume to blend better with each other. The fg_quiet routine, which stops continuous sound started with fg_sound or fg_voice, ends the sound after the final volume level.

    Both fg_sound and fg_voice produce a single sound. We've seen how to

combine sounds to produce sound effects, but still the individual sounds are defined numerically -- that is, by a certain frequency and duration. It is often easier to create sounds from musical notes, and for this reason Fastgraph includes a routine fg_music that produces such sounds. The fg_music routine uses the programmable timer to produce synchronous sound; it does not support the TI sound chip.

    The fg_music routine has a single argument called the music string,

passed by reference as a byte array or character string. The music string is simply a variable-length sequence of music commands, followed by a dollar-sign ($) terminator. Music commands are summarized in the following table.

command meaning

A thru G Play the specified note in the current octave.

  1. May be appended to a note character (A through G) to make that note
         sharp.

. May be appended to a note character (A through G) or a sharp (#) to

         extend that note by half its normal length. Multiple dots may be
         used, and each will again extend the note by half as much as the
         previous extension.

Ln Set the length of subsequent notes and pauses. The value of n is an

         integer between 1 and 64, where 1 indicates a whole note, 2 a half
         note, 4 a quarter note, and so forth. If no L command is present, L4
         is assumed.

On Set the octave for subsequent notes. The value of n may be an

         integer between 0 and 6 to set a specific octave. It also can be a   �

334 Fastgraph User's Guide


         plus (+) or minus (-) character to increment or decrement the
         current octave number. Octave 4 contains middle C, and if no O
         command is present, O4 is assumed.

P Pause (rest) for the duration specified by the most recent L

         command.

Sn Set the amount of silence between notes. The value of n is an

         integer between 0 and 2. If n is 0, each note plays for the full
         period set by the L command (music legato). If n is 1, each note
         plays for 7/8 the period set by the L command (music normal). If n
         is 2, each note plays for 3/4 the period set by the L command (music
         staccato). If no S command is present, S1 is assumed.

Tn Set the tempo of the music (the number of quarter notes per minute).

         The value of n is an integer between 32 and 255. If no T command is
         present, T120 is assumed.

The fg_music routine ignores any other characters in the music string. It also ignores command values outside the allowable range, such as T20 or O8.

    Example 15-3 illustrates some uses of fg_music. The program plays the

first few bars of "Mary Had a Little Lamb", followed by the musical scale (including sharps) in two octaves, and finally the introduction to Beethoven's Fifth Symphony. There is a pause of one second between each piece of music, and the program displays the titles before playing the music. Blank characters appear in the music strings to help make them more readable.

                                Example 15-3.


   #include <fastgraf.h>
   #include <stdio.h>
   void main(void);
   void main()
   {
   {  fg_initpm();
      printf("Mary Had a Little Lamb...\n");
      fg_music("T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC$");
      fg_waitfor(18);
      printf("up the scale in two octaves...\n");
      fg_music("L16 CC#DD#EFF#GG#AA#B O+ CC#DD#EFF#GG#AA#B$");
      fg_waitfor(18);
      printf("Beethoven's Fifth Symphony...\n");
      fg_music("T180 O2 L2 P L8 P GGG L2 D# L24 P L8 P FFF L2 D$");
   }                                                                          �
                                             Chapter 15:  Sound Effects   335


Asynchronous Sound

    Sounds made concurrently with other activity in a program are said to be

asynchronous. Fastgraph's routines that produce asynchronous sound just start the sound and then immediately return control to the calling program. The sounds will automatically stop when the end of the sequence is reached, and you also can suspend or stop it on demand before that time. None of Fastgraph's asynchronous sound routines have any effect if there is already asynchronous sound in progress. In addition, the asynchronous sound routines temporarily disable the synchronous sound routines (fg_sound, fg_voice, and fg_music) while asynchronous sound is in progress.

    To expand the range of sound effects and to play fast-tempo music,

Fastgraph temporarily quadruples the clock tick interrupt rate from 18.2 to 72.8 ticks per second while producing asynchronous sound. Because many disk controllers rely on the 18.2 tick per second clock rate to synchronize disk accesses, your programs should not perform any disk operations when asynchronous sound is in progress.

    The fg_sounds routine is the asynchronous version of fg_sound. It uses

the programmable timer to play a sequence of tones simultaneous to other operations. This routine expects as its first argument a variable-length integer array, passed by reference, containing pairs of frequency and duration values. As with fg_sound, each frequency is expressed in Hertz and must be between 18 and 32,767. The durations are also measured in clock ticks, but because the interrupt rate is quadrupled, there are 72.8 instead of 18.2 ticks per second.

    The format of the frequency and duration array passed to fg_sounds is

shown here:


                         [0]    frequency of sound 1
                         [1]    duration  of sound 1
                         [2]    frequency of sound 2
                         [3]    duration  of sound 2
                                          .
                                          .
                                          .
                      [2n-2]    frequency of sound n
                      [2n-1]    duration  of sound n
                        [2n]       terminator (0)


Note that a null character (that is, a zero byte) terminates the array. The second argument passed to fg_sounds is an integer value indicating the number of times to cycle through the frequency and duration array. If this value is negative, the sounds will continue until stopped with fg_hush or fg_hushnext. � 336 Fastgraph User's Guide


    Example 15-4 uses fg_sounds to play the 100 to 500 Hertz sliding tone

sequence of example 15-1. To prove the sounds are being made concurrently with other operations, messages are displayed while the sequence is playing. This is controlled by the Fastgraph routine fg_playing, which returns a value of 1 if asynchronous sounds are in progress, and 0 if not. Note how the duration must be specified as 8 clock ticks (instead of 2 as in example 15-1) to compensate for the quadrupled clock tick interrupt rate.

                                Example 15-4.
                #include <fastgraf.h>
                #include <stdio.h>
                void main(void);
                void main()
                {
                   int i;
                   int freq;
                   int sound_array[83];
                   i = 0;
                   for (freq = 100; freq <= 500; freq+=10) {
                      sound_array[i++] = freq;
                      sound_array[i++] = 8;
                      }
                   sound_array[i] = 0;
                   fg_initpm();
                   fg_sounds(sound_array,1);
                   while(fg_playing())
                      printf("Still playing...\n");
                }


    Just as fg_sounds is analogous to fg_sound, there is a Fastgraph routine

fg_voices that is similar to fg_voice. That is, fg_voices uses the TI sound chip to play an asynchronous sequence of tones. Its arguments are the same as those of fg_sounds, but the structure of the sound array is different. Its structure is:


                         [0]    channel # of sound 1
                         [1]    frequency of sound 1
                         [2]    volume    of sound 1
                         [3]    duration  of sound 1
                                          .
                                          .
                                          .
                      [4n-4]    channel # of sound n                          �
                                             Chapter 15:  Sound Effects   337


                      [4n-3]    frequency of sound n
                      [4n-2]    volume    of sound n
                      [4n-1]    duration  of sound n
                        [4n]       terminator (0)


The channel numbers, frequencies, volumes, and durations must be in the same ranges as discussed in the description of fg_voice, except the durations are quadrupled because of the accelerated clock tick interrupt rate. Again, note that a null character (that is, a zero byte) terminates the array.

    Example 15-5 uses fg_voices to play the 500 Hertz tone sequence of

increasing volume introduced in example 15-2. As in example 15-4, the program displays messages while the tone sequence is playing to demonstrate the sounds are being made concurrently with other operations. Note how the duration is now 16 clock ticks (instead of 4 as in example 15-2) because of the quadrupled clock tick interrupt rate.

                                Example 15-5.
           #include <fastgraf.h>
           #include <stdio.h>
           void main(void);
           void main()
           {
              int voice_array[61];
              int i;
              int volume;
              fg_initpm();
              if (fg_testmode(9,0) == 0) {
                 printf("This program requires a PCjr or ");
                 printf("a Tandy 1000 system.\n");
                 exit(1);
                 }
              i = 0;
              for (volume = 1; volume <= 15; volume++) {
                 voice_array[i++] = 1;      /* use channel 1 */
                 voice_array[i++] = 500;    /* 500 Hz frequency */
                 voice_array[i++] = volume; /* variable volume */
                 voice_array[i++] = 16;     /* duration */
                 }
              voice_array[i] = 0;
              fg_voices(voice_array,1);
              while(fg_playing())
                 printf("Still playing...\n");
           }                                                                  �

338 Fastgraph User's Guide


    There is also an asynchronous version of fg_music. It is called

fg_musicb, and it uses the same format music string as fg_music does. However, fg_musicb has a second argument that specifies the number of times to cycle through the music string. If this value is negative, the music will play repetitively until you stop it with fg_hush or fg_hushnext.

    Example 15-6 plays the same three pieces of music as example 15-3, but it

does so concurrently with other operations. As the music plays, the program continuously displays the title of each piece. Note how we can take advantage of the repetition in the music string for the "up the scale" sequence by playing the sequence twice.

                                Example 15-6.
  #include <fastgraf.h>
  #include <stdio.h>
  void main(void);
  void main()
  {
     fg_initpm();
     fg_musicb("T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC$",1);
     while (fg_playing())
        printf("Mary Had a Little Lamb...\n");
     fg_waitfor(18);
     fg_musicb("L16 CC#DD#EFF#GG#AA#B O+$",2);
     while (fg_playing())
        printf("up the scale in two octaves...\n");
     fg_waitfor(18);
     fg_musicb("T180 O2 L2 P L8 P GGG L2 D# L24 P L8 P FFF L2 D$",1);
     while (fg_playing())
        printf("Beethoven's Fifth Symphony...\n");
  }


    The next example demonstrates the effects of the Fastgraph routines

fg_hush and fg_hushnext, which stop sounds started with fg_sounds, fg_voices, or fg_musicb. The fg_hush routine immediately stops asynchronous sound, while fg_hushnext does so when the current cycle finishes. Neither routine has any arguments, and neither routine has any effect if no asynchronous sound is in progress. Furthermore, note that fg_hushnext has no effect unless the asynchronous sound is continuous.

    Example 15-7 runs in any text or graphics video mode. It displays

rectangles in up to 16 colors while playing continuous asynchronous music. The program periodically checks for keystrokes with fg_intkey, and it continues to play the music while there is no keyboard activity. If you press the Escape key, the program uses fg_hush to stop the music immediately; this causes an exit from the while loop. If you press any other key, the program uses fg_hushnext to stop the music as soon as the current repetition finishes. Once it does, the program exits the while loop because fg_playing will return a value of zero. �

                                             Chapter 15:  Sound Effects   339


                                Example 15-7.
     #include <fastgraf.h>
     void main(void);
     #define ESC 27
     void main()
     {
        int color;
        int old_mode;
        unsigned char key, aux;
        fg_initpm();
        old_mode = fg_getmode();
        fg_setmode(fg_automode());
        color = 0;
        fg_musicb("O4 L16 CC#DD#EFF#GG#AA#B O+ CC#DD#EFF#GG#AA#B$",-1);
        while (fg_playing())
        {
           color = (color + 1) & 15;
           fg_setcolor(color);
           fg_rect(0,fg_getmaxx(),0,fg_getmaxy());
           fg_waitfor(4);
           fg_intkey(&key,&aux);
           if (key == ESC)
              fg_hush();
           else if (key+aux != 0)
              fg_hushnext();
        }
        fg_setmode(old_mode);
        fg_reset();
     }


    Example 15-7 also demonstrates an important side-effect of fg_musicb when

playing continuous music. Any length, octave, silence, or tempo values changed within the string are not reset to their original values at the beginning of each repetition. If we did not include the O4 command at the beginning of the string, the later O+ command would cause the music to play in octaves 4 and 5 during the first repetition, 5 and 6 during the second repetition, and octave 6 for all subsequent repetitions (because you cannot increase the octave number above 6).

    The final two routines relating to asynchronous sound are fg_resume and

fg_suspend. The fg_suspend routine suspends music previously started by fg_musicb, while fg_resume restarts the music from the point where it was suspended. Example 15-8 plays the first few bars of "Mary Had a Little Lamb". If you press any key while the song is playing, it stops. Then, after another keystroke, the music resumes and continues until finished. � 340 Fastgraph User's Guide

                                Example 15-8.
  #include <fastgraf.h>
  #include <stdio.h>
  void main(void);
  void main()
  {
     fg_initpm();
     fg_musicb("T150 L8 EDCDEEE P DDD P EGG P EDCDEEE L16 P L8 EDDEDC$",1);
     fg_waitkey();
     fg_suspend();
     printf("Music suspended.  Press any key to resume.\n");
     fg_waitkey();
     fg_resume();
     printf("Music resumed.\n");
     while (fg_playing());
     printf("Music finished.\n");
  }


The fg_suspend routine has no effect if there is no asynchronous music in progress. Similarly, fg_resume has no effect if there is no suspended music. If you call fg_suspend and then need to cancel the music or exit to DOS instead of restarting the music, call fg_hush instead of fg_resume.


Summary of Sound Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_HUSH immediately stops asynchronous sound started with fg_sounds,

fg_voices, or fg_musicb.

    FG_HUSHNEXT is similar to fg_hush, but it does not stop the asynchronous

sound until the current repetition finishes.

    FG_MUSIC uses the programmable timer to play a sequence of musical tones.
    FG_MUSICB is the asynchronous version of fg_music. It uses the

programmable timer to play a sequence of musical tones, concurrent with other activity.

    FG_PLAYING determines whether or not there is any asynchronous sound in

progress.

    FG_QUIET stops continuous synchronous sound started with fg_sound or

fg_voice.

    FG_RESUME restarts asynchronous music previously suspended by fg_suspend. �
                                             Chapter 15:  Sound Effects   341


    FG_SOUND produces a tone of a specified frequency and duration using the

programmable timer.

    FG_SOUNDS is the asynchronous version of fg_sound. It can play a series

of tones of specified frequencies and durations, concurrent with other activity.

    FG_SUSPEND suspends asynchronous music previously started by fg_musicb.
    FG_VOICE produces a tone of a specified frequency, duration, and volume

using one of the TI sound chip's four voice channels.

    FG_VOICES is the asynchronous version of fg_voice. It can play a series

of tones of specified frequencies, durations, and volumes, concurrent with other activity. � 342 Fastgraph User's Guide




Chapter 16



Program Timing � 344 Fastgraph User's Guide


Overview

    It is occasionally necessary to delay a program's execution for a brief

period, or to determine how long it takes to execute specific sections of a program. Fastgraph includes routines to accomplish these tasks. Some of these routines are said to be real-time, which means they are independent of a system's processor speed, while the speed of others is processor-specific. This chapter describes both classes of timing routines, all of which are independent of the other parts of Fastgraph.


Real-Time Routines

    Real-time operations center around the BIOS time-of-day clock, which is

nothing more than a counter that the system automatically increments 18.2 times per second. This number is often called the clock tick interrupt rate because an interrupt routine performs the incrementing. In addition, each increment is usually called a clock tick.

    The Fastgraph routine fg_waitfor delays a program's execution by the

number of clock ticks specified as its argument. Because fg_waitfor uses clock ticks, the actual length of the delay is the same, regardless of the system's processor speed. Even when Fastgraph's asynchronous sound routines quadruple the clock tick interrupt rate, Fastgraph compensates for this internally so fg_waitfor always works as though the actual rate were still 18.2 times per second.

    Example 16-1 displays a message every five seconds that states how long

the program has been running. The fg_waitfor routine produces the five-second delay by pausing 91 (18.2 times 5) clock ticks before the program displays each message. The program returns to DOS when you press any key.

                                Example 16-1.
             #include <fastgraf.h>
             #include <stdio.h>
             void main(void);
             void main()
             {
                unsigned int seconds;
                unsigned char key, aux;
                fg_initpm();
                seconds = 0;
                do {
                   fg_waitfor(91);
                   seconds += 5;
                   printf("%u seconds have elapsed.\n",seconds);
                   fg_intkey(&key,&aux);
                }
                while (key+aux == 0);
             }                                                                �
                                            Chapter 16:  Program Timing   345


    Another common application of fg_waitfor is to slow down a loop that uses

fg_intkey to check for keystrokes. In loops that do little else, we may call fg_intkey too rapidly without this delay, and it is then possible that the BIOS may not be able to store characters in its keyboard buffer fast enough. A small delay, even one clock tick, often helps such "tight" loops.

    The fg_getclock routine provides an efficient way to measure time,

especially differences in time. This routine has no arguments and returns a 32-bit unsigned integer (as its function value) representing the number of clock ticks since midnight. Example 16-2 demonstrates fg_getclock. In response to any keystroke (except Escape, which returns control to DOS), the program displays the number of clock ticks since midnight, and the number of ticks since the program started.

                                Example 16-2.
     #include <fastgraf.h>
     #include <stdio.h>
     void main(void);
     #define ESC 27
     void main()
     {
        unsigned long start, ticks;
        unsigned char key, aux;
        fg_initpm();
        start = fg_getclock();
        do {
           ticks = fg_getclock();
           printf("%lu ticks since midnight.\n",ticks);
           printf("%lu ticks since start of program.\n\n",ticks-start);
           fg_getkey(&key,&aux);
        }
        while (key != ESC);
     }


Routines Dependent on the System Speed

    The fg_waitfor routine described in the previous section is independent

of the system's processor speed. This means the actual length of its delay is the same on any system. Another routine, fg_stall, is similar to fg_waitfor, but its delay is proportional to the processor speed. Like fg_waitfor, fg_stall has a single integer argument that specifies the length of the delay. However, instead of being expressed in clock ticks, fg_stall measures the delay in delay units. The fg_stall routine treats the length as an unsigned quantity, so in 16-bit modes the maximum number of delay units we can specify is 65,535. The following table lists the approximate number of delay units per clock tick on three typical systems. � 346 Fastgraph User's Guide


                     system       delay units
                      type      per clock tick
                  Tandy 1000 HX       280
                  25 MHz 80386       3,400
                  40 MHz 80386       7,100
    Fastgraph includes a routine that determines the number of delay units

per clock tick for the processor being used. This is the fg_measure routine, which has no arguments and returns the number of delay units per clock tick as its function value. Once we determine this value, we can use fg_stall to delay a program's execution in real time. This provides a much more refined delay than the clock tick unit used by fg_waitfor.

    Example 16-3 is functionally identical to example 16-1, but it uses

fg_stall instead of fg_waitfor to delay the program execution. The program first calls fg_measure to determine number of delay units equivalent to one clock tick. It then passes this value to fg_stall, called 91 times inside the for loop to create the five-second delay (because 91 clock ticks equals five seconds). The program returns to DOS when you press any key.

                                Example 16-3.
             #include <fastgraf.h>
             #include <stdio.h>
             void main(void);
             void main()
             {
                int i;
                int units_per_tick;
                unsigned int seconds;
                unsigned char key, aux;
                fg_initpm();
                seconds = 0;
                printf("Benchmarking system speed...\n");
                units_per_tick = fg_measure();
                printf("Benchmark completed.\n\n");
                do {
                   for (i = 0; i < 91; i++)
                      fg_stall(units_per_tick);
                   seconds += 5;
                   printf("%u seconds have elapsed.\n",seconds);
                   fg_intkey(&key,&aux);
                }
                while (key+aux == 0);
             }


    One final point: fg_measure takes a few seconds to benchmark the system

speed accurately. For this reason, you should only call fg_measure once (typically at the beginning of the program) and use its return value instead of calling fg_measure throughout the program. �

                                            Chapter 16:  Program Timing   347


Summary of Timing Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_GETCLOCK returns the number of clock ticks since midnight as its

function value. This quantity is a 32-bit unsigned integer.

    FG_MEASURE returns the approximate number of delay units per clock tick

as its function value. This quantity is proportional to the system's processor speed.

    FG_STALL delays a program's execution for a given number of processor-

specific delay units.

    FG_WAITFOR delays a program's execution for a given number of clock

ticks. There are 18.2 clock ticks per second, regardless of the system's processor speed. � 348 Fastgraph User's Guide




Chapter 17



Miscellaneous Routines � 350 Fastgraph User's Guide


Overview

    There are a few remaining Fastgraph routines that really don't fit into

any of the categories discussed so far. For this reason, we'll describe them separately in this chapter.


Determining Available Memory

    The fg_memavail routine returns the amount of free conventional memory

(in bytes) available to DOS. It returns the amount of memory as its function value, which is a 32-bit unsigned integer, and it has no arguments.

    Example 17-1 uses fg_memavail to show the effects of creating and

releasing virtual pages. When run in a video mode in which video pages 1 and 2 are physical pages, the amount of free memory remains the same because these pages use memory that is resident on the video adapter. However, in modes where pages 1 and 2 are virtual pages, the amount of free memory decreases after each call to fg_allocate and returns to its original value after the calls to fg_freepage. Note how the program requests and validates the video mode.

                                Example 17-1.
      #include <fastgraf.h>
      #include <stdio.h>
      #include <stdlib.h>
      void main(void);
      void main()
      {
         long original, mem0, mem1, mem2;
         int  mode, old_mode;
         printf("Which video mode? ");
         scanf("%d",&mode);
         fg_initpm();
         if (fg_testmode(mode,0) == 0) {
            printf("Your system does not support that video mode.\n");
            exit(1);
            }
         if (fg_testmode(mode,3) == 0) {
            printf("Your system does not have enough memory.\n");
            exit(1);
            }
         original = fg_memavail();
         old_mode = fg_getmode();
         fg_setmode(mode);
         mem0 = fg_memavail();
         fg_allocate(1);
         mem1 = fg_memavail();
         fg_allocate(2);
         mem2 = fg_memavail();                                                �
                                    Chapter 17:  Miscellaneous Routines   351


         fg_freepage(1);
         fg_freepage(2);
         fg_setmode(old_mode);
         fg_reset();
         printf("originally     = %ld\n",original);
         printf("after setmode  = %ld\n",mem0);
         printf("after 1st page = %ld\n",mem1);
         printf("after 2nd page = %ld\n",mem2);
         printf("at end         = %ld\n",memavail());
      }


Choosing the Video Memory Update Function

    In Chapter 12, we saw how to use the fg_setfunc routine to perform XOR

animation in native EGA and VGA graphics modes (modes 13 to 18). In these video modes, fg_setfunc controls the logical operation applied when the contents of video memory change. The specific operation is defined by its argument, as shown here:

                                value of  logical
                                argument operation
                                   0    replacement
                                   1        and
                                   2         or
                                   3    exclusive or

If a program does not call fg_setfunc, replacement mode is always used. That is, information written to video memory replaces whatever was there before. The fg_setfunc routine applies only to video memory, even if a virtual buffer is active, and is meaningful only in 16-color EGA, VGA, and SVGA graphics modes.

    Example 17-2 demonstrates the fg_setfunc routine. The program is similar

to example 6-11, which displays 200 random rectangles on the screen. However, example 17-2 displays the rectangles in XOR mode, which makes the rectangle intersections appear in different colors.

                                Example 17-2.
            #include <fastgraf.h>
            #include <stdio.h>
            #include <stdlib.h>
            void main(void);
            #define RECTANGLES 200
            #define SWAP(a,b,temp) { temp = a; a = b; b = temp; }
            void main()
            {
               int i;
               int minx, maxx, miny, maxy;                                    �

352 Fastgraph User's Guide


               int old_mode;
               int temp;
               int xres, yres;
               fg_initpm();
               if (fg_egacheck() == 0) {
                  printf("This program requires EGA or VGA.\n");
                  exit(1);
                  }
               old_mode = fg_getmode();
               fg_setmode(fg_automode());
               fg_setfunc(3);
               xres = fg_getmaxx() + 1;
               yres = fg_getmaxy() + 1;
               for (i = 0; i < RECTANGLES; i++) {
                  minx = rand() % xres;
                  maxx = rand() % xres;
                  miny = rand() % yres;
                  maxy = rand() % yres;
                  if (minx > maxx)
                     SWAP(minx,maxx,temp);
                  if (miny > maxy)
                     SWAP(miny,maxy,temp);
                  fg_setcolor(rand()%16);
                  fg_rect(minx,maxx,miny,maxy);
                  }
               fg_setmode(old_mode);
               fg_reset();
            }


Controlling Vertical Retrace Synchronization

    The vertical retrace is the brief period when the monitor's electron beam

travels from the bottom of the screen back to the upper left corner to begin a new display refresh cycle. Depending on the monitor, the vertical retrace typically occurs between 50 and 60 times per second.

    Certain graphics operations must be performed during a vertical retrace

interval to avoid potential screen flickering or snow. These include page flipping, panning, and reading or writing a block of video DAC registers or palettes. By default, Fastgraph's routines that perform these operations automatically provide the necessary vertical retrace synchronization. In most applications, these vertical retrace controls are completely sufficient. There are times, however, when you may wish to disable Fastgraph's vertical retrace checking and perform the vertical retrace synchronization at the application level.

    This is the purpose of Fastgraph's fg_waitvr routine. To disable all

internal vertical retrace synchronization within Fastgraph, call fg_waitvr with a zero argument. If you want to re-enable it, pass a non-zero value to �

                                    Chapter 17:  Miscellaneous Routines   353


fg_waitvr (note that this is the default state). The Fastgraph routines relevant to the vertical retrace are fg_getdacs, fg_palettes, fg_pan, fg_setdacs, and fg_setvpage; and in 256-color modes, fg_getrgb, fg_palette, and fg_setrgb. The vertical retrace is also applicable to Fastgraph's routines for displaying or creating PCX, GIF, or flic files in 16-color and 256-color graphics modes when the palette or DAC values are manipulated.

    As an example of why you might want to do disable Fastgraph's vertical

retrace controls, consider page flipping. After fg_setvpage defines the display start address for the new visual page, it waits for a vertical retrace interval so the new starting address can take effect. If fg_setvpage didn't do this, graphics displayed before the next vertical retrace would sometimes appear on the screen before the old visual page is completely removed. Suppose, though, that immediately after the page flip you did some calculations or other work that didn't affect the video display. If you disable Fastgraph's vertical retrace synchronization, you might achieve a faster frame rate because you can perform the post-page-flip calculations while the system is normally waiting for the vertical retrace. Depending on the extent of these calculations, you may find that it's not even necessary to wait for the vertical retrace following a page flip.


External SVGA Bank Switching

    One of the most important features that occurs during Fastgraph's SVGA

kernel initialization is the setup of chipset-specific bank switching functions. When a bank switch is needed, the current Fastgraph routine performs the bank switch through pre-defined entry points in the SVGA kernel. This removes the low-level details of knowing when and how to bank switch from an application's high-level code.

    If you have an application that performs some or all of its SVGA graphics

outside of Fastgraph, you can still use Fastgraph's extensive SVGA chipset autodetection and bank switching functions. After successfully initializing the SVGA kernel with fg_svgainit and establishing an SVGA graphics video mode, the read and write bank numbers will be set to zero. When you need to change SVGA banks, call the fg_setbanks routine; its two arguments specify the new read and write bank numbers. Note that fg_setbanks doesn't tell you when to perform a bank switch, it merely handles the details of how to do it. A complementary routine, fg_getbanks, returns the SVGA kernel's current read and write bank numbers.


Saving and Restoring the Video State

    If you call Fastgraph routines from an interrupt service routine (ISR) in

a VGA, XVGA, or SVGA graphics mode, the ISR is responsible for saving and restoring the VGA state. This is required because an interrupt might occur while performing other graphics operations, and the Fastgraph routines called from the ISR will almost certainly change the VGA state. When control returns to the point of interruption, the VGA will likely be in a different state than expected.

    The fg_vgastate routine saves and restores the VGA registers that

Fastgraph expects to be in specific states. These registers are: � 354 Fastgraph User's Guide


    * Graphics Controller index
    * Graphics Controller registers 0-8
    * Sequence Controller index
    * Sequence Controller register 2

To save the state of these registers, call fg_vgastate(0). To restore them to their previously saved values, call fg_vgastate(1). If you request a fg_vgastate save operation before performing a restore operation, nothing happens. The fg_vgastate routine is meaningful only in video modes numbered 13 and above when running on a VGA or SVGA system.

    If you need to save and restore the VGA state in an SVGA graphics mode,

you should use fg_vgastate to preserve the VGA registers plus fg_getbanks and fg_setbanks (described in the previous section) to preserve the SVGA bank numbers.


Summary of Miscellaneous Routines

    This section summarizes the functional descriptions of the Fastgraph

routines presented in this chapter. More detailed information about these routines, including their arguments and return values, may be found in the Fastgraph Reference Manual.

    FG_GETBANKS returns the current SVGA read and write bank numbers. These

values will be correct only if set through the SVGA kernel, or with fg_setbanks.

    FG_MEMAVAIL returns the amount of memory available to DOS.
    FG_SETBANKS defines the SVGA read and write bank numbers. This routine is

not usually called in an application but is provided as a high-level interface to Fastgraph's SVGA kernel.

    FG_SETFUNC specifies the logical operation (replacement, or, and,

exclusive or) applied when video memory changes in the 16-color EGA, VGA, and SVGA graphics modes. This routine has no effect in other video modes and does not apply to information written to virtual buffers.

    FG_VGASTATE saves or restores the state of the VGA Graphics Controller

and Sequence Controller registers used by Fastgraph.

    FG_WAITVR disables or enables vertical retrace synchronization within

Fastgraph.




Appendix A



Fastgraph Utilities � 356 Fastgraph User's Guide


Overview

    This appendix describes the utility programs supplied with Fastgraph. By

default, the Fastgraph installation procedure places these utilities in the \FG directory. To use these utilities, you must either (1) copy the EXE file from \FG to your current directory, (2) make \FG your current directory, or (3) include the \FG directory in your DOS path specification.


SNAPSHOT Utility

    The SNAPSHOT utility is a terminate and stay resident program (TSR) to

capture graphic images. It stores the image in Fastgraph's standard pixel run (SPR) format. To load SNAPSHOT, just enter the command SNAPSHOT at the DOS prompt, and you'll see messages similar to the following if SNAPSHOT loads successfully.


        C> SNAPSHOT
        SNAPSHOT  Version 1.04
        Copyright (c) 1993 Ted Gruber Software.  All Rights Reserved.
        Press <alt>-<left shift> to activate.


    After SNAPSHOT loads, control returns to the DOS prompt. At this point,

you can use any method whatsoever to display a graphic image and then press the Alt and left shift keys at the same time to capture the image. You don't need to load SNAPSHOT for each image capture, just once per system boot. SNAPSHOT uses about 24,000 bytes of conventional memory once loaded.

    To illustrate the use of SNAPSHOT, suppose you have drawn and saved an

image with a commercial paint program, and you want to incorporate this image into a Fastgraph application. Once you load SNAPSHOT, start the paint program and retrieve your image. Then press the Alt and left shift keys simultaneously and wait for the success tone (three quick medium-pitched sounds). Finally, exit the paint program to return to the DOS prompt.

    The sequence described in the preceding paragraph will store the captured

image in Fastgraph's standard pixel run format, in a file named SNAPSHOT.nnn in the current directory. The file type nnn will be the first sequence of digits that does not result in a duplicate file name. That is, if there are no captured image files in the current directory, SNAPSHOT will use the file name SNAPSHOT.000. The next time you capture an image, SNAPSHOT will store it in SNAPSHOT.001, then SNAPSHOT.002, and so forth. If you rename or delete one of these files, SNAPSHOT will again use that file name. For example, if you delete SNAPSHOT.000 but keep SNAPSHOT.001, SNAPSHOT will store the next image it captures in SNAPSHOT.000.

    If SNAPSHOT is unable to capture the image, it will produce its error

tone (a single low-pitched sound). The most common cause of this is trying to capture an image from a text video mode, but it also will occur if there is not enough disk space or if all 1,000 image file names are already being used. �

                                       Appendix A:  Fastgraph Utilities   357


CLIP Utility

    The SNAPSHOT utility described in the previous section captures the

entire screen. While this might be desirable in some cases, other times you'll just need a portion of the screen. CLIP is an interactive utility that you can use to reduce the size of any image stored in Fastgraph's standard or packed pixel run format. The syntax of the command for invoking the CLIP utility from the DOS prompt is

                     CLIP input_file output_file options

where input_file is the name of the original image file, and output_file is the name of the new image file. CLIP does not modify the input_file in any way, but it will overwrite the output_file if an identically named file exists in the current directory. The options list specifies one or more optional switches as shown here:

option meaning

/M:mode Specifies the video mode number in which to display the image. The

         mode value must be an integer between 0 and 29. If that video mode
         is a text mode, an unsupported graphics mode, or an unavailable
         graphics mode, CLIP displays an error message stating this. If the
         /M switch is not present, CLIP uses the first available video mode
         from the list 18, 16, 15, 19, 13, 9, 4, 12.

/P Indicates the input_file is in Fastgraph's packed pixel run format.

         If the /P switch is not present, CLIP assumes it is in standard
         pixel run format. The output_file will be in the same format as the
         input_file.

/W:width Specifies the image width in pixels. The width value must be an

         integer between 1 and the horizontal resolution of the selected
         video mode. If the /W switch is not present, CLIP uses the
         horizontal resolution of the selected video mode.

For example, if you wanted to create the image file PARTIAL.PPR from the packed pixel run file SCREEN.PPR, and use the native 320x200 EGA graphics video mode (mode 13), you would start CLIP with the following command.

                    CLIP PARTIAL.PPR SCREEN.PPR /P /M:13

Because no /W switch appears in the above command and the horizontal resolution of mode 13 is 320 pixels, CLIP assumes the image width is 320 pixels.

    When CLIP displays the image and the plus-shaped cursor, you are ready to

define one corner of the clipping region (that part of the image used to create the output_file). To do this, use the directional keys on the numeric keypad to move the cursor to the desired position, then press the Enter key. You are then ready to define the clipping region's opposite corner. Again, use the directional keys to move the cursor to the desired position. When defining the second corner, however, CLIP uses a rectangular box instead of the plus- shaped cursor to simplify marking the clipping region's boundaries. After you press Enter to define the second corner, CLIP creates the output_file and � 358 Fastgraph User's Guide


displays the resulting image width and the number of pixel runs the image contains.

    CLIP includes other features to help define the clipping region. You can

change the distance the cursor moves in response to the directional keys, display the current (x,y) pixel coordinates of the cursor, and change the cursor color. The following table explains the keystrokes that CLIP recognizes when you are defining the clipping region.

key meaning

F1 Displays the (x,y) coordinate bar at the top of the screen. If the

         coordinate bar is already on, F1 removes it.

F2 Displays the (x,y) coordinate bar at the bottom of the screen. If

         the coordinate bar is already on, F2 removes it.

F3 Changes the cursor or box color from white to black, or from black

         to white.

F4 Displays a summary of the keys CLIP recognizes when defining the

         clipping region.

KP1 Moves the cursor one unit down and to the left. KP2 Moves the cursor one unit down. KP3 Moves the cursor one unit down and to the right. KP4 Moves the cursor one unit to the left. KP6 Moves the cursor one unit to the right. KP7 Moves the cursor one unit up and to the left. KP8 Moves the cursor one unit up. KP9 Moves the cursor one unit up and to the right. + Increases the unit of cursor movement by one pixel. The default

         cursor movement is one pixel.

- Decreases the unit of cursor movement by one pixel. Enter Defines a corner of the clipping region at the cursor position. Esc Exits to DOS without creating the output_file. CLIP will first issue

         an "Exit to DOS?" prompt in case you pressed the Esc key
         accidentally.


CONVERT Utility

    The CONVERT utility lets you translate files between Fastgraph's SPR and

PPR image file formats. The syntax of the command for invoking CONVERT from the DOS prompt is

                       CONVERT input_file output_file

where input_file is the name of the original image file, and output_file is the name of the new translated image file. CONVERT does not modify the input_file in any way, but it will overwrite the output_file if an identically named file exists in the current directory.

    By default, the file type of the input_file and output_file determine the

image format of that file. If the file type is PPR, CONVERT assumes the image is in Fastgraph's packed pixel run format. If the file type is SPR, CONVERT assumes it is in the Fastgraph's standard pixel run format. If your image files use other file types, you can explicitly specify the file's image format by appending one of the switches /PPR or /SPR to the file name. The input_file �

                                       Appendix A:  Fastgraph Utilities   359


and output_file must not both specify the same image format (CONVERT will display an error message if this is so).

    The following command will translate the standard pixel run file

PICTURE.SPR to packed format. The packed image will be stored in the file PICTURE.IMG, so we must append the switch /PPR to tell CONVERT that it will be a packed file.

                     CONVERT PICTURE.SPR PICTURE.IMG/PPR


EDITSPR Utility

    The EDITSPR utility changes all pixel runs of one color to another color

in an image file stored in Fastgraph's standard pixel run (SPR) format. The syntax of the command for invoking the EDITSPR utility from the DOS command prompt is

                       EDITSPR input_file output_file

where input_file is the name of the original image file, and output_file is the name of the new image file. EDITSPR does not modify the input_file in any way, but it will overwrite the output_file if an identically named file exists in the current directory.

    After it reads the pixel runs from the input_file, EDITSPR will perform

the requested color changes. It does this iteratively by asking for an old color value followed by a new color value (each value must be between 0 and 255). EDITSPR then finds the pixel runs of the old color value and changes them to the new color value. Following this, EDITSPR displays a message stating how many pixel runs it changed. This process repeats until you enter a negative number for either color value.

    EDITSPR will next combine adjacent pixel runs of like colors. For

example, suppose the original image file contained a color 1 pixel run of length 50, followed by a color 2 pixel run of length 20, followed by another color 1 pixel run of length 10. If you changed all color 2 pixel runs to color 1, EDITSPR will combine these three pixel runs into a single run of length 80.


GrabRGB Utility

    The GrabRGB utility is a terminate and stay resident program (TSR) to

capture the current red, green, and blue color components of video DAC registers in 256-color graphics modes. You can use GrabRGB together with Fastgraph's SNAPSHOT utility to preserve the original colors of a captured image.

    To load GrabRGB, just enter the command GRABRGB at the DOS prompt. After

GrabRGB loads, control returns to the DOS prompt. At this point, you can use any method whatsoever to display a 256-color graphic image and then press the Alt and right shift keys at the same time to capture the current DAC values. You don't need to load GrabRGB for each image, just once per system boot. GrabRGB uses about 28,000 bytes of conventional memory once loaded. � 360 Fastgraph User's Guide


    To illustrate the use of GrabRGB, suppose you have drawn and saved a 256-

color image with a commercial paint program, and you want to incorporate this image into a Fastgraph application. Once you load SNAPSHOT and GrabRGB, start the paint program and retrieve your image. Then press the Alt and left shift keys to capture the image with SNAPSHOT. After SNAPSHOT's success tone (three quick medium-pitched sounds), press Alt and right shift to capture the RGB components of each DAC register with GrabRGB, and wait for GrabRGB's success tone. Finally, exit the paint program and return to the DOS prompt.

    The sequence described in the preceding paragraph will write the RGB

color components for each DAC register to a file named GRABRGB.nnn in the current directory. The file type nnn will be the first sequence of digits that does not result in a duplicate file name. That is, if there are no GrabRGB output files in the current directory, GrabRGB will use the file name GRABRGB.000. The next time you use GrabRGB, it will store the RGB information in GRABRGB.001, then GRABRGB.002, and so forth. If you rename or delete one of these files, GrabRGB will again use that file name. For example, if you delete GRABRGB.000 but keep GRABRGB.001, GrabRGB will next use the file name GRABRGB.000.

    If GrabRGB is unable to obtain the RGB components of each DAC register,

it will produce its error tone (a single low-pitched sound). The most common cause of this is trying to capture an image from a text video mode, or from a graphics video mode with fewer than 256 colors. It also will occur if there is not enough disk space or if all 1,000 output file names are already being used.

    Each line in the output file created by GrabRGB is of the form
                                nnn,rr,gg,bb,

where nnn is a DAC register index (between 0 and 255), rr is the red component of that DAC register, gg is the green component, and bb is the blue component. Each color component is between 0 and 63. You can edit and reformat these lines as necessary for inclusion in a C or C++ initializer list, a BASIC or FORTRAN data statement, or a Pascal array-type constant list. Such an array of RGB components, but without the nnn indices, is in the format expected by fg_setdacs.

    By default, GrabRGB captures information for all 256 DAC registers. If

you want to consider only the DAC registers with color components different from their default values, just include the /D option when you load GrabRGB (that is, use the command GRABRGB /D). If you specify the /D option and all 256 DACs use their default values, the output file will contain a message stating this.


HERCFIX Utility

    The HERCFIX utility allows you to use SNAPSHOT (and possibly other TSRs)

with programs that do not update the BIOS data area when establishing the 720x348 Hercules graphics mode. If you use SNAPSHOT with such a program, it will think the monochrome text mode (video mode 7) is active and will produce its low-pitched error tone when activated. �

                                       Appendix A:  Fastgraph Utilities   361


    If this occurs, use HERCFIX to load the application from which you are

trying to capture the image. To do this, enter

                               HERCFIX command

at the DOS prompt, where command is the command that starts the application. For example, suppose you use the command PAINTER /H to run a commercial paint program in Hercules graphics mode. To load the paint program with HERCFIX, you would enter the command HERCFIX PAINTER /H.


PCXHEAD Utility

    The PCXHEAD utility displays the most important information from the

header of a PCX file. This consists of the PCX version number, the number of bits per pixel, the number of bit planes, the scan line width, and the image dimensions and screen position. It also proposes the optimal video mode for displaying the PCX file. By optimal, we mean the compatible video mode having the lowest resolution larger than or equal to the image dimensions. For 256- color PCX images, PCXHEAD displays the extended color palette if one is present.

    The syntax of the command for invoking the PCXHEAD utility from the DOS

command prompt is

                              PCXHEAD pcx_file

where pcx_file is the name of the PCX file to examine. PCXHEAD does not modify the pcx_file in any way. If the PCX file includes an extended color palette, you may prefer to direct the PCXHEAD output to a file using the DOS redirection operator (>). � 362 Fastgraph User's Guide �




Appendix B



Using Fastgraph from Assembly Language � 364 Fastgraph User's Guide


    The information in this appendix provides information about calling

Fastgraph routines from assembly language programs. It is not intended to be a complete tutorial on the subject, but it should provide experienced assembly language programmers with enough details to call Fastgraph routines in their applications.

    Fastgraph uses the same naming and stack-based calling conventions used

by Borland, Microsoft, and other companies in their C and C++ compilers. The details of these conventions important to assembly language programming are summarized below. If you're calling Fastgraph routines from an assembly language program, the program must follow these conventions.

          *   All arrays and pointers are passed by reference.
          *   All other items are passed by value.
          *   Arguments are pushed onto the stack in reverse
              order.
          *   The calling program is responsible for removing
              the arguments from the stack.
          *   16-bit function values are returned in the AX
              register.
          *   32-bit function values are returned in the DX:AX
              register pair in 16-bit environments, or the EAX
              register in 32-bit environments.
          *   Fastgraph routine names are prefixed with an
              underscore.

The small and medium model real mode Fastgraph libraries pass arrays and pointers by near reference (an offset into DGROUP), while the large model and 16-bit protected mode libraries do so by far reference (a segment:offset or selector:offset pair). The 32-bit protected mode libraries use a flat model architecture, meaning arrays and pointers are passed as 32-bit offsets into DGROUP. This is consistent with the conventions and run-time libraries for the supported compilers.

    All Fastgraph routines preserve the (E)BP, (E)DI, (E)SI, and DS

registers. In the 32-bit protected mode libraries, the EBX and ES registers are also preserved. The contents of any other registers are unknown upon return from a Fastgraph routine (except for the (E)AX register, which will either contain zero or the routine's return value).

    Example B-1 calls fg_getmode, fg_setmode, fg_reset, and fg_version from

an assembly language program. The fg_getmode routine returns its function value in the (E)AX register. The fg_setmode routine has a single argument, while fg_reset has no arguments. The fg_version routine has two arguments, both passed by reference. Notice how they are pushed on the stack in reverse order. This example is written for the medium memory model. To make it work with the large model libraries, add 8 instead of 4 to the (E)SP register following the call to fg_version (because large model items passed by reference are 32-bit segmented values). To make it work with the small model library, change the word "far" to "near" in the EXTRN declarations, and change the name of the code segment from "main_TEXT" to "_TEXT".

    This example is in the file BB-01.ASM in the \FG\EXAMPLES directory. The

following commands show how to use MASM or TASM to assemble this program and link it with the medium model real mode Fastgraph library. �

                    Appendix B:  Using Fastgraph from Assembly Language   365


    Microsoft Macro Assembler (MASM) version 5:
         MASM BB-01.ASM;
         LINK /CP:4096 BB-01,,NUL,FGM;
    Microsoft Macro Assembler (MASM) version 6:
         ML /c /Cx /Zm BB-01.ASM
         LINK /CP:4096 BB-01,,NUL,FGM;
    Turbo Assembler (TASM):
         TASM BB-01.ASM
         TLINK BB-01.OBJ FGM.LIB
                                Example B-1.
               EXTRN   _fg_getmode:far  ; Fastgraph's GETMODE routine
               EXTRN   _fg_reset:far    ; Fastgraph's RESET routine
               EXTRN   _fg_setmode:far  ; Fastgraph's SETMODE routine
               EXTRN   _fg_version:far  ; Fastgraph's VERSION routine
     stackseg  SEGMENT stack
               db      1024 dup (?)  ; use a 1K stack
     stackseg  ENDS
     _DATA     SEGMENT word public 'DATA'
     major     dw      ?             ; major version number
     minor     dw      ?             ; minor version number
     old_mode  dw      ?             ; original video mode
     _DATA     ENDS
     dgroup    GROUP   _DATA
               ASSUME  cs:main_TEXT,ds:dgroup
     main_TEXT SEGMENT byte public 'CODE'
     start:    mov     ax,_DATA      ; load segment location
               mov     ds,ax         ; into DS register
               call    _fg_getmode   ; AX = current video mode
               mov     old_mode,ax   ; save it
               mov     ax,4          ; use video mode 4
               push    ax            ; pass argument fg_setmode
               call    _fg_setmode   ; establish CGA four-color mode
               add     sp,2          ; remove fg_setmode argument
               push    old_mode      ; pass argument to fg_setmode
               call    _fg_setmode   ; restore original video mode
               add     sp,2          ; remove fg_setmode argument
               call    _fg_reset     ; restore screen attributes
               lea     ax,minor      ; get address of minor variable
               push    ax            ; pass argument #2 to fg_version
               lea     ax,major      ; get address of major variable
               push    ax            ; pass argument #1 to fg_version         �

366 Fastgraph User's Guide


               call    _fg_version   ; get the Fastgraph version number
               add     sp,4          ; remove fg_version arguments
               mov     ah,76         ; function 76: terminate process
               xor     al,al         ; errorlevel 0
               int     21h           ; exit to DOS
     main_TEXT ENDS
               END     start                                                  �




Appendix C



Interrupts and Fastgraph � 368 Fastgraph User's Guide


Interrupts Used by Fastgraph

    DOS maintains an interrupt vector table where it stores the addresses of

256 interrupt handlers, or routines, that perform various functions. The handlers are usually referenced by their hexadecimal interrupt number, between 00 and FF. Of these, only interrupts 60 through 66 and F1 through FF are not used by DOS, the ROM BIOS, or other software and are thus available for user applications.

    Certain Fastgraph routines use some of the available interrupts. All

Fastgraph/Light routines use interrupt 62. In addition, Fastgraph's low-level keyboard handler replaces interrupt 09. If your program defines its own interrupt handlers, it must not use any interrupts reserved for Fastgraph (unless, of course, it doesn't use any Fastgraph routines that would create a conflict).


Extending the Time-of-Day Interrupt

    As mentioned in Chapter 16, the BIOS time-of-day clock is incremented by

an interrupt handler. The routine that does this is interrupt 08, a hardware interrupt automatically activated 18.2 times per second. After incrementing the clock, interrupt 08 invokes interrupt 1C, which by default references a "do-nothing" interrupt handler. While changing interrupt 08 can be tricky, it is fairly straightforward to define our own handler for interrupt 1C. This handler also will be executed automatically 18.2 times per second. Example C-1 illustrates how to do this.

    When we discussed joysticks in Chapter 14, we said there were two ways to

monitor joystick button status. One is to intersperse calls to fg_button at strategic places in your program and then take necessary action depending on the button status. However, the problem with this scheme is the chance of missing a button press -- if you press the joystick button and then release it between calls to fg_button, the program will not detect the joystick activity. A preferable method is to call fg_button from a handler for interrupt 1C, which essentially provides continuous monitoring of the joystick buttons. When we need the button status within our program, all we need to do is examine a global variable.

    Example C-1 consists of a main program (written in C) and an assembly

language subroutine named int1C (suitable for the real mode medium memory model). The main program calls int1C to define a handler for interrupt 1C. In response to any keystroke (except Escape), the program displays the button press information for each joystick since the previous keystroke (refer to the discussion of fg_button for the meanings of the status values). When you press the Escape key, the program exits to DOS, but not before calling int1C to restore the original interrupt 1C handler.

                         Example C-1 (main program).
              #include <fastgraf.h>
              #include <stdio.h>
              void main(void);
              #define ESC 27                                                  �
                                  Appendix C:  Interrupts and Fastgraph   369


              int status1, status2;
              void main()
              {
                 unsigned char key, aux;
                 int1C(1);
                 status1 = 0;
                 status2 = 0;
                 do {
                    printf("\n");
                    printf("Joystick 1 status: %d\n",status1);
                    printf("Joystick 2 status: %d\n",status2);
                    status1 = 0;
                    status2 = 0;
                    fg_getkey(&key,&aux);
                    }
                 while (key != ESC);
                 int1C(0);
              }


    We'll now examine the int1C assembly language subroutine. It actually

consists of three parts: a portion to enable our interrupt handler, our handler itself, and a portion to disable the handler. When we call int1C with a nonzero argument, it saves the original data segment (so we can access the global variables within the handler), saves the original handler's address (called the vector) for interrupt 1C, and then enables our handler, which takes the form of a far procedure.

    The handler routine then begins to be activated 18.2 times per second.

After saving all the important registers, the handler calls the Fastgraph routine fg_button twice, once for each joystick. The return values are logically ORed with the status1 and status2 C global variables to update the button status information. Finally, the handler restores the original registers and returns control to the point of the interrupt.

    Before the main program exits, it calls int1C with a zero argument to

restore the original handler for interrupt 1C. No provision is made in the program to check if we had previously defined our own handler (and hence saved the original interrupt 1C vector), but this could be added with little difficulty.

                 Example C-1 (assembly language subroutine).
          EXTRN   _status1:word ; C global variable for button 1 status
          EXTRN   _status2:word ; C global variable for button 2 status
          EXTRN   _fg_button:far ; Fastgraph routine

int1C_TEXT SEGMENT byte public 'CODE'

          ASSUME  cs:int1C_TEXT                                               �

370 Fastgraph User's Guide


int1C_CS dw  ?  ; holds original INT 1C segment address int1C_IP dw  ?  ; holds original INT 1C offset orig_DS dw  ?  ; holds original data segment

_int1C PROC far

          PUBLIC  _int1C
          push    bp            ; save caller's BP register
          mov     bp,sp         ; make BP point to argument list
          push    si            ; save caller's SI register
          push    di            ; save caller's DI register
          mov     dx,[bp+6]     ; get the flag parameter
          or      dx,dx         ; replace the old interrupt handler?
          jz      replace       ; yes, branch to that processing
define a new handler for INT 1C

define: mov ax,ds  ; put current data segment in AX

          mov     cs:orig_DS,ax ; save it in the control information area
          mov     al,1Ch        ; interrupt vector to save
          mov     ah,53         ; function 53: get interrupt vector
          int     21h           ; get the interrupt vector
          mov     cs:int1C_CS,es; save the segment
          mov     cs:int1C_IP,bx; save the offset
          push    ds            ; save our DS register
          mov     dx,offset handler ; get offset of interrupt handler
          mov     ax,seg handler; get segment of interrupt handler
          mov     ds,ax         ; put it in DS
          mov     al,1Ch        ; interrupt vector to change
          mov     ah,37         ; function 37: set interrupt vector
          int     21h           ; change the INT 1C vector to our handler
          pop     ds            ; restore our DS register
          jmp     short return  ; return to the caller
replace the original handler for INT 1C

replace: push ds  ; save our DS register

          mov     dx,cs:int1C_IP; put original INT 1C offset in DX
          mov     ds,cs:int1C_CS; put original INT 1C segment in DS
          mov     ah,37         ; function 37: set interrupt vector
          mov     al,1Ch        ; interrupt vector 1C
          int     21h           ; restore original INT 1C vector
          pop     ds            ; restore our DS register

return: xor ax,ax  ; in case int1C was called as a function

          pop     di            ; restore our DI register
          pop     si            ; restore our SI register
          pop     bp            ; restore our BP register
          ret

_int1C ENDP �

                                  Appendix C:  Interrupts and Fastgraph   371


handler PROC far  ; interrupt handler that replaces INT 1C

          cli                   ; disable interrupts while handler active
          push    ax            ; save registers that may be altered
          push    bx
          push    cx
          push    dx
          push    di
          push    si
          push    ds
          push    es
          mov     ds,cs:orig_DS ; retrieve the original data segment
          mov     ax,1          ; use joystick 1
          push    ax            ; pass joystick number to button routine
          call    _fg_button    ; AX = button status for joystick 1
          add     sp,2          ; remove the argument
          or      _status1,ax   ; update status variable for joystick 1
          mov     ax,2          ; use joystick 2
          push    ax            ; pass joystick number to button routine
          call    _fg_button    ; AX = button status for joystick 2
          add     sp,2          ; remove the argument
          or      _status2,ax   ; update status variable for joystick 2
          pop     es            ; restore altered registers
          pop     ds
          pop     si
          pop     di
          pop     dx
          pop     cx
          pop     bx
          pop     ax
          iret                  ; return from the interrupt routine

handler ENDP

int1C_TEXT ENDS

          END
    The example just presented is not meant to be a tutorial on interrupts;

there are many good references on DOS that explain them in detail. However, an example specific to Fastgraph should be helpful. � 372 Fastgraph User's Guide �




Appendix D



Contents of the Compiler-Specific Libraries � 374 Fastgraph User's Guide


    For most compilers, Fastgraph provides a compiler-specific library (also

called the auxiliary Fastgraph library) that contains the following routines:

    fg_boxw             fg_drawxw           fg_panw             fg_setsize
    fg_boxxw            fg_drectw           fg_pointw           fg_setsizew
    fg_circlew          fg_ellipsew         fg_pointxw          fg_setworld
    fg_circlefw         fg_ellipsfw         fg_polygonw         fg_swchar
    fg_clprectw         fg_floodw           fg_rectw            fg_swlength
    fg_dashrw           fg_getworld         fg_restorew         fg_swtext
    fg_dashw            fg_initw            fg_savew            fg_xscreen
    fg_drawrw           fg_moverw           fg_setangle         fg_xworld
    fg_drawrxw          fg_movew            fg_setclipw         fg_yscreen
    fg_draww            fg_paintw           fg_setratio         fg_yworld

These routines use the world space coordinate system, either directly or internally. None of them are included in Fastgraph/Light.

    As mentioned in Chapter 1, if your program uses any of these routines,

you must link it with the general Fastgraph library and the corresponding auxiliary Fastgraph library. Some compilers, such as Microsoft Visual C++ 32- bit Edition, Microsoft FORTRAN PowerStation, and Fastgraph's supported BASIC compilers do not require an auxiliary library because the routines listed above are included directly in the Fastgraph library for those compilers. �




Appendix E



Contents of the Pascal Unit Files � 376 Fastgraph User's Guide


    Borland Pascal and Turbo Pascal restrict the total size of all code

segments in a unit file 65,520 bytes. Because the size of Fastgraph's code exceeds this amount, the Fastgraph functions are split among several unit files. This appendix lists the contents of each Pascal unit file.

Fastgraph routines in FGBITMAP

    fg_clipmap          fg_flpimage         fg_pack             fg_scale
    fg_clipmask         fg_getblock         fg_print            fg_shear
    fg_clpimage         fg_getimage         fg_printc           fg_text
    fg_drawmap          fg_getmap           fg_putblock         fg_textc
    fg_drawmask         fg_imagebuf         fg_putimage         fg_unpack
    fg_drwimage         fg_imagesiz         fg_revimage
    fg_flipmask         fg_invert           fg_revmask

Fastgraph routines in FGFLIC

    fg_flicdone         fg_flicmode         fg_flicplay         fg_flicskip
    fg_flichead         fg_flicopen         fg_flicsize         fg_showflic

Fastgraph routines in FGGIF

    fg_gifhead          fg_gifpal           fg_makegif          fg_showgif
    fg_gifmode          fg_gifrange

Fastgraph routines in FGMISC

    fg_button           fg_kbinit           fg_mousemov         fg_setcaps
    fg_capslock         fg_kblast           fg_mousepos         fg_setnum
    fg_cursor           fg_kbreset          fg_mouseptr         fg_sound
    fg_getclock         fg_kbtest           fg_mousespd         fg_sounds
    fg_getkey           fg_measure          fg_mousevis         fg_suspend
    fg_getxjoy          fg_memavail         fg_music            fg_voice
    fg_getyjoy          fg_mouse256         fg_musicb           fg_voices
    fg_hush             fg_mousebut         fg_numlock          fg_waitfor
    fg_hushnext         fg_mousecur         fg_playing          fg_waitkey
    fg_initjoy          fg_mousefin         fg_quiet
    fg_intjoy           fg_mouseini         fg_resume
    fg_intkey           fg_mouselim         fg_scrlock

Fastgraph routines in FGPCX

    fg_loadpcx          fg_pcxhead          fg_pcxpal           fg_showpcx
    fg_makepcx          fg_pcxmode          fg_pcxrange

Fastgraph routines in FGPR

    fg_dispfile         fg_displayp         fg_makespr          fg_showspr
    fg_display          fg_makeppr          fg_showppr

Fastgraph routines in FGSVGA

    fg_defpages         fg_memory           fg_svgainit         fg_svgaver
    fg_getbanks         fg_setbanks         fg_svgastat

Fastgraph routines in FGVB

    fg_vbaddr           fg_vbcut            fg_vbinit           fg_vbundef
    fg_vballoc          fg_vbdefine         fg_vbopen
    fg_vbclose          fg_vbfree           fg_vbpaste
    fg_vbcopy           fg_vbhandle         fg_vbtcxfer                       �
                         Appendix E:  Contents of the Pascal Unit FIles   377


The world space routines listed in Appendix D are in the FGWORLD unit. Any other Fastgraph routine NOT listed in this appendix is in the FGMAIN unit.

As mentioned in Chapter 1, Pascal programs must include a uses statement listing all units referenced in the program. The fgmain unit is always required in all programs, as is the WinAPI unit in 16-bit protected mode programs. Other unit files are needed when you call the Fastgraph routines they contain. � 378 Fastgraph User's Guide �




Appendix F



Integrating Fastgraph With Other Graphics Software � 380 Fastgraph User's Guide


    Sometimes you may want to use Fastgraph with other graphics software,

such as when converting an existing graphics application to Fastgraph. This appendix may clarify some points about doing this.

    First, let the other graphics software establish the video mode, then

initialize Fastgraph for that mode by calling fg_setmode(-1). Passing -1 to fg_setmode does not physically change video modes but merely initializes Fastgraph's internal parameters for the current video mode.

    Second, if you're using the EGA/VGA/SVGA 16-color graphics modes (modes

13 to 18, 28, and 29), you'll probably need to explicitly define the value of the EGA/VGA Enable Set/Reset register (port address 03CE hex, index 01). Fastgraph's functions expect this register to have the value 0F hex; this allows Fastgraph take advantage of a more efficient variant available in EGA/VGA write mode 0. The default value for the Enable Set/Reset register is zero.

    After you've called fg_setmode(-1) and need to call a third party

graphics function, set the Enable Set/Reset register to its default value by including the following statement just before calling the third party function:

outport(0x03CE,0x0001); Borland C++, Turbo C/C++, or Power C outpw(0x03CE,0x0001); Microsoft C/C++, QuickC, WATCOM C/C++ OUT &h03CE,1 : OUT &h03CF,0 QuickBASIC, BASIC PDS, or Visual Basic

Just before you call the next Fastgraph function, restore the Enable Set/Reset register value with the following statement:

outport(0x03CE,0x0F01); Borland C++, Turbo C/C++, or Power C outpw(0x03CE,0x0F01); Microsoft C/C++, QuickC, WATCOM C/C++ OUT &h03CE,1 : OUT &h03CF,15 QuickBASIC, BASIC PDS, or Visual Basic �




Appendix G



Converting Programs to Protected Mode � 382 Fastgraph User's Guide


    In this appendix we'll describe the steps necessary for porting real mode

Fastgraph applications to protected mode. We'll also cover common changes required when converting 16-bit applications to 32-bit protected mode.


Protected Mode Initialization

    The first and most obvious step when converting programs to protected

mode is to call fg_initpm. This routine sets up protected mode features for each supported DOS extender and must be called before any other Fastgraph routine in protected mode programs. Failure to do this will result in a protection fault, usually immediately after setting the video mode. The fg_initpm routine has no arguments and no return value. It is included in the extender-specific support libraries (for example, in FG16DPMI.LIB) if Fastgraph supports more than one DOS extender for a given compiler.


Considerations for Logical Pages

    In real mode, Fastgraph lets you create logical pages in conventional

memory (with fg_alloccms), expanded memory (with fg_allocems), or extended memory (with fg_allocxms). In protected mode, the distinction between conventional, expanded, and extended memory disappears because DOS extenders essentially treat all system memory as conventional memory. For this reason, the fg_initems and fg_initxms routines are not meaningful and thus always return -1 in the protected mode Fastgraph libraries. This effectively disables the fg_allocems and fg_allocxms routines, so you must create logical pages with fg_alloccms in protected mode.

    If you have real mode Fastgraph applications that use logical pages, it's

very simple to convert them to protected mode -- just change all fg_allocems and fg_allocxms calls to fg_alloccms.


Considerations for Virtual Buffers

    Chapter 8 describes the various methods available for allocating memory

for virtual buffers. Because some real mode compilers have limited support for huge arrays (blocks of memory greater than 64K bytes), Fastgraph's fg_vballoc and fg_vbfree routines are provided for allocating and releasing memory suitable for virtual buffers. All protected mode compilers provide full support for huge arrays, so these two functions aren't needed (in fact, they're not even included in the protected mode libraries). Thus, you must replace the fg_vballoc and fg_vbfree calls with your compiler's corresponding memory management functions as listed in Chapter 8 and use fg_vbdefine to create the virtual buffer.


Mouse Cursor Definition

    The fg_mouseptr routine expects the screen and cursor masks to reside in

a 32-element array of 16-bit values. If you're converting a C or C++ Fastgraph application from a 16-bit to a 32-bit environment, you must change the data type of the screen/cursor mask array passed to fg_mouseptr from int to short. �

                     Appendix G:  Converting Programs to Protected Mode   383


FORTRAN programmers should be sure to pass an INTEGER*2 array instead of an ordinary INTEGER array.


FORTRAN Data Types

    When converting FORTRAN programs to 32-bit protected mode, any INTEGER*2

quantities passed to Fastgraph functions must be changed to four-byte integers. For maximum portability, we recommend changing them to type INTEGER, which is equivalent to INTEGER*2 in 16-bit environments and equivalent to INTEGER*4 in 32-bit environments.


Incompatible Real Mode Behavior

    After you've added the fg_initpm call and made the other changes

described so far, you should test your program to see if it runs in protected mode. Most high-level language programs will work at this point with no further changes required.

    However, some programs include features that are acceptable in real mode

but not in protected mode (often this behavior is unintentional). These practices include loading physical addresses in segment registers, using physical segment addresses in far pointers, writing data to a code segment, referencing unspecified command line arguments, accessing memory beyond a segment's limit, and dereferencing null pointers. When a protected mode program encounters one of these problems during execution, it exits to DOS with a general protection fault, or GPF.

    The documentation shipped with your DOS extender will likely provide

information on isolating protection faults and offer suggestions on how to fix them. Two other references, Extending DOS edited by Ray Duncan (Addison- Wesley, 1992) and DOS and Windows Protected Mode by Al Williams (Addison- Wesley, 1993) are valuable resources for protected mode programming. Both books include detailed information about the differences between real mode and protected mode and discuss common protected mode programming problems and solutions. � 384 Fastgraph User's Guide �




Appendix H



Image File Header Formats � 386 Fastgraph User's Guide


    PCX, GIF, and FLI/FLC images include file headers that define the image

size, number of colors, and other information needed to display the image. Fastgraph provides routines for reading the image headers and retrieving their more useful items. However, there may be times when you need additional information stored in the file header. This appendix provides full details about the structure of the PCX, GIF, and flic file headers. In the tables that follow, we'll assume all offsets start at zero, all field sizes are in bytes, and all integer values are stored with the least significant byte first.

PCX files begin with a 128-byte header:

    offset  size   description
       0      1    manufacturer byte, must be 10 decimal
       1      1    PCX version number
                     0 = PC Paintbrush version 2.5
                     2 = PC Paintbrush 2.8 with palette information
                     3 = PC Paintbrush 2.8 without palette information
                     4 = PC Paintbrush for Windows
                     5 = PC Paintbrush 3.0 or later, PC Paintbrush Plus
       2      1    run length encoding byte, must be 1
       3      1    number of bits per pixel per bit plane
       4      8    image limits in pixels: Xmin, Ymin, Xmax, Ymax
      12      2    horizontal dots per inch when printed (unreliable)
      14      2    vertical dots per inch when printed (unreliable)
      16     48    16-color palette (16 RGB triples between 0-255)
      64      1    reserved, must be zero
      65      1    number of bit planes
      66      2    video memory bytes per image row
      68      2    16-color palette interpretation (unreliable)
                     0 = color or b&w, 1 = grayscale
      70      2    horizontal screen resolution - 1 (unreliable)
      72      2    vertical screen resolution - 1 (unreliable)
      74     54    reserved, must be zero

GIF files begin with a 13-byte global header and a 10-byte local header:

    offset  size   description
       0      6    GIF signature, must be GIF87a or GIF89a
       6      2    horizontal resolution of creating video mode (unreliable)
       8      2    vertical resolution of creating video mode (unreliable)
      10      1    global flag byte
                     bit 7 is set if global color map is present
                     bits 0-3 are the number of colors (2**(n+1))
      11      1    background color
      12      1    for GIF87a, must be zero
                   for GIF89a, aspect ratio
      13      0    reserved, must be 44 decimal (ASCII comma)
      14      2    left edge of image in pixels
      16      2    top edge of image in pixels
      18      2    image width in pixels
      20      2    image height in pixels
      22      1    local flag byte
                     bit 7 is set if local color map is present               �
                                 Appendix H:  Image File Header Formats   387


                     bit 6 is set if image is interlaced
                     bits 0-3 are the number of colors (2**(n+1))


FLI and FLC files begin with a 128-byte header:

    offset  size   description
       0      4    file size in bytes
       4      2    signature, AF11 hex for FLI files, AF12 hex for FLC files
       6      2    number of frames
       8      2    image width in pixels
      10      2    image height in pixels
      12      2    bits per pixel, must be 8
      14      2    reserved, must be 3
      16      4    time delay between frames
                     units are 1/70 second for FLI files
                     units are milliseconds for FLC files
      20      2    reserved, must be zero
      22      4    file creation date/time (MS-DOS format)
      26      4    creator serial number (unreliable)
      30      4    file revision date/time (MS-DOS format)
      34      4    updater serial number (unreliable)
      38      4    horizontal aspect ratio of creating video mode
      40      2    vertical aspect ratio of creating video mode
      42     38    reserved, must be zero
      80      4    byte offset to start of first frame
      84      4    byte offset to start of second frame
      88     40    reserved, must be zero

The fields starting at offset 22 and above in the flic file header apply to FLC files only. For FLI files, they should all be zero. � 388 Fastgraph User's Guide �

                                                                  Index   389