home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / FACETV.ZIP / GRAFXLOG.C < prev    next >
C/C++ Source or Header  |  1994-01-05  |  26KB  |  944 lines

  1. /************************************************************************
  2. **
  3. ** @(#)grafxlog.c    01/05/94    Chris Ahlstrom
  4. **
  5. **    A module using Borland video functions, but meant to isolate
  6. ** this "Borlandness" from caller programs.
  7. **
  8. **    Contains routines for setting and obtaining the current video
  9. ** context in one fell swoop.  These routines obtain everything that
  10. ** Borland functions allow you to obtain concerning the graphics
  11. ** screen.
  12. **
  13. **    All of these routines work with whatever the current
  14. ** video adapter is.
  15. **
  16. *************************************************************************/
  17.  
  18. #define GRAFXLOG_c
  19.  
  20. #include <alloc.h>
  21. #include <conio.h>
  22. #include <dos.h>
  23. #include <graphics.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26.  
  27. #include "bios_vid.h"
  28. #include "grafxlog.h"
  29.  
  30. #define KBHIT    while (!kbhit() ) ; (void) getch()
  31.  
  32.  
  33.  
  34. /************************************************************************
  35. ** setGraphicsModes()
  36. **
  37. **    Sets the current graphics video mode values by loading from the
  38. ** Screen structure.  The following members of Screen object *s must
  39. ** be loaded first:
  40. **
  41. **    screen_page
  42. **    screen_mode
  43. **    cursor_row
  44. **    cursor_column
  45. **    cursor_start_line
  46. **    cursor_end_line
  47. **
  48. *************************************************************************/
  49.  
  50. int
  51. setGraphicsModes
  52. (
  53.     Screen *s
  54. )
  55. {
  56.     union REGS regs;
  57.     int type;
  58.     int err = 0;
  59.  
  60.     /********************************************************************
  61.     ** Set the page number, if in the proper range.
  62.     *********************************************************************/
  63.  
  64.     if (s->screen_page >= 0 && s->screen_page < 8)
  65.     {
  66.     regs.h.ah = VIDEO_PAGE_SELECT;
  67.     regs.h.al = s->screen_page;
  68.     int86(VIDEO_BIOS, ®s, ®s);    /* set video page no.    */
  69.     }
  70.     else
  71.     err = 1;
  72.  
  73.     /********************************************************************
  74.     ** Now set the mode of the page
  75.     *********************************************************************/
  76.  
  77.     if (s->screen_mode > 80)        /* supports extended modes    */
  78.     {
  79.     s->screen_mode += VID_TEXT_43_50; /* IS THIS RIGHT? NO...    */
  80.     }
  81.     regs.h.ah = VIDEO_MODE;
  82.     regs.h.al = s->screen_mode;
  83.     int86(VIDEO_BIOS, ®s, ®s);    /* set cursor position        */
  84.  
  85.     /********************************************************************
  86.     ** Set the cursor type.
  87.     *********************************************************************/
  88.  
  89.     type = s->cursor_start_line;    /* CH = starting (top) line    */
  90.     type <<= 8;                /* CL = ending (bottom) line    */
  91.     type += s->cursor_end_line;
  92.     regs.h.ah = VIDEO_CURSOR_SIZE;
  93.     regs.x.cx = type;            /* position of cursor bounds    */
  94.     int86(VIDEO_BIOS, ®s, ®s);    /* set cursor position        */
  95.  
  96.     /********************************************************************
  97.     ** Set the cursor position.  Use desired video page.
  98.     *********************************************************************/
  99.  
  100.     regs.h.ah = VIDEO_CURSOR_POSITION;
  101.     regs.h.bh = s->screen_page;
  102.     regs.h.dh = s->cursor_row;
  103.     regs.h.dl = s->cursor_column;
  104.     int86(VIDEO_BIOS, ®s, ®s);    /* set cursor position        */
  105.  
  106.     setcolor(s->screen_attribute);
  107.     setbkcolor(s->screen_backattribute);
  108.  
  109.     /********************************************************************
  110.     ** We cannot set the rest, so we dummy them for now.
  111.     **
  112.     ** dummy = s->screen_rows;
  113.     **
  114.     ********************************************************************/
  115.  
  116.     return err;
  117. }
  118.  
  119.  
  120. /************************************************************************
  121. ** getGraphicsModes()
  122. **
  123. **    Returns the current graphics video mode values by loading up the
  124. ** Screen structure.
  125. **
  126. **    The return value is the type of video screen (which is also
  127. ** returned as part of the structure).  The rest are returned as
  128. ** side-effects, in the Screen structure.
  129. **
  130. **    If the Screen structure pointer is NULL, then only the
  131. ** screen driver code is returned (for easy, breakable, screen-checking).
  132. ** See video.c for typical values returned for some video setups.
  133. ** Also see Borland's graphics.h file.
  134. **
  135. ** IMPORTANT:
  136. **
  137. **    The screen_gmax_x and screen_gmax_y parameters will be 0 unless
  138. ** graphics-mode is first entered [e.g. by graphicsScreen()] before
  139. ** calling getGraphicsModes().
  140. **
  141. ** WARNING:
  142. **
  143. **    1.  Still doesn't obtain s->screen_atribute
  144. **    2.  Doesn't check s->adapter... just uses the current one
  145. **
  146. *************************************************************************/
  147.  
  148. GraphicsDriver
  149. getGraphicsModes
  150. (
  151.     Screen *s
  152. )
  153. {
  154.     union REGS regs;
  155.     int graphdrvr = (int) DETECT;    /* start with auto-detection    */
  156.     int graphmode = (int) VGALO;    /* start with a "zero" value    */
  157.     int *gd = &graphdrvr;        /* detectgraph (if 0) or driver    */
  158.     int *gm = &graphmode;        /* if not zero, graphics mode    */
  159.     int xasp, yasp;            /* for reading aspect ratio    */
  160.     int errcode = DETECT;        /* here, zero is an error!    */
  161.  
  162.     detectgraph(gd, gm);            /* find basic fact    */
  163.     if (graphresult() != grOk)            /* no graphics hardware    */
  164.     {
  165.     return errcode;
  166.     }
  167.  
  168.     if (s != NULL)
  169.     {
  170.     /****************************************************************
  171.     ** Allocate the following two structures, and make sure that
  172.     ** the SFT member of *vbs points to *sft.  Be very rigorous
  173.     ** about error-checking.
  174.     *****************************************************************/
  175.  
  176.     Static_Function_Table *sft;
  177.     Video_BIOS_State *vbs;
  178.  
  179.     sft = (Static_Function_Table *) malloc(sizeof(Static_Function_Table));
  180.     if (sft == NULL)
  181.         return errcode;
  182.  
  183.     vbs = (Video_BIOS_State *) malloc(sizeof(Video_BIOS_State));
  184.     if (vbs == NULL)
  185.     {
  186.         free(sft);
  187.         return errcode;
  188.     }
  189.     else
  190.     {
  191.         vbs->SFT = sft;
  192.     }
  193.  
  194.     regs.h.ah = VIDEO_STATUS;
  195.     int86(VIDEO_BIOS, ®s, ®s);
  196.     s->screen_mode      = (int) regs.h.al;    /* get the mode        */
  197.     s->screen_page      = (int) regs.h.bh;    /* get the video page    */
  198.     s->screen_columns = (int) regs.h.ah;    /* width in characters    */
  199.  
  200.     /****************************************************************
  201.     ** regs.h.bh from above is used implicitly as the screen page number.
  202.     *****************************************************************/
  203.  
  204.     regs.h.ah = VIDEO_READ_CURSOR;
  205.     int86(VIDEO_BIOS, ®s, ®s);    /* get cursor position    */
  206.     s->cursor_column    = regs.h.dl;
  207.     s->cursor_row        = regs.h.dh;
  208.  
  209.     /****************************************************************
  210.     ** Instead of the following, we use the getvbs() routine below:
  211.     **
  212.     ** s->cursor_start_line    = regs.h.cl;
  213.     ** s->cursor_end_line    = regs.h.ch;
  214.     **
  215.     *****************************************************************/
  216.  
  217.     (void) getvbs(vbs);            /* state of video BIOS    */
  218.  
  219.     s->cursor_start_line    = vbs->cursor_start_line;
  220.     s->cursor_end_line    = vbs->cursor_end_line;
  221.  
  222.     if (s->screen_columns != vbs->character_columns)
  223.     {
  224.         printf("Screen column mismatch!\n");
  225.         return errcode;
  226.     }
  227.     s->screen_rows        = vbs->number_of_rows;
  228.     s->screen_gmax_x    = getmaxx();    /*vbs->character_columns*/
  229.     s->screen_gmax_y    = getmaxy();    /*vbs->number_of_rows    */
  230.     s->screen_attribute    = getcolor();
  231.     s->screen_backattribute    = getbkcolor();
  232.  
  233.     s->screen_rasters    = sft->raster_lines_supported;
  234.     s->screen_charsets    = sft->max_character_sets;
  235.     s->screen_chardefs    = sft->max_chardef_tables;
  236.     s->screen_driver    = (GraphicsDriver) graphdrvr;
  237.     s->screen_type        = (GraphicsMode) graphmode;   /* vbs->mode*/
  238.  
  239.     getaspectratio(&xasp, &yasp);    /* read the hardware aspect    */
  240.     s->screen_aspect    = (double) xasp / (double) yasp;
  241.  
  242.     s->screen_colors    = getmaxcolor()+1; /* max # of colors    */
  243.  
  244.     getpalette(&s->palette);    /* read the palette from board    */
  245.  
  246.     free(vbs);
  247.     free(sft);
  248.  
  249.     }
  250.     return graphdrvr;
  251. }
  252.  
  253.  
  254. /************************************************************************
  255. ** getScreenModes()
  256. **
  257. **    Returns a subset of the variables returned by getGraphicsModes().
  258. **
  259. **    Frankly, the only reason for this routine is that, in text mode
  260. ** on this Dell 433/M machine, the call to Borland's getcolor()
  261. ** causes and immediate exit, returning an error code of 255.  This
  262. ** doesn't happen when a program first changes to a graphics mode.
  263. **
  264. **    Be sure to heed the relevant warnings in getGraphicsModes().
  265. **
  266. **    Because this is really meant for text-mode usage (although we do
  267. ** not enforce that restriction), all the graphics parameters are
  268. ** zero'd, unless they "apply" to text-mode.
  269. **
  270. **    Of course, we don't bother with color calls here.
  271. **
  272. *************************************************************************/
  273.  
  274. GraphicsDriver
  275. getScreenModes
  276. (
  277.     Screen *s
  278. )
  279. {
  280.     union REGS regs;
  281.     int graphdrvr = (int) DETECT;    /* start with auto-detection    */
  282.     int graphmode = (int) VGALO;    /* start with a "zero" value    */
  283.     int *gd = &graphdrvr;        /* detectgraph (if 0) or driver    */
  284.     int *gm = &graphmode;        /* if not zero, graphics mode    */
  285.     int errcode = DETECT;        /* here, zero is an error!    */
  286.  
  287.     detectgraph(gd, gm);            /* find basic fact    */
  288.     if (graphresult() != grOk)            /* no graphics hardware    */
  289.     {
  290.     return errcode;
  291.     }
  292.  
  293.     if (s != NULL)
  294.     {
  295.     /****************************************************************
  296.     ** Allocate the following two structures, and make sure that
  297.     ** the SFT member of *vbs points to *sft.  Be very rigorous
  298.     ** about error-checking.
  299.     *****************************************************************/
  300.  
  301.     Static_Function_Table *sft;
  302.     Video_BIOS_State *vbs;
  303.  
  304.     sft = (Static_Function_Table *) malloc(sizeof(Static_Function_Table));
  305.     if (sft == NULL)
  306.         return errcode;
  307.  
  308.     vbs = (Video_BIOS_State *) malloc(sizeof(Video_BIOS_State));
  309.     if (vbs == NULL)
  310.     {
  311.         free(sft);
  312.         return errcode;
  313.     }
  314.     else
  315.     {
  316.         vbs->SFT = sft;
  317.     }
  318.  
  319.     regs.h.ah = VIDEO_STATUS;
  320.     int86(VIDEO_BIOS, ®s, ®s);
  321.     s->screen_mode      = (int) regs.h.al;    /* get the mode        */
  322.     s->screen_page      = (int) regs.h.bh;    /* get the video page    */
  323.     s->screen_columns = (int) regs.h.ah;    /* width in characters    */
  324.  
  325.  
  326.     /****************************************************************
  327.     ** Instead of the following, we use the getvbs() routine below:
  328.     **
  329.     ** s->cursor_start_line    = regs.h.cl;
  330.     ** s->cursor_end_line    = regs.h.ch;
  331.     **
  332.     *****************************************************************/
  333.  
  334.     (void) getvbs(vbs);            /* state of video BIOS    */
  335.  
  336.     s->cursor_start_line    = vbs->cursor_start_line;
  337.     s->cursor_end_line    = vbs->cursor_end_line;
  338.  
  339.     if (s->screen_columns != vbs->character_columns)
  340.     {
  341.         printf("Screen column mismatch!\n");
  342.         return errcode;
  343.     }
  344.     s->screen_rows        = vbs->number_of_rows;
  345.     s->screen_gmax_x    = getmaxx();    /* pixel width        */
  346.     s->screen_gmax_y    = getmaxy();    /* pixel height        */
  347.     s->screen_attribute    = 0;        /* was 'getcolor()'    */
  348.     s->screen_backattribute    = 0;        /* was 'getbkcolor()'    */
  349.  
  350.     s->screen_rasters    = 0;
  351.     s->screen_charsets    = 0;
  352.     s->screen_chardefs    = 0;
  353.     s->screen_driver    = 0;
  354.     s->screen_type        = 0;
  355.  
  356.     /****************************************************************
  357.     ** Not used here...
  358.     **
  359.     ** getaspectratio(&xasp, &yasp);
  360.     ** s->screen_aspect    = (double) xasp / (double) yasp;
  361.     ** s->screen_colors    = getmaxcolor()+1;
  362.     ** getpalette(&s->palette);    // read the palette from board    //
  363.     **
  364.     *****************************************************************/
  365.  
  366.     s->screen_aspect    = 0;
  367.     s->screen_colors    = 0;
  368.  
  369.     free(vbs);
  370.     free(sft);
  371.  
  372.     }
  373.     return graphdrvr;
  374. }
  375.  
  376.  
  377. /************************************************************************
  378. ** getScreenVBS()
  379. **
  380. **    A routine to get the video BIOS state into the appropriate
  381. ** elements of the Screen structure.
  382. **
  383. ************************************************************************/
  384.  
  385. void
  386. getScreenVBS
  387. (
  388.     Screen *s
  389. )
  390. {
  391.     if (s != NULL)
  392.     {
  393.     Static_Function_Table *sft;
  394.     Video_BIOS_State *vbs;
  395.  
  396.     sft = (Static_Function_Table *) malloc(sizeof(Static_Function_Table));
  397.     if (sft == NULL)
  398.     {
  399.         s->error_code = 1;
  400.         return;
  401.     }
  402.  
  403.     vbs = (Video_BIOS_State *) malloc(sizeof(Video_BIOS_State));
  404.     if (vbs == NULL)
  405.     {
  406.         free(sft);
  407.         s->error_code = 2;
  408.         return;
  409.     }
  410.     else
  411.     {
  412.         vbs->SFT = sft;
  413.     }
  414.  
  415.     (void) getvbs(vbs);            /* state of video BIOS    */
  416.  
  417.     s->cursor_start_line    = vbs->cursor_start_line;
  418.     s->cursor_end_line    = vbs->cursor_end_line;
  419.     s->screen_rows        = vbs->number_of_rows;
  420.     s->screen_rasters    = sft->raster_lines_supported;
  421.     s->screen_charsets    = sft->max_character_sets;
  422.     s->screen_chardefs    = sft->max_chardef_tables;
  423.  
  424.     free(vbs);
  425.     free(sft);
  426.     }
  427. }
  428.  
  429.  
  430. /************************************************************************
  431. ** getvbs()
  432. **
  433. **    A routine to get the "video BIOS state".  See bios_vid.h for
  434. ** complete details.
  435. **
  436. ** Input:
  437. **
  438. **    AH    27
  439. **    BX    implementation type (must be 0)
  440. **    ES:DI    address of 64-Byte buffer
  441. **
  442. ** Output:
  443. **
  444. **    AL    = 0x1B
  445. **    ES:DI    buffer updated with function and state information
  446. **
  447. ************************************************************************/
  448.  
  449. int
  450. getvbs
  451. (
  452.     Video_BIOS_State *vbs
  453. )
  454. {
  455.     union REGS regs;
  456.     struct SREGS sregs;
  457.  
  458.     regs.h.ah    = VIDEO_BIOS_STATE;
  459.     regs.x.bx    = 0;
  460.     sregs.es    = FP_SEG(vbs);
  461.     regs.x.di    = FP_OFF(vbs);
  462.     int86x(VIDEO_BIOS, ®s, ®s, &sregs);
  463.  
  464.     return (regs.h.al != 0x1B);    /* 0 if normal operation occurred    */
  465. }
  466.  
  467.  
  468. /************************************************************************
  469. ** getvbsdump()
  470. **
  471. **    Allocate the following two structures, get them filled,
  472. ** and dump (to a file called "GRAFXVBS.TXT") the current state
  473. ** of the video adapter.
  474. **
  475. *************************************************************************/
  476.  
  477. void
  478. getvbsdump (void)
  479. {
  480.     FILE *f;
  481.     Static_Function_Table *sft;
  482.     Video_BIOS_State *vbs;
  483.  
  484.     sft = (Static_Function_Table *) malloc(sizeof(Static_Function_Table));
  485.     if (sft != NULL)
  486.     {
  487.     vbs = (Video_BIOS_State *) malloc(sizeof(Video_BIOS_State));
  488.     if (vbs == NULL)
  489.     {
  490.         free(sft);
  491.     }
  492.     else
  493.     {
  494.         vbs->SFT = sft;
  495.         f = fopen("GRAFXVBS.TXT", "a");
  496.         if (f == NULL)
  497.         {
  498.         free(sft);
  499.         free(vbs);
  500.         }
  501.         else
  502.         {
  503.         (void) getvbs(vbs);    /* state of the video BIOS    */
  504.         dumpvbs(f, vbs);
  505.         fclose(f);
  506.         }
  507.     }
  508.     free(vbs);
  509.     free(sft);
  510.     }
  511. }
  512.  
  513.  
  514. /************************************************************************
  515. ** dumpvbs()
  516. **
  517. **    Does the actual dumping to a file.  Assumes everything's
  518. ** been setup ok.
  519. **
  520. *************************************************************************/
  521.  
  522. #define P    fprintf
  523.  
  524. void
  525. dumpvbs
  526. (
  527.     FILE *f,
  528.     Video_BIOS_State *vbs
  529. )
  530. {
  531.     Static_Function_Table *sft;
  532.  
  533.     sft = vbs->SFT;
  534.  
  535.     P
  536.     (
  537.         f,
  538.         "\n\n===============================================\n\n"
  539.         "Video Bios Table\n"
  540.         "----------------\n\n"
  541.     );
  542.  
  543.     P(f, "Static_Func_Tbl *SFT    = %p\n", vbs->SFT);
  544.     P(f, "Byte mode        = 0x%x\n", (unsigned)vbs->mode);
  545.     P(f, "Word char_columns    = 0x%x\n", vbs->character_columns);
  546.     P(f, "Word buff_disp_length    = 0x%x\n", vbs->buffer_displayed_length);
  547.     P(f, "Word buff_start        = 0x%x\n", vbs->buffer_start);
  548.     /****P(f, "Cursor_Coordinate cursor[8]= 0x%x\n", vbs->);****/
  549.     P(f, "Byte cursor_end_line    = 0x%x\n", (unsigned)vbs->cursor_end_line);
  550.     P(f, "Byte cursor_start    = 0x%x\n", (unsigned)vbs->cursor_start_line);
  551.     P(f, "Byte active_vid_page    = 0x%x\n", (unsigned)vbs->active_video_page);
  552.     P(f, "Word CRTC_IO_port    = 0x%x\n", vbs->CRTC_IO_port);
  553.     P(f, "Byte crt_mode_set    = 0x%x\n", (unsigned)vbs->crt_mode_set);
  554.     P(f, "Byte crt_palette    = 0x%x\n", (unsigned)vbs->crt_palette);
  555.     P(f, "Byte number_of_rows    = 0x%x\n", (unsigned)vbs->number_of_rows);
  556.     P(f, "Word points_in_character= 0x%x\n", vbs->points_in_character);
  557.     P(f, "Byte active_display    = 0x%x\n", (unsigned)vbs->active_display);
  558.     P(f, "Byte inactive_display    = 0x%x\n", (unsigned)vbs->inactive_display);
  559.     P(f, "Word colors_in_display    = 0x%x\n", vbs->colors_in_display);
  560.     P(f, "Byte pages_supported    = 0x%x\n", (unsigned)vbs->pages_supported);
  561.     P(f, "Byte raster_lines    = 0x%x\n", (unsigned)vbs->raster_lines);
  562.     P(f, "Byte alpha_table_0    = 0x%x\n", (unsigned)vbs->alpha_table_0);
  563.     P(f, "Byte alpha_table_1    = 0x%x\n", (unsigned)vbs->alpha_table_1);
  564.     P(f, "Byte misc_state        = 0x%x\n", (unsigned)vbs->misc_state);
  565.     /****P(f, "Byte reserved[3]    = 0x%x\n", (unsigned)vbs->);****/
  566.     P(f, "Byte video_RAM_size    = 0x%x\n", (unsigned)vbs->video_RAM_size);
  567.     P(f, "Byte save_area_status    = 0x%x\n", (unsigned)vbs->save_area_status);
  568.  
  569.     P
  570.     (
  571.         f,
  572.         "\nStatic Function Table\n"
  573.         "---------------------\n\n"
  574.     );
  575.     P
  576.     (
  577.     f,
  578.     "Byte vmodes_support[3]    = 0x%x %x %x\n",
  579.     (unsigned) sft->vmodes_supported[0],
  580.     (unsigned) sft->vmodes_supported[1],
  581.     (unsigned) sft->vmodes_supported[2]
  582.     );
  583.     P
  584.     (
  585.     f,
  586.     "Byte sft_reserved[4]    = 0x%x %x %x %x\n",
  587.     (unsigned) sft->sft_reserved[0],
  588.     (unsigned) sft->sft_reserved[1],
  589.     (unsigned) sft->sft_reserved[2],
  590.     (unsigned) sft->sft_reserved[3]
  591.     );
  592.     P(f, "Byte raster_lines_sup    = 0x%x\n",(unsigned)sft->raster_lines_supported);
  593.     P(f, "Byte max_char_sets    = 0x%x\n", (unsigned)sft->max_character_sets);
  594.     P(f, "Byte max_chardef_tbls    = 0x%x\n", (unsigned)sft->max_chardef_tables);
  595.     P(f, "Byte misc_abilities    = 0x%x\n", (unsigned)sft->misc_abilities);
  596.     P(f, "Byte misc_BIOS_abil    = 0x%x\n", (unsigned)sft->misc_BIOS_abilities);
  597.     P
  598.     (
  599.     f,
  600.     "Byte sft_reverved_2[2]    = 0x%x %x\n",
  601.     (unsigned)sft->sft_reverved_2[0],
  602.     (unsigned)sft->sft_reverved_2[1]
  603.     );
  604.     P(f, "Byte save_area_abil    = 0x%x\n", (unsigned)sft->save_area_abilities);
  605.     P(f, "Byte sft_reserved_3    = 0x%x\n", (unsigned)sft->sft_reserved_3);
  606. }
  607.  
  608.  
  609. /************************************************************************
  610. ** showScreen
  611. **
  612. **    A procedure to display some video parameters; mainly a tool
  613. ** for debugging.
  614. **
  615. **    Note that we must bring graphics up in order to get the
  616. ** non-zero values of the screen dimensions in units of pixels.
  617. **
  618. *************************************************************************/
  619.  
  620. void
  621. showScreen
  622. (
  623.     Screen *s
  624. )
  625. {
  626.     if (s != NULL)
  627.     {
  628.     printf
  629.     (
  630.         "\tVideo driver type\t: %3d (%s)\n"
  631.         "\tVideo driver mode\t: %3d\n"
  632.         "\tRaster lines supported\t: %3d\n"
  633.         "\tMaximum character sets\t: %3d\n"
  634.         "\tMaximum chardef tables\t: %3d\n",
  635.  
  636.         s->screen_driver, s->screen_driver_name,
  637.         s->screen_type,
  638.         s->screen_rasters,
  639.         s->screen_charsets,
  640.         s->screen_chardefs
  641.     );
  642.  
  643.     printf
  644.     (
  645.         "\tVideo mode\t\t: %3d\n"
  646.         "\tVideo page\t\t: %3d\n"
  647.         "\tVideo columns\t\t: %3d\n"
  648.         "\tVideo rows\t\t: %3d\n"
  649.         "\tHorizontal pixels\t: %3d\n"
  650.         "\tVertical pixels\t\t: %3d\n",
  651.  
  652.         s->screen_mode,
  653.         s->screen_page,
  654.         s->screen_columns,
  655.         s->screen_rows,
  656.         s->screen_gmax_x,
  657.         s->screen_gmax_y
  658.     );
  659.  
  660.     printf
  661.     (
  662.         "\tForeground color\t: %3d\n"
  663.         "\tBackground color\t: %3d\n"
  664.         "\tCursor start line\t: %3d\n"
  665.         "\tCursor end line\t\t: %3d\n",
  666.  
  667.         s->screen_attribute,
  668.         s->screen_backattribute,
  669.         s->cursor_start_line,
  670.         s->cursor_end_line
  671.     ); 
  672.  
  673.     puts("Hit any key to exit...");
  674.     KBHIT;
  675.     }
  676.     else
  677.     {
  678.     printf("Need a non-null Screen pointer.\n");
  679.     }
  680. }
  681.  
  682. /************************************************************************
  683. ** Typical results for various systems:
  684. **
  685. ** Easy way:               EGA    VGA  VGA
  686. **                        (1)  (2)
  687. **
  688. **    Video mode        =    3    3    3
  689. **    Video page        =    0    0    0
  690. **    Video width        =   80   80   80
  691. **
  692. ** Hard way:
  693. **
  694. **    Video driver type    :    3    9    9
  695. **    Video driver mode    :    1    2    2
  696. **    Raster lines supported    :    0    0    0
  697. **    Maximum character sets    :    0    0    0
  698. **    Maximum chardef tables    :    0    0    0
  699. **    Video mode        :    3    3    3
  700. **    Video page        :    0    0    0
  701. **    Video columns        :    0   80   80
  702. **    Video rows        :    0   25   50
  703. **    Horizontal pixels    :  639  639  639
  704. **    Vertical pixels        :  349  479  479
  705. **    Cursor start line    :    0   13    6
  706. **    Cursor end line        :    0   14    7
  707. **
  708. ** Notes:
  709. **
  710. **    (1) 25-line mode;
  711. **    (2) 50-line mode;
  712. **
  713. *************************************************************************/
  714.  
  715.  
  716. /************************************************************************
  717. ** getScreenContext()
  718. **
  719. **    Similar in idea to getGraphicsModes(), but obtains the
  720. ** information solely via Borland BGI facilities.
  721. **
  722. **    The purpose of this routine is to store all necessary information
  723. ** about the current adapter before switching to another one.
  724. **
  725. *************************************************************************/
  726.  
  727. int
  728. getScreenContext
  729. (
  730.     Screen *s
  731. )
  732. {
  733.     int graphdrvr = (int) DETECT;    /* start with auto-detection    */
  734.     int graphmode = (int) VGALO;    /* start with a "zero" value    */
  735.     int *gd = &graphdrvr;        /* detectgraph (if 0) or driver    */
  736.     int *gm = &graphmode;        /* if not zero, graphics mode    */
  737.     int xasp, yasp;            /* for reading aspect ratio    */
  738.     int errcode = DETECT;        /* here, zero is an error!    */
  739.  
  740.     detectgraph(gd, gm);        /* check graphics hardware    */
  741.     errcode = graphresult();        /* check graphics hardware code    */
  742.  
  743.     if (s != NULL)
  744.     {
  745.     if (s->adapter != ADAPTER_INACTIVE)
  746.     {
  747.         s->screen_type        = (GraphicsMode) getgraphmode();
  748.         s->screen_driver        = (GraphicsDriver) graphdrvr;
  749.         s->screen_mode        = getgrafxmode();
  750.         s->screen_page        = getgrafxpage();
  751.         s->screen_attribute        = getcolor();
  752.         s->screen_backattribute    = getbkcolor();
  753.         s->screen_columns        = getgrafxcolumns();
  754.         s->screen_gmax_x        = getmaxx();
  755.         s->screen_gmax_y        = getmaxy();
  756.         s->cursor_column        = getx();
  757.         s->cursor_row        = gety();
  758.         s->screen_colors        = getmaxcolor() + 1;
  759.  
  760.         getaspectratio(&xasp, &yasp);
  761.         s->screen_aspect        = (double) xasp / (double) yasp;
  762.  
  763.         getpalette(&s->palette);
  764.  
  765.         s->error_code        = errcode;
  766.         s->screen_driver_name    = getdrivername();
  767.  
  768.         getScreenVBS(s);            /* get all the rest    */
  769.     }
  770.     }
  771.     return s->error_code;
  772. }
  773.  
  774.  
  775. /************************************************************************
  776. ** setScreenContext()
  777. **
  778. **    Similar in idea to setGraphicsModes(), but sets the
  779. ** information solely via Borland BGI facilities.
  780. **
  781. **    The purpose of this routine is to recover all information
  782. ** about the new adapter after switching from another one.
  783. **
  784. *************************************************************************/
  785.  
  786. void
  787. setScreenContext
  788. (
  789.     Screen *s
  790. )
  791. {
  792.     int graphdrvr = (int) DETECT;    /* start with auto-detection    */
  793.     int graphmode = (int) VGALO;    /* start with a "zero" value    */
  794.     int *gd = &graphdrvr;        /* detectgraph (if 0) or driver    */
  795.     int *gm = &graphmode;        /* if not zero, graphics mode    */
  796.     int errcode = DETECT;        /* here, zero is an error!    */
  797.  
  798.     detectgraph(gd, gm);        /* check graphics hardware    */
  799.     errcode = graphresult();        /* check graphics hardware code    */
  800.  
  801.     if (s != NULL)
  802.     {
  803.     if (s->adapter != ADAPTER_INACTIVE)
  804.     {
  805.         setgraphmode((int) s->screen_type);
  806.         s->screen_driver        = (GraphicsDriver) graphdrvr;
  807.         s->screen_mode        = getgrafxmode();
  808.         s->screen_page        = getgrafxpage();
  809.         setcolor(s->screen_attribute);
  810.         setbkcolor(s->screen_backattribute);
  811.         s->screen_columns        = getgrafxcolumns();
  812.         s->screen_gmax_x        = getmaxx();
  813.         s->screen_gmax_y        = getmaxy();
  814.         s->cursor_column        = getgrafxcursorcolumn(s->screen_page);
  815.         s->cursor_row        = getgrafxcursorrow(s->screen_page);
  816.         s->screen_colors        = getmaxcolor() + 1;
  817.  
  818.         getpalette(&s->palette);
  819.  
  820.         s->error_code        = errcode;
  821.         s->screen_driver_name    = getdrivername();
  822.  
  823.         getScreenVBS(s);            /* get all the rest    */
  824.     }
  825.     }
  826. }
  827.  
  828.  
  829. /************************************************************************
  830. ** getgrafxmode()
  831. **
  832. **    Not sure if this is different from Borland's getgraphmode(),
  833. ** but it get the mode directly from the BIOS.
  834. **
  835. ** getgrafxpage()
  836. **
  837. **    Gets the page number directly from the hardware.
  838. **
  839. ** getgrafxcolumns()
  840. **
  841. **    Gets the number of columns directly from the hardware.
  842. **
  843. *************************************************************************/
  844.  
  845. int
  846. getgrafxmode (void)
  847. {
  848.     union REGS regs;
  849.  
  850.     regs.h.ah = VIDEO_STATUS;
  851.     int86(VIDEO_BIOS, ®s, ®s);
  852.     return (int) regs.h.al;
  853. }
  854.  
  855. int
  856. getgrafxpage (void)
  857. {
  858.     union REGS regs;
  859.  
  860.     regs.h.ah = VIDEO_STATUS;
  861.     int86(VIDEO_BIOS, ®s, ®s);
  862.     return (int) regs.h.bh;
  863. }
  864.  
  865. int
  866. getgrafxcolumns (void)
  867. {
  868.     union REGS regs;
  869.  
  870.     regs.h.ah = VIDEO_STATUS;
  871.     int86(VIDEO_BIOS, ®s, ®s);
  872.     return (int) regs.h.ah;
  873. }
  874.  
  875. int
  876. getgrafxcursorrow            /* similar to BGI's gety()    */
  877. (
  878.     int page
  879. )
  880. {
  881.     union REGS regs;
  882.  
  883.     regs.h.ah = VIDEO_READ_CURSOR;
  884.     regs.h.bh = page;            /* get the video page    */
  885.     int86(VIDEO_BIOS, ®s, ®s);    /* get cursor position    */
  886.     return (int) regs.h.dh;
  887. }
  888.  
  889. int
  890. getgrafxcursorcolumn            /* similar to BGI's getx()    */
  891. (
  892.     int page
  893. )
  894. {
  895.     union REGS regs;
  896.  
  897.     regs.h.ah = VIDEO_READ_CURSOR;
  898.     regs.h.bh = page;            /* get the video page    */
  899.     int86(VIDEO_BIOS, ®s, ®s);    /* get cursor position    */
  900.     return (int) regs.h.dl;
  901. }
  902.  
  903.  
  904.  
  905. static char bgiPath[] = "C:\BC\BGI";    /* we'll use env variables later*/
  906.  
  907. int
  908. initGraphics
  909. (
  910.     Screen *s                /* all screen parameters    */
  911. )
  912. {
  913.     int errcode = 0;            /* return code for errors    */
  914.     char *bgi_path = &bgiPath[0];    /* path to find BGI support    */
  915.     int *gm, *gd;            /* for initgraph()        */
  916.     int gdriver = DETECT;
  917.     int gmode;
  918.  
  919.     gd = (int *) &gdriver;
  920.     gm = (int *) &gmode;
  921.     initgraph(gd, gm, bgi_path);
  922.     s->error_code = graphresult();        /* result of initialize    */
  923.     if (s->error_code != grOk)        /* init error occurred    */
  924.     {
  925.     printf
  926.     (
  927.         "%%Graphics error: %s, current adapter\n",
  928.         grapherrormsg(s->error_code) 
  929.     );
  930.     errcode = 1;
  931.     }
  932.     return errcode;
  933. }
  934.  
  935. void
  936. closeGraphics
  937. (
  938.     Screen *s                /* all screen parameters    */
  939. )
  940. {
  941.     closegraph();
  942.     s->adapter = ADAPTER_INACTIVE;    /* ???    */
  943. }
  944.