/* file: vsetup.c G. Moody July 1989 Last revised: 1 May 1997 Initialization for `view' Copyright (C) Massachusetts Institute of Technology 1997. All rights reserved. */ #include #include #include #include #include /* Keyboard scan codes */ #define UP 72 #define DOWN 80 #define LEFT 75 #define RIGHT 77 #define ENTER 28 /* Abbreviate incredibly long Microsoft function names. */ #define st(A,B) _settextposition(A,B) #define sv(A) _setvideomode(A) #define dotted _setlinestyle(0x5555) #define solid _setlinestyle(0xffff) #define li(A,B) _putimage(A,B,b,_GXOR) main(argc, argv) int argc; char *argv[]; { struct videoconfig vc; char far *b; FILE *ofile = NULL; int done, mode = 0, r0, left, right, top, bottom, width, height; unsigned int s1, s2; char buf[10]; /* Take a command-line argument as a video mode number to be tried first; if the argument is `-s', however, append the derived command for setting VIEWP to the file named in the next argument. */ if (argc > 1) { if (strcmp(argv[1], "-s") == 0 && argc > 2) { if ((ofile = fopen(argv[2], "a")) == NULL) { fprintf(stderr, "can't append to `%s'\n", argv[2]); exit(1); } } else switch (mode = atoi(argv[1])) { case _MRES256COLOR: case _VRES16COLOR: case _VRES2COLOR: case _ERESCOLOR: case _HERCMONO: case _ERESNOCOLOR: case _HRES16COLOR: case _MRES16COLOR: case _MRES4COLOR: case _HRESBW: case _MRESNOCOLOR: #if (_MSC_VER >= 700) case _ORESCOLOR: case _ORES256COLOR: case _VRES256COLOR: case _SRES16COLOR: case _SRES256COLOR: case _XRES16COLOR: case _XRES256COLOR: case _ZRES16COLOR: case _ZRES256COLOR: #endif if (sv(mode)) break; /* If unsucessful, fall through to the default case. */ default: printf("Sorry, video mode %d cannot be used.\n", mode); printf("Press ENTER and this program will try to find\n"); printf("a usable video mode: "); fgets(buf, 10, stdin); mode = 0; } } else mode = 0; /* Try to find a mode that works. */ if (mode == 0 && !(mode = set_mode())) { printf("Your current video mode is not supported.\n"); printf("Try typing `mode co80' before continuing.\n"); exit(1); } /* Read the selected video mode configuration. */ _getvideoconfig(&vc); /* Set the assumed display area based on the configuration structure. Note that the origin is at *top* left, and the coordinates increase going right or down. Note also that the largest legal coordinates are one less than the number of pixels in each direction (since row and column 0 are legal). */ left = top = 0; right = vc.numxpixels-1; bottom = vc.numypixels-1; /* Allocate a buffer for storage of the dotted lines which will be moved about when finding the displayable area. */ s1 = _imagesize(left, top, left, bottom); s2 = _imagesize(left, top, right, top); b = (char far *)malloc((s1 > s2) ? s1 : s2); /* Messages will be placed near the middle of the screen. We must be careful not to go beyond 40 columns per line, or we'll have problems with CGA displays. It also seems as if we have to set the row and column at the beginning of each line, or we get double-spaced text in 320x200 CGA mode and single-spaced text in 640x200 CGA mode, and who knows what else. Arghhh! */ r0 = vc.numtextrows/2-2; /* Find the leftmost displayable abscissa. */ st(r0, 1); printf("<- A vertical line should be visible \n"); st(r0+1, 1); printf(" to the left; if not, press the \n"); st(r0+2, 1); printf(" right arrow key until it is visible.\n"); st(r0+3, 1); printf(" To continue, press ENTER."); dotted; _moveto(left, top); _lineto(left, bottom); solid; _getimage(0, 0, 0, bottom, b); for (done = 0; !done; ) { switch ((_bios_keybrd(_KEYBRD_READ) & 0xff00) >> 8) { case LEFT: if (0 < left) { li(left--, top); li(left, top); } break; case RIGHT: if (left < right) { li(left++, top); li(left, top); } break; case ENTER: _moveto(left,top); _lineto(left,bottom); done = 1; break; } } /* Find the rightmost displayable abscissa. */ st(r0, 1); printf(" A vertical line should be visible ->\n"); st(r0+1, 1); printf(" to the right; if not, press the \n"); st(r0+2, 1); printf(" left arrow key until it is visible. \n"); st(r0+3, 1); printf(" To continue, press ENTER."); _moveto(left, top); _lineto(left, bottom); li(right, top); for (done = 0; !done; ) { switch ((_bios_keybrd(_KEYBRD_READ) & 0xff00) >> 8) { case LEFT: if (left < right) { li(right--, top); li(right, top); } break; case RIGHT: if (right < vc.numxpixels-1) { li(right++, top); li(right, top); } break; case ENTER: _moveto(right, top); _lineto(right, bottom); done = 1; break; } } /* Find the top displayable ordinate. */ st(r0, 1); printf(" A horizontal line should be visible \n"); st(r0+1, 1); printf(" above; if not, press the \n"); st(r0+2, 1); printf(" down arrow key until it is visible. \n"); st(r0+3, 1); printf(" To continue, press ENTER."); _moveto(left, top); _lineto(left, bottom); dotted; _moveto(left, top); _lineto(right, top); solid; _getimage(left, 0, right, 0, b); for (done = 0; !done; ) { switch ((_bios_keybrd(_KEYBRD_READ) & 0xff00) >> 8) { case UP: if (0 < top) { li(left, top--); li(left, top); } break; case DOWN: if (top < bottom) { li(left, top++); li(left, top); } break; case ENTER: _moveto(left, top); _lineto(right, top); done = 1; break; } } /* Find the bottom displayable ordinate. */ st(r0, 1); printf(" A horizontal line should be visible \n"); st(r0+1, 1); printf(" below; if not, press the \n"); st(r0+2, 1); printf(" up arrow key until it is visible. \n"); st(r0+3, 1); printf(" To continue, press ENTER."); _moveto(left, top); _lineto(left, bottom); li(left, bottom); for (done = 0; !done; ) { switch ((_bios_keybrd(_KEYBRD_READ) & 0xff00) >> 8) { case UP: if (0 < bottom) { li(left, bottom--); li(left, bottom); } break; case DOWN: if (bottom < vc.numypixels-1) { li(left, bottom++); li(left, bottom); } break; case ENTER: _moveto(left, bottom); _lineto(right, bottom); done = 1; break; } } st(r0, 1); printf(" Please measure the length of one of \n"); st(r0+1, 1); printf(" the horizontal lines in millimeters \n"); st(r0+2, 1); printf(" and enter it here: ___ \n"); st(r0+3, 1); printf(" To continue, press ENTER.\n"); _moveto(left, top); _lineto(left, bottom); st(r0+2, 23); scanf("%d", &width); st(r0, 1); printf(" Please measure the length of one of \n"); st(r0+1, 1); printf(" the vertical lines in millimeters \n"); st(r0+2, 1); printf(" and enter it here: ___ \n"); st(r0+3, 1); printf(" To continue, press ENTER.\n"); _moveto(left, top); _lineto(left, bottom); st(r0+2, 23); scanf("%d", &height); sv(_DEFAULTMODE); if (ofile == NULL) { printf("To use `view', either type the command below or put it in\n"); printf("your `autoexec.bat' file (if you do the latter, it will be\n"); printf("effective only after a reboot):\n\n"); printf(" set VIEWP=%d,%d,%d,%d,%d,%d,%d\n", mode, left, right, top, bottom, width, height); } else { fprintf(ofile, "set VIEWP=%d,%d,%d,%d,%d,%d,%d\n", mode, left, right, top, bottom, width, height); fclose(ofile); } exit(0); } int set_mode() { if (sv(_VRES16COLOR)) return (_VRES16COLOR); /* 640x480x4 */ if (sv(_VRES2COLOR)) return (_VRES2COLOR); /* 640x480x1 */ if (sv(_ERESCOLOR)) return (_ERESCOLOR); /* 640x350x2/4 */ if (sv(_HERCMONO)) return (_HERCMONO); /* 720x348x1 */ if (sv(_ERESNOCOLOR)) return (_ERESNOCOLOR); /* 640x350x1 */ if (sv(_HRES16COLOR)) return (_HRES16COLOR); /* 640x200x4 */ if (sv(_HRESBW)) return (_HRESBW); /* 640x200x1 */ if (sv(_MRES16COLOR)) return (_MRES16COLOR); /* 320x200x4 */ if (sv(_MRES4COLOR)) return (_MRES4COLOR); /* 320x200x2 */ if (sv(_MRESNOCOLOR)) return (_MRESNOCOLOR); /* 320x200x2 */ return (0); }