1 /* ______ ___ ___
2 * /\ _ \ /\_ \ /\_ \
3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 * /\____/
9 * \_/__/
10 *
11 * Allegro library utility for checking which VBE/AF modes are available.
12 *
13 * By Shawn Hargreaves.
14 *
15 * See readme.txt for copyright information.
16 */
17
18 #define ALLEGRO_USE_CONSOLE
19
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "allegro.h"
24
25
26 /* this program is not portable! */
27 #if (defined ALLEGRO_DOS) || (defined ALLEGRO_LINUX_VBEAF)
28
29 #include "allegro/internal/aintern.h"
30
31 #ifdef ALLEGRO_INTERNAL_HEADER
32 #include ALLEGRO_INTERNAL_HEADER
33 #endif
34
35 #if (defined ALLEGRO_DJGPP) && (!defined SCAN_DEPEND)
36 #include <sys/nearptr.h>
37 #endif
38
39
40
41 #ifdef ALLEGRO_LINUX
42
43 #include <sys/mman.h>
44
45 /* quick and dirty Linux emulation of the DOS memory mapping routines */
46 #define _create_linear_mapping(_addr, _base, _len) \
47 ({ \
48 (_addr)->base = _base; \
49 (_addr)->size = _len; \
50 (_addr)->perms = PROT_READ | PROT_WRITE; \
51 __al_linux_map_memory(_addr); \
52 })
53
54 #define _remove_linear_mapping(_addr) \
55 { \
56 if ((_addr)->data) \
57 __al_linux_unmap_memory(_addr); \
58 }
59
60 #define MMAP struct MAPPED_MEMORY
61 #define NOMM { 0, 0, 0, 0 }
62 #define MVAL(a) a.data
63
64 #else
65
66 /* DOS version */
67 #define MMAP unsigned long
68 #define NOMM 0
69 #define MVAL(a) (void *)((a)-__djgpp_base_address)
70
71 #endif
72
73
74
75 int verbose = FALSE;
76
77
78
79 #ifdef ALLEGRO_GCC
80 #define __PACKED__ __attribute__ ((packed))
81 #else
82 #define __PACKED__
83 #endif
84
85 #ifdef ALLEGRO_WATCOM
86 #pragma pack (1)
87 #endif
88
89
90
91 typedef struct AF_MODE_INFO
92 {
93 unsigned short Attributes __PACKED__;
94 unsigned short XResolution __PACKED__;
95 unsigned short YResolution __PACKED__;
96 unsigned short BytesPerScanLine __PACKED__;
97 unsigned short BitsPerPixel __PACKED__;
98 unsigned short MaxBuffers __PACKED__;
99 unsigned char RedMaskSize;
100 unsigned char RedFieldPosition;
101 unsigned char GreenMaskSize;
102 unsigned char GreenFieldPosition;
103 unsigned char BlueMaskSize;
104 unsigned char BlueFieldPosition;
105 unsigned char RsvdMaskSize;
106 unsigned char RsvdFieldPosition;
107 unsigned short MaxBytesPerScanLine __PACKED__;
108 unsigned short MaxScanLineWidth __PACKED__;
109 unsigned short LinBytesPerScanLine __PACKED__;
110 unsigned char BnkMaxBuffers;
111 unsigned char LinMaxBuffers;
112 unsigned char LinRedMaskSize;
113 unsigned char LinRedFieldPosition;
114 unsigned char LinGreenMaskSize;
115 unsigned char LinGreenFieldPosition;
116 unsigned char LinBlueMaskSize;
117 unsigned char LinBlueFieldPosition;
118 unsigned char LinRsvdMaskSize;
119 unsigned char LinRsvdFieldPosition;
120 unsigned long MaxPixelClock __PACKED__;
121 unsigned long VideoCapabilities __PACKED__;
122 unsigned short VideoMinXScale __PACKED__;
123 unsigned short VideoMinYScale __PACKED__;
124 unsigned short VideoMaxXScale __PACKED__;
125 unsigned short VideoMaxYScale __PACKED__;
126 unsigned char reserved[76];
127 } AF_MODE_INFO;
128
129
130
131 #define DC struct AF_DRIVER *dc
132
133
134
135 typedef struct AF_DRIVER
136 {
137 char Signature[12];
138 unsigned long Version __PACKED__;
139 unsigned long DriverRev __PACKED__;
140 char OemVendorName[80];
141 char OemCopyright[80];
142 short *AvailableModes __PACKED__;
143 unsigned long TotalMemory __PACKED__;
144 unsigned long Attributes __PACKED__;
145 unsigned long BankSize __PACKED__;
146 unsigned long BankedBasePtr __PACKED__;
147 unsigned long LinearSize __PACKED__;
148 unsigned long LinearBasePtr __PACKED__;
149 unsigned long LinearGranularity __PACKED__;
150 unsigned short *IOPortsTable __PACKED__;
151 unsigned long IOMemoryBase[4] __PACKED__;
152 unsigned long IOMemoryLen[4] __PACKED__;
153 unsigned long LinearStridePad __PACKED__;
154 unsigned short PCIVendorID __PACKED__;
155 unsigned short PCIDeviceID __PACKED__;
156 unsigned short PCISubSysVendorID __PACKED__;
157 unsigned short PCISubSysID __PACKED__;
158 unsigned long Checksum __PACKED__;
159 unsigned long res2[6] __PACKED__;
160 void *IOMemMaps[4] __PACKED__;
161 void *BankedMem __PACKED__;
162 void *LinearMem __PACKED__;
163 unsigned long res3[5] __PACKED__;
164 unsigned long BufferEndX __PACKED__;
165 unsigned long BufferEndY __PACKED__;
166 unsigned long OriginOffset __PACKED__;
167 unsigned long OffscreenOffset __PACKED__;
168 unsigned long OffscreenStartY __PACKED__;
169 unsigned long OffscreenEndY __PACKED__;
170 unsigned long res4[10] __PACKED__;
171 unsigned long SetBank32Len __PACKED__;
172 void *SetBank32;
173 void *Int86;
174 void *CallRealMode;
175 void *InitDriver;
176 void *af10Funcs[40];
177 void *PlugAndPlayInit;
178 void *(*OemExt)(DC, unsigned long id);
179 void *SupplementalExt;
180 long (*GetVideoModeInfo)(DC, short mode, AF_MODE_INFO *modeInfo);
181 } AF_DRIVER;
182
183
184
185 #undef DC
186
187
188
189 #define FAF_ID(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | d)
190
191 #define FAFEXT_INIT FAF_ID('I','N','I','T')
192 #define FAFEXT_MAGIC FAF_ID('E','X', 0, 0)
193
194 #define FAFEXT_LIBC FAF_ID('L','I','B','C')
195 #define FAFEXT_PMODE FAF_ID('P','M','O','D')
196
197 #define FAFEXT_HWPTR FAF_ID('H','P','T','R')
198
199 #define FAFEXT_CONFIG FAF_ID('C','O','N','F')
200
201
202 typedef struct FAF_CONFIG_DATA
203 {
204 unsigned long id;
205 unsigned long value;
206 } FAF_CONFIG_DATA;
207
208
209
210 AF_DRIVER *af = NULL;
211
212 MMAP af_memmap[4] = { NOMM, NOMM, NOMM, NOMM };
213 MMAP af_banked_mem = NOMM;
214 MMAP af_linear_mem = NOMM;
215
216
217
218 #ifdef ALLEGRO_DOS
219
220 /* hooks to let the driver call BIOS routines */
221 extern void _af_int86(void), _af_call_rm(void);
222
223 #else
224
225 /* no BIOS on this platform, my friend! */
nobios(void)226 void nobios(void) { }
227
228 #endif
229
230
231
af_exit(void)232 void af_exit(void)
233 {
234 int c;
235
236 for (c=0; c<4; c++)
237 _remove_linear_mapping(&af_memmap[c]);
238
239 _remove_linear_mapping(&af_banked_mem);
240 _remove_linear_mapping(&af_linear_mem);
241
242 if (af) {
243 free(af);
244 af = NULL;
245 }
246 }
247
248
249
call_vbeaf_asm(void * proc)250 static int call_vbeaf_asm(void *proc)
251 {
252 int ret;
253
254 proc = (void *)((long)af + (long)proc);
255
256 #ifdef ALLEGRO_GCC
257
258 /* use gcc-style inline asm */
259 asm (
260 " call *%%edx "
261
262 : "=&a" (ret) /* return value in eax */
263
264 : "b" (af), /* VBE/AF driver in ds:ebx */
265 "d" (proc) /* function ptr in edx */
266
267 : "memory" /* assume everything is clobbered */
268 );
269
270 #elif defined ALLEGRO_WATCOM
271
272 /* use Watcom-style inline asm */
273 {
274 int _af(void *func, AF_DRIVER *driver);
275
276 #pragma aux _af = \
277 " call esi " \
278 \
279 parm [esi] [ebx] \
280 modify [ecx edx edi] \
281 value [eax];
282
283 ret = _af(proc, af);
284 }
285
286 #else
287
288 /* don't know what to do on this compiler */
289 ret = -1;
290
291 #endif
292
293 return ret;
294 }
295
296
297
load_vbeaf_driver(char * filename)298 int load_vbeaf_driver(char *filename)
299 {
300 long size;
301 PACKFILE *f;
302
303 size = file_size_ex(filename);
304 if (size <= 0)
305 return -1;
306
307 f = pack_fopen(filename, F_READ);
308 if (!f)
309 return -1;
310
311 af = malloc(size);
312
313 if (pack_fread(af, size, f) != size) {
314 free(af);
315 af = NULL;
316 return -1;
317 }
318
319 pack_fclose(f);
320
321 return 0;
322 }
323
324
325
initialise_freebeaf_extensions(void)326 void initialise_freebeaf_extensions(void)
327 {
328 typedef unsigned long (*EXT_INIT_FUNC)(AF_DRIVER *af, unsigned long id);
329 EXT_INIT_FUNC ext_init;
330 FAF_CONFIG_DATA *cfg;
331 unsigned long magic;
332 int v1, v2;
333
334 if (!af->OemExt) {
335 printf("no OemExt\n");
336 return;
337 }
338
339 ext_init = (EXT_INIT_FUNC)((long)af + (long)af->OemExt);
340
341 magic = ext_init(af, FAFEXT_INIT);
342
343 v1 = (magic>>8)&0xFF;
344 v2 = magic&0xFF;
345
346 if (((magic&0xFFFF0000) != FAFEXT_MAGIC) || (!uisdigit(v1)) || (!uisdigit(v2))) {
347 printf("bad magic number!\n");
348 return;
349 }
350
351 printf("EX%c%c", v1, v2);
352
353 if (af->OemExt(af, FAFEXT_LIBC))
354 printf(", FAFEXT_LIBC");
355
356 if (af->OemExt(af, FAFEXT_PMODE))
357 printf(", FAFEXT_PMODE");
358
359 if (af->OemExt(af, FAFEXT_HWPTR))
360 printf(", FAFEXT_HWPTR");
361
362 cfg = af->OemExt(af, FAFEXT_CONFIG);
363 if (cfg)
364 printf(", FAFEXT_CONFIG");
365
366 printf("\n");
367
368 if (cfg) {
369 while (cfg->id) {
370 printf("Config variable:\t%c%c%c%c = 0x%08lX\n",
371 (char)(cfg->id>>24), (char)(cfg->id>>16),
372 (char)(cfg->id>>8), (char)(cfg->id), cfg->value);
373
374 cfg++;
375 }
376 }
377 }
378
379
380
initialise_vbeaf(void)381 static int initialise_vbeaf(void)
382 {
383 int c;
384
385 #ifdef ALLEGRO_DOS
386 if (__djgpp_nearptr_enable() == 0)
387 return -1;
388 #else
389 if (!__al_linux_have_ioperms)
390 return -1;
391 #endif
392
393 for (c=0; c<4; c++) {
394 if (af->IOMemoryBase[c]) {
395 if (_create_linear_mapping(&af_memmap[c], af->IOMemoryBase[c],
396 af->IOMemoryLen[c]) != 0)
397 return -1;
398
399 af->IOMemMaps[c] = MVAL(af_memmap[c]);
400 }
401 }
402
403 if (af->BankedBasePtr) {
404 if (_create_linear_mapping(&af_banked_mem, af->BankedBasePtr, 0x10000) != 0)
405 return -1;
406
407 af->BankedMem = MVAL(af_banked_mem);
408 }
409
410 if (af->LinearBasePtr) {
411 if (_create_linear_mapping(&af_linear_mem, af->LinearBasePtr, af->LinearSize*1024) != 0)
412 return -1;
413
414 af->LinearMem = MVAL(af_linear_mem);
415 }
416
417 #ifdef ALLEGRO_DOS
418 af->Int86 = _af_int86;
419 af->CallRealMode = _af_call_rm;
420 #else
421 af->Int86 = nobios;
422 af->CallRealMode = nobios;
423 #endif
424
425 return 0;
426 }
427
428
429
print_af_attributes(unsigned long attrib)430 void print_af_attributes(unsigned long attrib)
431 {
432 static char *flags[] =
433 {
434 "multibuf",
435 "scroll",
436 "banked",
437 "linear",
438 "accel",
439 "dualbuf",
440 "hwcursor",
441 "8bitdac",
442 "nonvga",
443 "2scan",
444 "interlace",
445 "3buffer",
446 "stereo",
447 "rop2",
448 "hwstsync",
449 "evcstsync"
450 };
451
452 int first = TRUE;
453 int c;
454
455 printf("Attributes:\t\t");
456
457 for (c=0; c<(int)(sizeof(flags)/sizeof(flags[0])); c++) {
458 if (attrib & (1<<c)) {
459 if (first)
460 first = FALSE;
461 else
462 printf(", ");
463
464 printf(flags[c]);
465 }
466 }
467
468 printf("\n");
469 }
470
471
472
get_af_info(void)473 int get_af_info(void)
474 {
475 static char *possible_filenames[] =
476 {
477 #ifdef ALLEGRO_DOS
478 "c:\\vbeaf.drv",
479 #else
480 "/usr/local/lib/vbeaf.drv",
481 "/usr/lib/vbeaf.drv",
482 "/lib/vbeaf.drv",
483 "/vbeaf.drv",
484 #endif
485 NULL
486 };
487
488 char filename[256];
489 AL_CONST char *p;
490 int c, attrib;
491
492 p = get_config_string(NULL, "vbeaf_driver", NULL);
493 if ((p) && (*p)) {
494 strcpy(filename, p);
495 if (*get_filename(filename) == 0) {
496 strcat(filename, "vbeaf.drv");
497 }
498 else {
499 if (file_exists(filename, FA_DIREC, &attrib)) {
500 if (attrib & FA_DIREC) {
501 put_backslash(filename);
502 strcat(filename, "vbeaf.drv");
503 }
504 }
505 }
506 if (load_vbeaf_driver(filename) == 0)
507 goto found_it;
508 }
509
510 for (c=0; possible_filenames[c]; c++) {
511 strcpy(filename, possible_filenames[c]);
512 if (load_vbeaf_driver(filename) == 0)
513 goto found_it;
514 }
515
516 p = getenv("VBEAF_PATH");
517 if (p) {
518 strcpy(filename, p);
519 put_backslash(filename);
520 strcat(filename, "vbeaf.drv");
521 if (load_vbeaf_driver(filename) == 0)
522 goto found_it;
523 }
524
525 #ifdef ALLEGRO_DOS
526 printf("Error: no VBE/AF driver found!\nYou should have a vbeaf.drv file in the root of your C: drive\n");
527 #else
528 printf("Error: no VBE/AF driver found!\nYou should have a vbeaf.drv file in the root of your filesystem\n");
529 #endif
530
531 return -1;
532
533 found_it:
534
535 printf("Driver file:\t\t%s\n", filename);
536
537 if (strcmp(af->Signature, "VBEAF.DRV") != 0) {
538 af_exit();
539 printf("\nError: bad header ID in this driver file!\n");
540 return -1;
541 }
542
543 if (af->Version < 0x200) {
544 af_exit();
545 printf("Error: obsolete driver version! (0x%lX)\n", af->Version);
546 return -1;
547 }
548
549 printf("FreeBE/AF ext:\t\t");
550
551 if (strstr(af->OemVendorName, "FreeBE"))
552 initialise_freebeaf_extensions();
553 else
554 printf("not a FreeBE/AF driver\n");
555
556 if (call_vbeaf_asm(af->PlugAndPlayInit) != 0) {
557 af_exit();
558 printf("\nError: VBE/AF Plug and Play initialisation failed!\n");
559 return -1;
560 }
561
562 if (initialise_vbeaf() != 0) {
563 af_exit();
564 printf("\nError: cannot map VBE/AF device memory!\n");
565 return -1;
566 }
567
568 if (call_vbeaf_asm(af->InitDriver) != 0) {
569 af_exit();
570 printf("\nError: VBE/AF device not present!\n");
571 return -1;
572 }
573
574 printf("VBE/AF version:\t\t0x%lX\n", af->Version);
575 printf("VendorName:\t\t%s\n", af->OemVendorName);
576 printf("VendorCopyright:\t%s\n", af->OemCopyright);
577 printf("TotalMemory:\t\t%ld\n", af->TotalMemory);
578
579 print_af_attributes(af->Attributes);
580
581 if (verbose) {
582 printf("BankedAddr:\t\t0x%08lX\n", af->BankedBasePtr);
583 printf("BankedSize:\t\t0x%08lX\n", af->BankSize*1024);
584 printf("LinearAddr:\t\t0x%08lX\n", af->LinearBasePtr);
585 printf("LinearSize:\t\t0x%08lX\n", af->LinearSize*1024);
586
587 for (c=0; c<4; c++) {
588 printf("IOMemoryBase[%d]:\t0x%08lX\n", c, af->IOMemoryBase[c]);
589 printf("IOMemoryLen[%d]:\t\t0x%08lX\n", c, af->IOMemoryLen[c]);
590 }
591
592 printf("\n\n\n");
593 }
594 else
595 printf("\n");
596
597 return 0;
598 }
599
600
601
602 typedef struct COLORINFO
603 {
604 int size;
605 int pos;
606 char c;
607 } COLORINFO;
608
609 COLORINFO colorinfo[4];
610
611 int colorcount = 0;
612
613
614
color_cmp(const void * e1,const void * e2)615 int color_cmp(const void *e1, const void *e2)
616 {
617 COLORINFO *c1 = (COLORINFO *)e1;
618 COLORINFO *c2 = (COLORINFO *)e2;
619
620 return c2->pos - c1->pos;
621 }
622
623
624
add_color(int size,int pos,char c)625 void add_color(int size, int pos, char c)
626 {
627 if ((size > 0) || (pos > 0)) {
628 colorinfo[colorcount].size = size;
629 colorinfo[colorcount].pos = pos;
630 colorinfo[colorcount].c = c;
631 colorcount++;
632 }
633 }
634
635
636
get_color_desc(char * s)637 void get_color_desc(char *s)
638 {
639 int c;
640
641 if (colorcount > 0) {
642 qsort(colorinfo, colorcount, sizeof(COLORINFO), color_cmp);
643
644 for (c=0; c<colorcount; c++)
645 *(s++) = colorinfo[c].c;
646
647 *(s++) = ' ';
648
649 for (c=0; c<colorcount; c++)
650 *(s++) = '0' + colorinfo[c].size;
651
652 colorcount = 0;
653 }
654
655 *s = 0;
656 }
657
658
659
get_mode_info(int mode)660 int get_mode_info(int mode)
661 {
662 AF_MODE_INFO mode_info;
663 char color_desc[80];
664 char buf[80];
665
666 if (!verbose) {
667 sprintf(buf, "%X:", mode);
668 printf("Mode 0x%-5s", buf);
669 }
670 else
671 printf("Mode 0x%X:\n\n", mode);
672
673 if (af->GetVideoModeInfo(af, mode, &mode_info) != 0) {
674 printf("GetVideoModeInfo failed!\n");
675 if (verbose)
676 printf("\n\n\n");
677 return -1;
678 }
679
680 add_color(mode_info.RedMaskSize, mode_info.RedFieldPosition, 'R');
681 add_color(mode_info.GreenMaskSize, mode_info.GreenFieldPosition, 'G');
682 add_color(mode_info.BlueMaskSize, mode_info.BlueFieldPosition, 'B');
683 add_color(mode_info.RsvdMaskSize, mode_info.RsvdFieldPosition, 'x');
684 get_color_desc(color_desc);
685
686 if (verbose) {
687 print_af_attributes(mode_info.Attributes);
688
689 if (color_desc[0])
690 printf("Format:\t\t\t%s\n", color_desc);
691
692 printf("XResolution:\t\t%d\n", mode_info.XResolution);
693 printf("YResolution:\t\t%d\n", mode_info.YResolution);
694 printf("BitsPerPixel:\t\t%d\n", mode_info.BitsPerPixel);
695 printf("BytesPerScanLine:\t%d\n", mode_info.BytesPerScanLine);
696 printf("LinBytesPerScanLine:\t%d\n", mode_info.LinBytesPerScanLine);
697 printf("MaxBytesPerScanLine:\t%d\n", mode_info.MaxBytesPerScanLine);
698 printf("MaxScanLineWidth:\t%d\n", mode_info.MaxScanLineWidth);
699 printf("MaxBuffers:\t\t%d\n", mode_info.MaxBuffers);
700 printf("BnkMaxBuffers:\t\t%d\n", mode_info.BnkMaxBuffers);
701 printf("LinMaxBuffers:\t\t%d\n", mode_info.LinMaxBuffers);
702 printf("RedMaskSize:\t\t%d\n", mode_info.RedMaskSize);
703 printf("RedFieldPos:\t\t%d\n", mode_info.RedFieldPosition);
704 printf("GreenMaskSize:\t\t%d\n", mode_info.GreenMaskSize);
705 printf("GreenFieldPos:\t\t%d\n", mode_info.GreenFieldPosition);
706 printf("BlueMaskSize:\t\t%d\n", mode_info.BlueMaskSize);
707 printf("BlueFieldPos:\t\t%d\n", mode_info.BlueFieldPosition);
708 printf("RsvdMaskSize:\t\t%d\n", mode_info.RsvdMaskSize);
709 printf("RsvdFieldPos:\t\t%d\n", mode_info.RsvdFieldPosition);
710 printf("LinRedMaskSize:\t\t%d\n", mode_info.LinRedMaskSize);
711 printf("LinRedFieldPos:\t\t%d\n", mode_info.LinRedFieldPosition);
712 printf("LinGreenMaskSize:\t%d\n", mode_info.LinGreenMaskSize);
713 printf("LinGreenFieldPos:\t%d\n", mode_info.LinGreenFieldPosition);
714 printf("LinBlueMaskSize:\t%d\n", mode_info.LinBlueMaskSize);
715 printf("LinBlueFieldPos:\t%d\n", mode_info.LinBlueFieldPosition);
716 printf("LinRsvdMaskSize:\t%d\n", mode_info.LinRsvdMaskSize);
717 printf("LinRsvdFieldPos:\t%d\n", mode_info.LinRsvdFieldPosition);
718 printf("MaxPixelClock:\t\t%ld\n", mode_info.MaxPixelClock);
719
720 printf("\n\n\n");
721 }
722 else {
723 printf("%5dx%-6d", mode_info.XResolution, mode_info.YResolution);
724 printf("%d bpp", mode_info.BitsPerPixel);
725 if (color_desc[0])
726 printf(" (%s)", color_desc);
727 printf("\n");
728 }
729
730 return 0;
731 }
732
733
734
main(int argc,char * argv[])735 int main(int argc, char *argv[])
736 {
737 int c;
738
739 if (allegro_init() != 0)
740 return 1;
741
742 #ifdef SYSTEM_XWINDOWS
743 if (system_driver->id == SYSTEM_XWINDOWS) {
744 allegro_message("Sorry, VBE/AF is not available under X, run AFINFO from Linux console\n");
745 return 1;
746 }
747 #endif
748
749 #ifdef ALLEGRO_LINUX
750 if (!__al_linux_have_ioperms) {
751 printf("Sorry, you need to be root before you can do stuff with VBE/AF\n");
752 return 1;
753 }
754 #endif
755
756 for (c=1; c<argc; c++)
757 if (((argv[c][0] == '-') || (argv[c][0] == '/')) &&
758 ((argv[c][1] == 'v') || (argv[c][1] == 'V')))
759 verbose = TRUE;
760
761 printf("\nAllegro VBE/AF info utility " ALLEGRO_VERSION_STR ", " ALLEGRO_PLATFORM_STR);
762 printf("\nBy Shawn Hargreaves, " ALLEGRO_DATE_STR "\n\n");
763
764 if (get_af_info() != 0)
765 return -1;
766
767 for (c=0; af->AvailableModes[c] != -1; c++)
768 get_mode_info(af->AvailableModes[c]);
769
770 if (!verbose)
771 printf("\n'afinfo -v' for a verbose listing\n\n");
772
773 af_exit();
774
775 return 0;
776 }
777
778
779
780 #else /* ifdef VBE/AF cool on this platform */
781
782
main(void)783 int main(void)
784 {
785 allegro_init();
786 allegro_message("Sorry, the AFINFO program only works on DOS or Linux\n");
787 return 1;
788 }
789
790
791 #endif
792
793
794 END_OF_MAIN()
795