Bienvenue sur le wiki de Nuit debout, nous sommes le 2987 mars.
Villes/Montluçon/sciences/FastGraph
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.
- 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