home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / STK100.ZIP / STKSRC.COM / GR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-20  |  10.0 KB  |  334 lines

  1. /**********************************************************************
  2. * gr.c
  3. *
  4. * Support routines for graphics mode.
  5. **********************************************************************
  6.                     This file is part of
  7.  
  8.          STK -- The sprite toolkit -- version 1.0
  9.  
  10.               Copyright (C) Jari Karjala 1990
  11.  
  12. The sprite toolkit (STK) is a FreeWare toolkit for creating high
  13. resolution sprite graphics with PCompatible hardware. This toolkit 
  14. is provided as is without any warranty or such thing. See the file
  15. COPYING for further information.
  16.  
  17. **********************************************************************/
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <stdarg.h>
  22. #include <string.h>
  23. #include <signal.h>
  24. #include <conio.h>
  25. #include <graphics.h>
  26. #include <dos.h>
  27.  
  28. #include "gr.h"
  29. #include "gr_int9.h"
  30.  
  31. /**********************************************************************
  32. * The maximum coordinate values 
  33. **********************************************************************/
  34. int gr_max_x;
  35. int gr_max_y;
  36.  
  37. int gr_text_mode = GR_MODE_CLEAR;
  38.  
  39.  
  40.  
  41. /**********************************************************************
  42. * Detect the graphics card and mode of the system.
  43. * The type parameter can be used to specify special requests (see above).
  44. * graphdriver and graphmode parameters are returned. They contain -1
  45. * if some error occured (cannot find requested mode, etc)
  46. **********************************************************************/
  47. void gr_detect(int type, int *graphdriver, int *graphmode)
  48. {
  49.     detectgraph(graphdriver, graphmode);
  50.     
  51.     switch (type) {
  52.         case GR_TYPE_ANY:
  53.             break;
  54.         case GR_TYPE_SPR:
  55.             if (*graphdriver==EGA || *graphdriver==VGA) {
  56.                 *graphdriver = EGAMONO;
  57.                 *graphmode = EGAMONOHI;
  58.             }
  59.             else if (*graphdriver!=HERCMONO) {
  60.                 *graphdriver = *graphmode = -1;
  61.             }
  62.             break;
  63.         default:
  64.             break;
  65.     }
  66. }
  67.  
  68.  
  69. /***************************************************************************
  70. * Called at the end of the program
  71. ***************************************************************************/
  72. void gr_end(void)
  73. {
  74.     closegraph();
  75. }
  76.  
  77. /***************************************************************************
  78. * Initializes the graphics system. Search BGI drivers from the path defined
  79. * in the enviroment variable BGIDIR or current directory. Set videomode
  80. * into the BIOS are to fool mouse drivers with Hercules graphics.
  81. * Set gr_end at exit and ctrl-C.
  82. * Terminate with error message if initialization fails.
  83. *
  84. * graphdriver   pointer to the driver ID (or DETECT)
  85. * graphmode     pointer to the mode ID
  86. ***************************************************************************/
  87. void gr_start(int *graphdriver, int *graphmode)
  88. {
  89.   int ErrorCode;
  90.   char *bgidir;
  91.   unsigned char far *Mode = (unsigned char far *)MK_FP(0x40, 0x49);
  92.  
  93.   if ((bgidir=getenv("BGIDIR"))==NULL)  /* Find BGIs in other dirs also */
  94.       bgidir="";
  95.  
  96.   initgraph( graphdriver, graphmode, bgidir);
  97.   ErrorCode = graphresult();            /* Read result of initialization*/
  98.   if( ErrorCode != grOk ){              /* Error occured during init    */
  99.     printf(" Graphics System Error: %s\n", grapherrormsg( ErrorCode ) );
  100.     exit( 1 );
  101.   }
  102.   
  103.   if (*graphdriver == HERCMONO)         /* Just to fool mouse drivers */
  104.      *Mode = 6;
  105.  
  106.   signal(SIGINT, gr_end);          /* Back to text when user break */
  107.   atexit(gr_end);                  /* Back to text when end-of-pgm */
  108.   
  109.   gr_max_x = getmaxx();
  110.   gr_max_y = getmaxy();
  111.  
  112. }
  113.  
  114.  
  115. /***************************************************************************
  116. * Output one character at the current cursor location, advance cursor.
  117. * Understands \n and \r correctly (no scrolling, though)
  118. ***************************************************************************/
  119. void gr_putch(char ch)
  120. {
  121.     static char buf[2] = "?";
  122.     
  123.     buf[0]=ch;
  124.  
  125.     switch (ch) {
  126.         case '\n':
  127.             moveto(0, gety()+textheight(buf));
  128.             break;
  129.         case '\r':
  130.             moveto(0, gety());
  131.             break;
  132.         default:
  133.             if (gr_text_mode == GR_MODE_CLEAR) {
  134.                 struct fillsettingstype fs;
  135.                 /** clear the background **/
  136.                 getfillsettings(&fs);
  137.                 setfillstyle(EMPTY_FILL,0);
  138.                 bar(getx(),gety(),
  139.                     getx()+textwidth(buf),gety()+textheight(buf));
  140.                 setfillstyle(fs.pattern, fs.color);
  141.             }
  142.             outtext(buf);
  143.             if (getx() > getmaxx())
  144.                 moveto(0, gety()+textheight(buf));
  145.     }
  146. }
  147.  
  148. /***************************************************************************
  149. * Output the given string.
  150. ***************************************************************************/
  151. void gr_puts(char *s)
  152. {
  153.     while(*s)
  154.         gr_putch(*s++); 
  155.     
  156.     gr_putch('\n');
  157. }
  158.  
  159.  
  160. /***************************************************************************
  161. * As printf, but in the graphics mode.
  162. ***************************************************************************/
  163. void gr_printf(char *s,...)
  164. {
  165.     char buf[100];
  166.     va_list argptr;
  167.  
  168.     va_start(argptr,100);
  169.     vsprintf(buf,s,argptr);
  170.     va_end(argptr);
  171.     gr_puts(buf);
  172. }
  173.  
  174. /**********************************************************************
  175. * Print text at the given position. (x and y in pixels) 
  176. **********************************************************************/
  177. void gr_xy_printf(int x, int y, char *s,...)
  178. {
  179.     char buf[100];
  180.     va_list argptr;
  181.  
  182.     va_start(argptr,100);
  183.     vsprintf(buf,s,argptr);
  184.     va_end(argptr);
  185.  
  186.     moveto(x,y);
  187.     gr_puts(buf);
  188. }
  189.  
  190. /**********************************************************************
  191. * Print text into both graphics pages at the given position.
  192. * (x and y in pixels) Page 0 is left active.
  193. **********************************************************************/
  194. void gr_dual_xy_printf(int x, int y, char *s,...)
  195. {
  196.     char buf[100];
  197.     va_list argptr;
  198.  
  199.     va_start(argptr,100);
  200.     vsprintf(buf,s,argptr);
  201.     va_end(argptr);
  202.  
  203.     setactivepage(1);
  204.     moveto(x,y);
  205.     gr_puts(buf);
  206.     
  207.     setactivepage(0);
  208.     moveto(x,y);
  209.     gr_puts(buf);
  210. }
  211.  
  212. /**********************************************************************
  213. * Read a string from screen in graphics mode (at most max_len<80 chrs)
  214. * Backspace deletes characters, Esc returns a null pointer.
  215. **********************************************************************/
  216. char *gr_gets(char *cpdest, int max_len)
  217. {
  218.     char buf[80], buf2[2]=" ", *cp=buf, ch;
  219.     int quit = 0;
  220.     struct fillsettingstype fs;
  221.     /** clear the old char **/
  222.     getfillsettings(&fs);
  223.     setfillstyle(EMPTY_FILL,0);
  224.     
  225.     while (!quit) {
  226.         gr_putch('_');
  227.         ch=getch();
  228.         /** remove underline **/
  229.         buf2[0] = '_';
  230.         bar(getx()-textwidth(buf2), gety(),
  231.             getx(), gety()+textheight(buf2));
  232.         moveto(getx()-textwidth(buf2),gety());
  233.         
  234.         switch (ch) {
  235.             case 8:     /** backspace **/
  236.                 if (cp>buf) {
  237.                     cp--;
  238.                     buf2[0] = *cp;
  239.                     bar(getx()-textwidth(buf2), gety(),
  240.                         getx(), gety()+textheight(buf2));
  241.                     moveto(getx()-textwidth(buf2),gety());
  242.                 }
  243.                 break;
  244.                 
  245.             case 13:    /** enter **/
  246.                 quit = 1;
  247.                 break;
  248.                 
  249.             case 27:    /** esc **/
  250.                 cp = NULL;
  251.                 quit = 1;
  252.                 break;
  253.                 
  254.             default:
  255.                 if (cp < buf+max_len-1) {
  256.                     gr_putch(ch);
  257.                     *cp++ = ch;
  258.                 }
  259.         }
  260.     }
  261.     
  262.     setfillstyle(fs.pattern, fs.color);
  263.     if (cp==NULL)
  264.         return NULL;
  265.     *cp++ = '\0';
  266.     strcpy(cpdest, buf);
  267.     return cpdest;
  268. }
  269.  
  270. /**********************************************************************
  271. * Return a keypress if one pending, otherwise 0.
  272. * Extended codes contain 0 in the low byte.
  273. *
  274. * Automatic key repeat disabled by setting kbd buffer head and tail
  275. * equal. If someone knows a better solution, I would like to hear
  276. * about it.
  277. **********************************************************************/
  278. int gr_inkey(void)
  279. {
  280.     unsigned int far *fptail, far *fphead;
  281.     int c;
  282.     
  283.     c = 0;
  284.     fptail = MK_FP(0x40,0x1A);
  285.     fphead = MK_FP(0x40,0x1C);
  286.     
  287.     disable();
  288.     if (*fptail!=*fphead) {   /** there were a keypress **/
  289.         c = getch();
  290.         if (!c)     /** extended code (F-keys, cursor keys etc) **/
  291.             c = getch() << 8;
  292.         *fptail = *fphead;
  293.     }
  294.     enable();
  295.     
  296.     return c;
  297. }
  298.  
  299.  
  300. /**********************************************************************
  301. * Array of booleans for each key of the keyboard (indexed by the scan
  302. * code value). Non-zero if key pressed, zero otherwise.
  303. * The array is updated during the kbd_grab, see the function 
  304. * gr_start_kbd_grab below.
  305. **********************************************************************/
  306. char gr_keys[128];
  307.  
  308. /**********************************************************************
  309. * Restore the original keyboard handler
  310. **********************************************************************/
  311. void gr_end_kbd_grab(void)
  312. {
  313.     setvect(9, gr_old_int9);    
  314. }
  315.  
  316. /**********************************************************************
  317. * Set a new handler for the keyboard. This handler sets and resets
  318. * the gr_keys array values for each scancode received, flushes the
  319. * keyboard buffer and then calls the original handler.
  320. **********************************************************************/
  321. void gr_start_kbd_grab(void)
  322. {
  323.     static int first_time = 1;
  324.     
  325.     gr_old_int9 = getvect(9);
  326.     memset(gr_keys, 0, sizeof(gr_keys));
  327.     setvect(9, gr_int9);
  328.     if (first_time) {
  329.         atexit(gr_end_kbd_grab);
  330.         first_time = 0;
  331.     }
  332. }
  333.  
  334.