home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / IRIT / DRAWFN3S.ZIP / GRAPHGEN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-06  |  39.0 KB  |  1,241 lines

  1. /*****************************************************************************
  2. *   General routines to    handle the graphic calls.                 *
  3. *                                         *
  4. * Written by:  Gershon Elber                   Ver 0.9, Apr. 1989    *
  5. *                                         *
  6. * Support: Hercules, CGA, EGA/VGA graphic cards.                 *
  7. *                                         *
  8. * 0.3  modif. -    menus now can read alpha and compere to    first chars in menus.*
  9. * 0.32 modif. -    if erase of GGDrawMenu TRUE, simply clear area first.         *
  10. *        fix DrawPoint title drawing error...                 *
  11. *        fix set up color default (not to be black).             *
  12. * 0.4  modif. - MS mouse support added.                         *
  13. * 0.5  modif. - CGA support was added.                         *
  14. * 0.6  modif. - Prefix all functions/external vars with GG.             *
  15. *        Add window frame to view & status windows.             *
  16. * 0.7  modif. - Improving the shape of the graphical cursor.             *
  17. *        Disabling stdout during graphic mode to unshow ^c...         *
  18. * 0.8  modif. - Adding support for the EGA/VGA class of machines.         *
  19. * 0.9  modif. - Full line editing replaced old simplified version.         *
  20. * 1.0  modif. - Fix EGA/VGA type of devices aspect ratio.             *
  21. *****************************************************************************/
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <alloc.h>
  26. #include <dir.h>
  27. #include <dos.h>
  28. #include <mem.h>
  29. #include <math.h>
  30. #include <ctype.h>
  31. #include <graphics.h>
  32. #include <string.h>
  33. #include <io.h>
  34. #include <fcntl.h>
  35. #include <conio.h>
  36.  
  37. /* See also the conditional compilation flags in GraphGnG.h! */
  38.  
  39. #include "Program.h"
  40. #include "GraphGnG.h"
  41. #include "GraphGnL.h"
  42. #include "MouseDrv.h"
  43.  
  44. extern int MouseExists;                   /* Responsibility of program! */
  45. extern int GraphDriver;                               /* "" */
  46.  
  47. int    GGGraphMode;                 /* The Graphics mode value. */
  48. double GGAspectRatio;           /* Aspect ratio of a pixel on the screen. */
  49. int    GGScreenMaxX, GGScreenMaxY;  /* The maximum resolution of the screen. */
  50. int    GGScreenMaxY2;                      /* ScreenMaxY / 2. */
  51. int    GGScreenMaxColors;           /* The maximum # of colors available. */
  52. int    GGScreenMaxPages;            /* The maximum # of pages available. */
  53. int    GGScreenErrorCode;                 /* Reports any graphics errors. */
  54. int    GGCurrentCursorX, GGCurrentCursorY;       /* Cursor current position. */
  55. int    GGScreenGraphicMode = FALSE;   /* TRUE if the screen in graphic mode. */
  56.  
  57. static double WndwAspectRatio, GlblAspectRatio;
  58. static struct palettetype palette;            /* Used to read palette info. */
  59. static char *CursorImageBuffer;                    /* Cursor shape. */
  60. static int LocalMoveToX, LocalMoveToY;          /* Save last position we move. */
  61. static char LastGetChar;      /* Last char recieved in GGUpdateGetPoint. */
  62. static double MouseXRatio, MouseYRatio;
  63. static int DefaultFontSize, MenuLineWidth;    /* Depend on graphic driver. */
  64. static int ScreenCursorColor;        /* Graphic and text (in graphic screen). */
  65. static int ViewPortX, ViewPortY;    /* Viewport offset from top left (0, 0). */
  66. static int OldStdOut;    /* So we could recover it when exit from graph mode. */
  67. static int CurrentColor = 1;
  68.  
  69. #ifndef NOWINDOWS
  70.  
  71. typedef struct WindowStruct {                /* The window structure. */
  72.     double MinX, MaxX, MinY, MaxY;
  73.     int FrameColor, LineColor;
  74. } WindowStruct;
  75.  
  76. #define    FRAME_X_WIDTH 0.03              /* Width of the window frames. */
  77. #define FRAME_Y_WIDTH 0.03
  78.  
  79. static WindowStruct MenuWindow =                 /* Menu window. */
  80. {   SW_MIN_X, SW_MAX_X, SW_MIN_Y, SW_MAX_Y,
  81.     SW_FRAME_COLOR, SW_LINE_COLOR
  82. };
  83.  
  84. static WindowStruct ViewWindow =                 /* View window. */
  85. {   VW_MIN_X, VW_MAX_X, VW_MIN_Y, VW_MAX_Y,
  86.     VW_FRAME_COLOR, VW_LINE_COLOR
  87. };
  88.  
  89. static WindowStruct *WndwViewWindow, *WndwMenuWindow;
  90.  
  91. static void WndwDrawAllWndwFrames(void);
  92. static void WndwDrawWindowFrame(WindowStruct *Window);
  93. static void WndwSetUpAllWndws(void);
  94. static void WndwClearWindow(WindowStruct *Window);
  95. static void WndwSetViewPort(double XMin, double YMin, double XMax, double YMax);
  96.  
  97. #endif    NOWIDNOWS
  98.  
  99. #ifndef NOMENUS
  100.  
  101. static struct MenuItem *ActvMenu;    /* Last drawn menu (active menu...). */
  102. static int ActvMenuN, ActvMenuActive;            /* Info. on active menu. */
  103.  
  104. static void GGDrawMenuFrame(int n, int color);
  105. static void GGDrawMenuItems(int n, struct MenuItem m[], int *active);
  106.  
  107. #endif    NOMENUS
  108.  
  109. #ifndef NOHELP
  110.  
  111. static FILE *GGFindFile(char *FileName, char *Attribute);
  112. static void HelpUpdateY(double *Yaxis);
  113.  
  114. #endif    NOHELP
  115.  
  116. static int GGUpdateGetPointKbd(int *x, int *y);
  117. static int GGGetKey(void);
  118.  
  119. /****************************************************************************
  120. * Routine to move to a normalized point    between    -1..1 on both axes :        *
  121. ****************************************************************************/
  122. void GGMyMove(double x, double y)
  123. {
  124. #ifndef    NOGRAPHICS
  125.     /* Note I use ScreenMaxY2 as X>ScreenMaxY2 left for    text (menus). */
  126.     LocalMoveToX = (int) ((x * WndwAspectRatio * GGScreenMaxY2 + GGScreenMaxY2)
  127.                             * GlblAspectRatio);
  128.     LocalMoveToY = (int) (-y * GGScreenMaxY2 + GGScreenMaxY2);
  129.     moveto(LocalMoveToX - ViewPortX, LocalMoveToY - ViewPortY);
  130. #endif NOGRAPHICS
  131. }
  132.  
  133. /****************************************************************************
  134. * Routine to draw to a normalized point    between    -1..1 on both axes :        *
  135. ****************************************************************************/
  136. void GGMyDraw(double x, double y)
  137. {
  138. #ifndef    NOGRAPHICS
  139.     int    NewX, NewY;
  140.  
  141.     /* Note I use ScreenMaxY2 as X>ScreenMaxY2 left for    text (menus). */
  142.     NewX = (int) ((x * WndwAspectRatio * GGScreenMaxY2 + GGScreenMaxY2)
  143.                             * GlblAspectRatio);
  144.     NewY = (int) (-y * GGScreenMaxY2 + GGScreenMaxY2);
  145.     line(LocalMoveToX - ViewPortX, LocalMoveToY - ViewPortY,
  146.                     NewX - ViewPortX, NewY - ViewPortY);
  147.     LocalMoveToX = NewX;
  148.     LocalMoveToY = NewY;
  149. #endif NOGRAPHICS
  150. }
  151.  
  152. /****************************************************************************
  153. * Routine to draw to a normelized point    between    -1..1 on both axes :        *
  154. ****************************************************************************/
  155. void GGMySetColor(int Color)
  156. {
  157. #ifndef    NOGRAPHICS
  158.     if (Color >= GGScreenMaxColors)
  159.     Color = Color % (GGScreenMaxColors-1) + 1;
  160.     CurrentColor = Color;
  161.     setcolor(Color);
  162. #endif NOGRAPHICS
  163. }
  164.  
  165. /****************************************************************************
  166. * Routine to reset all the system to starting condition    :            *
  167. ****************************************************************************/
  168. void GGInitGraph(void)
  169. {
  170. #ifndef    NOGRAPHICS
  171.     int    xasp, yasp,               /* Used to read the aspect ratio. */
  172.     i, j;
  173.  
  174.     if (registerbgidriver(Herc_driver) < 0) MyExit(1);
  175.     if (registerbgidriver(CGA_driver) < 0) MyExit(1);
  176.     if (registerbgidriver(EGAVGA_driver) < 0) MyExit(1);
  177.  
  178.     /* For some wierd reason, some machines waits much more than expected on */
  179.     /* the first delay. Lets do it now, so people will consider it part of   */
  180.     /* the initialization (make it a feature...)...                          */
  181.     delay(1);
  182.  
  183.     if (GraphDriver == 0) {
  184.     /* Use autodetect feature of graphic library to see what we have. */
  185.     detectgraph(&GraphDriver, &GGGraphMode);
  186.     if (GraphDriver < 0) {
  187.         fprintf(stderr, "Auto detect: No graphics device detected\n");
  188.         MyExit(1);
  189.     }
  190.     }
  191.  
  192.     /* Put in the following any graphic driver specific setup: */
  193.     switch (GraphDriver) {
  194.     case CGA:
  195.         GGGraphMode = CGAHI;
  196.         break;
  197.     case EGA:
  198.         GGGraphMode = EGAHI;
  199.         break;
  200.     case EGA64:
  201.         GGGraphMode = EGA64HI;
  202.         break;
  203.     case EGAMONO:
  204.         GGGraphMode = EGAMONOHI;
  205.         break;
  206.     case HERCMONO:
  207.         GGGraphMode = HERCMONOHI;
  208.         break;
  209.     case VGA:
  210.         GGGraphMode = VGAHI;
  211.         break;
  212.     default:
  213.         fprintf(stderr, "Requested graphic device (%d - see .CFG file) is not supported\n",
  214.         GraphDriver);
  215.         MyExit(1);
  216.         break;
  217.     }
  218.  
  219.     initgraph(&GraphDriver, &GGGraphMode, "");
  220.     GGScreenErrorCode = graphresult();       /* Read result of initialization. */
  221.     if (GGScreenErrorCode != grOk) {           /* Error occured during init. */
  222.     fprintf(stderr, " Graphics System Error: %s\n",
  223.                 grapherrormsg(GGScreenErrorCode));
  224.     MyExit(1);
  225.     }
  226.  
  227.     getpalette(&palette);             /* Read the palette from board. */
  228.     GGScreenMaxColors = getmaxcolor() + 1; /* Read maximum number of colors. */
  229.     ScreenCursorColor = (GGScreenMaxColors > 1 ? GGScreenMaxColors - 1 :
  230.                          GGScreenMaxColors);
  231.  
  232.     GGScreenMaxX = getmaxx();                 /* Read size of screen. */
  233.     GGScreenMaxY = getmaxy();
  234.     GGScreenMaxY2 = GGScreenMaxY / 2;
  235.     GGCurrentCursorX = GGScreenMaxX / 2;
  236.     GGCurrentCursorY = GGScreenMaxY2;
  237.     getaspectratio(&xasp, &yasp);        /* Read the hardware aspect. */
  238.     GGAspectRatio = (double) xasp / (double) yasp; /* Get correction factor: */
  239.     GlblAspectRatio = 1.0 / GGAspectRatio;
  240.     WndwAspectRatio = 1.0;
  241.  
  242.     /* Put in the following any graphic driver specific setup: */
  243.     switch (GraphDriver) {
  244.     case CGA:
  245.         DefaultFontSize = 1;            /* Fixed width font. */
  246.         MenuLineWidth = NORM_WIDTH;
  247.         GlblAspectRatio = 1 / (GGAspectRatio * 1.14);    /* Make bigger. */
  248.         GGScreenMaxPages = 1;
  249.         GGScreenMaxY -= 2;                 /* Dont ask my why! */
  250.         GGScreenMaxY2 -= 1;
  251.         break;
  252.  
  253.     case EGA:
  254.         DefaultFontSize = 1;            /* Fixed width font. */
  255.         MenuLineWidth = THICK_WIDTH;
  256.         GGScreenMaxPages = 2;
  257.         GlblAspectRatio = 1.2;/* I dont like it either, but its simple...*/
  258.         break;
  259.  
  260.     case EGA64:
  261.         DefaultFontSize = 1;            /* Fixed width font. */
  262.         MenuLineWidth = THICK_WIDTH;
  263.         GGScreenMaxPages = 1;
  264.         GlblAspectRatio = 1.2;/* I dont like it either, but its simple...*/
  265.         break;
  266.  
  267.     case EGAMONO:
  268.         DefaultFontSize = 1;            /* Fixed width font. */
  269.         MenuLineWidth = THICK_WIDTH;
  270.         GGScreenMaxPages = 2;
  271.         GGScreenMaxColors = 2;          /* Dont want blinking lines... */
  272.         GlblAspectRatio = 1.2;/* I dont like it either, but its simple...*/
  273.         break;
  274.  
  275.     case HERCMONO:
  276.         DefaultFontSize = 1;            /* Fixed width font. */
  277.         MenuLineWidth = THICK_WIDTH;
  278.         GGScreenMaxPages = 2;
  279.         break;
  280.  
  281.     case VGA:
  282.         DefaultFontSize = 1;            /* Fixed width font. */
  283.         MenuLineWidth = THICK_WIDTH;
  284.         GGScreenMaxPages = 2;
  285.         GlblAspectRatio = 0.88;/*I dont like it either, but its simple...*/
  286.         break;
  287.     }
  288.  
  289. #   ifdef SINGLEPAGE
  290.     GGScreenMaxPages = 1;
  291. #   endif SINGLEPAGE
  292. #   ifdef DEBUG
  293.     GGCloseGraph();
  294.     fprintf(stderr, "ScreenMaxX = %d, ScreenMaxY = %d, MaxColors = %d\n",
  295.         GGScreenMaxX, GGScreenMaxY, GGScreenMaxColors);
  296.     fprintf(stderr, "AspectRatio = %lf\n", GGAspectRatio);
  297.     MyExit(1);
  298. #   endif DEBUG
  299.  
  300.     /* Prepare the cursor (Arrow) image : */
  301.     cleardevice();
  302.     GGMySetColor(ScreenCursorColor);
  303.     setlinestyle(SOLID_LINE, 0,    NORM_WIDTH);
  304.     line(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y);
  305.     j = CURSOR_IMAGE_X / 3;
  306.     for    (i=1; i<=7; i++) line(0, 0, j, j + i);         /* Draw the arrow head. */
  307.     j = CURSOR_IMAGE_Y / 3;
  308.     for    (i=1; i<=7; i++) line(0, 0, j + i, j);
  309.  
  310.     CursorImageBuffer = malloc(imagesize(0, 0, CURSOR_IMAGE_X,
  311.                             CURSOR_IMAGE_Y));
  312.     getimage(0,    0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y, CursorImageBuffer);
  313.  
  314.     for (i = GGScreenMaxPages - 1; i >= 0; i--) {
  315.     setactivepage(i);
  316. #    ifndef NOWINDOWS
  317.         WndwSetUpAllWndws();
  318. #    else
  319.         GGClearAllScreen();
  320. #    endif  NOWINDOWS
  321.     }
  322.  
  323.     settextstyle(DEFAULT_FONT, HORIZ_DIR, DefaultFontSize);
  324.  
  325.     if (MouseExists) {
  326.     switch (GraphDriver) {
  327.         case CGA:
  328.         MSMouseXmax = 1000;            /* Set Column Range. */
  329.         MSMouseYmax = 1000;               /* Set Row range. */
  330.         break;
  331.         case EGA:
  332.         case EGA64:
  333.         case EGAMONO:
  334.         case VGA:
  335.         /* Although 1000x1000 is the regular normalized mouse screen */
  336.         /* it is too lazy on 1:1 ratio.                     */
  337.         MSMouseXmax = 1000;            /* Set Column Range. */
  338.         MSMouseYmax = 1000;               /* Set Row range. */
  339.         break;
  340.         case HERCMONO:
  341.         /* Compensate on the text mode the mouse knows about as      */
  342.         /* hercules is not supported by the mouse driver!            */
  343.         MSMouseXmax = 8000;            /* Set Column Range. */
  344.         MSMouseYmax = 8000;               /* Set Row range. */
  345.         break;
  346.     }
  347.     MouseXRatio = ((double) GGScreenMaxX) / MSMouseXmax;
  348.     MouseYRatio = ((double) GGScreenMaxY) / MSMouseYmax;
  349.     }
  350.  
  351.     GGScreenGraphicMode = TRUE;
  352.     i = open("nul", O_WRONLY);      /* Redirect the stdout to nul: (no ^C...). */
  353.     fflush(stdout);
  354.     OldStdOut = dup(1);
  355.     dup2(i, 1);
  356.     close(i);
  357. #endif NOGRAPHICS
  358. }
  359.  
  360. /****************************************************************************
  361. * Routine to close and shutdown    graphic    mode :                    *
  362. ****************************************************************************/
  363. void GGCloseGraph(void)
  364. {
  365. #ifndef    NOGRAPHICS
  366.     if (!GGScreenGraphicMode) return;
  367.     closegraph();              /* Return the system to text mode. */
  368.     GGScreenGraphicMode = FALSE;
  369.     dup2(OldStdOut, 1);            /* Recover stdout to its regular status. */
  370.     close(OldStdOut);
  371. #endif NOGRAPHICS
  372. }
  373.  
  374. /****************************************************************************
  375. * Routine to update x, y coordinates according to current x, y and key        *
  376. * pressed. Returns TRUE only if <Enter> or alpha char is pressed.        *
  377. ****************************************************************************/
  378. static int GGUpdateGetPointKbd(int *x, int *y)
  379. {
  380.     int    BrkPressed = FALSE;
  381.  
  382.     switch (LastGetChar    = getch()) {
  383.     case 0:
  384.         switch (getch()) {                  /* Extended character: */
  385.         case 16: MyExit(0);          /* Alt - Q, async. exit... */
  386.         case 71:
  387.             *x -= 1;              /* Arrowes - move 1 at a time. */
  388.             *y -= 1;
  389.             break;
  390.         case 72:
  391.             *y -= 1;
  392.             break;
  393.         case 73:
  394.             *x += 1;
  395.             *y -= 1;
  396.             break;
  397.         case 75:
  398.             *x -= 1;
  399.             break;
  400.         case 77:
  401.             *x += 1;
  402.             break;
  403.         case 79:
  404.             *x -= 1;
  405.             *y += 1;
  406.             break;
  407.         case 80:
  408.             *y += 1;
  409.             break;
  410.         case 81:
  411.             *x += 1;
  412.             *y += 1;
  413.             break;
  414.         }
  415.         break;
  416.     case 10:
  417.     case 13:
  418.         BrkPressed = TRUE;
  419.         break;
  420.     case '1':
  421.         *x -= 10;             /* Shifted arrowes - move 10 at a time. */
  422.         *y += 10;
  423.         break;
  424.     case '2':
  425.         *y += 10;
  426.         break;
  427.     case '3':
  428.         *x += 10;
  429.         *y += 10;
  430.         break;
  431.     case '4':
  432.         *x -= 10;
  433.         break;
  434.     case '6':
  435.         *x += 10;
  436.         break;
  437.     case '7':
  438.         *x -= 10;
  439.         *y -= 10;
  440.         break;
  441.     case '8':
  442.         *y -= 10;
  443.         break;
  444.     case '9':
  445.         *x += 10;
  446.         *y -= 10;
  447.         break;
  448.     /* If the key pressed is an alpha - exit */
  449.     default:
  450.         if isalpha(LastGetChar) BrkPressed = TRUE;
  451.         break;
  452.     }
  453.  
  454.     return BrkPressed;
  455. }
  456.  
  457. /****************************************************************************
  458. * Routine to get one x, y selected point in normelized form (-1..1) :        *
  459. ****************************************************************************/
  460. void GGGetPoint(double *x, double *y)
  461. {
  462. #ifndef    NOGRAPHICS
  463.     int    Xtemp, Ytemp, Buttons, Xscreen, Yscreen, Quit, GetInput;
  464.     struct viewporttype view;
  465.  
  466.     WndwAspectRatio = 1.0;
  467.  
  468.     getviewsettings(&view);  /* During Mouse input - must enable all screen. */
  469.     setviewport(ViewPortX = 0, ViewPortY = 0, getmaxx(), getmaxy(), FALSE);
  470.  
  471.     LastGetChar = 0x001;          /* Make no kbd input if mouse input... */
  472.  
  473.     Xtemp = GGCurrentCursorX;
  474.     Ytemp = GGCurrentCursorY;
  475.     putimage(GGCurrentCursorX,         /* Draw the cursor - starting position. */
  476.          GGCurrentCursorY, CursorImageBuffer, XOR_PUT);
  477.  
  478.     if (MouseExists)            /* Update mouse on current position. */
  479.     MouseSetPosition((int) (GGCurrentCursorX / MouseXRatio),
  480.              (int) (GGCurrentCursorY / MouseYRatio));
  481.     Quit = FALSE;
  482.     do {
  483.     GetInput = FALSE;
  484.     do {
  485.         /* Wait for input from one of the devices: Mouse/Keyboard. */
  486.         if (MouseExists && MouseQueryBuffer()) {
  487.         MouseGetBuffer(&Xscreen, &Yscreen, &Buttons);
  488.         GetInput = TRUE;
  489.         GGCurrentCursorX = (int) (Xscreen * MouseXRatio);
  490.         GGCurrentCursorY = (int) (Yscreen * MouseYRatio);
  491.         Quit = Buttons & 0x01;
  492.         }
  493.         if (kbhit()) {
  494.         Quit = GGUpdateGetPointKbd(&GGCurrentCursorX,
  495.                        &GGCurrentCursorY);
  496.         if (MouseExists)    /* Update mouse on the new position. */
  497.             MouseSetPosition((int) (GGCurrentCursorX / MouseXRatio),
  498.                      (int) (GGCurrentCursorY / MouseYRatio));
  499.         GetInput = TRUE;
  500.         }
  501.     }
  502.     while (!GetInput);
  503.     if (GGCurrentCursorX < 0) GGCurrentCursorX = 0;
  504.     if (GGCurrentCursorY < 0) GGCurrentCursorY = 0;
  505.     if (GGCurrentCursorX > GGScreenMaxX - CURSOR_IMAGE_X)
  506.         GGCurrentCursorX = GGScreenMaxX - CURSOR_IMAGE_X;
  507.     if (GGCurrentCursorY > GGScreenMaxY - CURSOR_IMAGE_Y / 2)
  508.         GGCurrentCursorY = GGScreenMaxY - CURSOR_IMAGE_Y / 2;
  509.  
  510.     putimage(Xtemp, Ytemp, CursorImageBuffer, XOR_PUT);/* Erase old crsr!*/
  511.     putimage(GGCurrentCursorX, GGCurrentCursorY, CursorImageBuffer,
  512.                          XOR_PUT); /* Draw new crsr! */
  513.     Xtemp = GGCurrentCursorX;   /* Save them so we could erase it later. */
  514.     Ytemp = GGCurrentCursorY;
  515.     }
  516.     while (!Quit);
  517.  
  518.     putimage(Xtemp,            /* Erase last old cursor before quiting. */
  519.          Ytemp, CursorImageBuffer, XOR_PUT);
  520.  
  521.     /* See GGMyMove for ScreenMaxY2 */
  522.     *x = (((double) GGCurrentCursorX) / GlblAspectRatio - GGScreenMaxY2) /
  523.                                 GGScreenMaxY2;
  524.     *y = (((double) GGCurrentCursorY) - GGScreenMaxY2) / (-GGScreenMaxY2);
  525.  
  526.     setviewport(ViewPortX = view.left, ViewPortY = view.top,
  527.         view.right, view.bottom, view.clip);
  528.  
  529.     if (MouseExists) {
  530.     delay(250);   /* Flush out any spikes mouse buttons had generated... */
  531.     MouseFlushBuffer();
  532.     }
  533.  
  534. #endif NOGRAPHICS
  535. }
  536.  
  537. /****************************************************************************
  538. * Routine to draw a point on screen as marker +    with a title :            *
  539. ****************************************************************************/
  540. void GGDrawPoint(double p[], char title[], int PointColor)
  541. {
  542. #ifndef    NOGRAPHICS
  543.     GGMySetColor(PointColor);
  544.     GGMyMove(p[1] + POINT_SIZE, p[2]);
  545.     GGMyDraw(p[1] - POINT_SIZE, p[2]);
  546.     GGMyMove(p[1], p[2] + POINT_SIZE);
  547.     GGMyDraw(p[1], p[2] - POINT_SIZE);
  548.  
  549.     GGPutMsgXY(title, p[1] + POINT_TITLE, p[2] + POINT_TITLE);
  550. #endif NOGRAPHICS
  551. }
  552.  
  553. #ifndef NOMENUS
  554.  
  555. static double MenuBaseY;
  556.  
  557. /*****************************************************************************
  558. *   Routine to draw a menu and return active flag.                 *
  559. * Gets n - number of items, m -    list of    string & colors, menu header first.  *
  560. * erase    - if TRUE force    erase of menu area first                 *
  561. * returns bit pattern integer -    one bit    per entry.                 *
  562. *****************************************************************************/
  563. int GGMenuDraw(int n, struct MenuItem m[], int erase)
  564. {
  565. #ifndef    NOGRAPHICS
  566.     int    active; /* Used to hold how is active (not null) - one bit per item. */
  567.     struct viewporttype    view;
  568.  
  569.     getviewsettings(&view);
  570.     if (n <= MENU_MAX_ITEMS) {
  571.     MenuBaseY = MENU_TOP_Y - n*MENU_ITEM_Y - MENU_HEAD_Y;/*Calc menu bot.*/
  572.  
  573.     /* Draw    the frame & header of the Menu */
  574.     GGViewPortMenuArea();
  575.     if (erase) GGClearMenuArea();
  576.  
  577.     GGDrawMenuFrame(n, MENU_FRAME_COLOR);
  578.     GGDrawMenuItems(n, m, &active);                 /* Draw string. */
  579.  
  580.     ActvMenu = m; /* Save some information on active menu. */
  581.     ActvMenuN = n;
  582.     ActvMenuActive = active;
  583.     }
  584.  
  585.     if (!erase)
  586.     setviewport(ViewPortX = view.left, ViewPortY = view.top,
  587.             view.right, view.bottom, view.clip);
  588.  
  589.     return active;
  590. #endif NOGRAPHICS
  591. }
  592.  
  593. /*****************************************************************************
  594. *   Routine to draw the    menu frame.                         *
  595. * Gets n - number of items, color - color of frame.                 *
  596. *****************************************************************************/
  597. static void GGDrawMenuFrame(int n, int color)
  598. {
  599. #ifndef    NOGRAPHICS
  600.     int    i;
  601.     struct linesettingstype saveline;
  602.  
  603.     getlinesettings(&saveline);
  604.     setlinestyle(SOLID_LINE, 0,    MenuLineWidth);
  605.  
  606.     GGMySetColor(color);
  607.     GGMyMove((double) MENU_BASE_X,
  608.          (double) MenuBaseY);            /* Draw the outer frame. */
  609.     GGMyDraw((double) MENU_BASE_X,
  610.          (double) MenuBaseY+MENU_ITEM_Y*n+MENU_HEAD_Y);
  611.     GGMyDraw((double) MENU_BASE_X+MENU_ITEM_X,
  612.          (double) MenuBaseY+MENU_ITEM_Y*n+MENU_HEAD_Y);
  613.     GGMyDraw((double) MENU_BASE_X+MENU_ITEM_X,
  614.          (double) MenuBaseY);
  615.     GGMyDraw((double) MENU_BASE_X,
  616.          (double) MenuBaseY);
  617.     for    (i=1; i<=n; i++) {
  618.     GGMyMove((double) MENU_BASE_X,
  619.          (double) MenuBaseY+MENU_ITEM_Y*i);
  620.     GGMyDraw((double) MENU_BASE_X+MENU_ITEM_X,
  621.          (double) MenuBaseY+MENU_ITEM_Y*i);
  622.     }
  623.     setlinestyle(saveline.linestyle, saveline.upattern, saveline.thickness);
  624. #endif NOGRAPHICS
  625. }
  626.  
  627. /*****************************************************************************
  628. *   Routine to draw the    menu internal strings.                     *
  629. * Gets n - number of items, m string structure,    active - active    string.         *
  630. * Returns in active the    none null strings (bit per item) - active menu items.*
  631. *****************************************************************************/
  632. static void GGDrawMenuItems(int n, struct MenuItem m[], int *active)
  633. {
  634. #ifndef    NOGRAPHICS
  635.     int i, power2;
  636.     struct textsettingstype oldtext;
  637.  
  638.     *active = 0;
  639.     power2 = 1;
  640.  
  641.     gettextsettings(&oldtext);
  642.     settextstyle(DEFAULT_FONT, HORIZ_DIR, DefaultFontSize);
  643.     settextjustify(CENTER_TEXT, CENTER_TEXT);
  644.  
  645.     for (i=0; i<=n; i++) {
  646.     GGMySetColor(m[i].color);
  647.     if (i == 0)
  648.         GGPutMsgXY(m[i].string,
  649.         MENU_BASE_X+MENU_ITEM_X/2, MenuBaseY+MENU_ITEM_Y*(n + 0.7));
  650.     else {
  651.         GGPutMsgXY(m[i].string,
  652.         MENU_BASE_X+MENU_ITEM_X/2,
  653.         MenuBaseY+MENU_ITEM_Y*(n - i + 0.4));
  654.         if (strlen(m[i].string)) *active |= power2;
  655.         power2 <<= 1;
  656.     }
  657.     }
  658.  
  659.     settextstyle(oldtext.font, oldtext.direction, oldtext.charsize);
  660.     settextjustify(oldtext.horiz, oldtext.vert);
  661. #endif NOGRAPHICS
  662. }
  663.  
  664. /*****************************************************************************
  665. *   Routine to pick an item from menu from active ones:                 *
  666. *****************************************************************************/
  667. int GGMenuPick(void)
  668. {
  669.     double x, y;
  670.     int    i, select = 0, Duplicate;
  671.  
  672.     do {
  673.     if (MouseExists) MouseFlushBuffer();      /* No need of old garbage! */
  674.     GGGetPoint(&x, &y);
  675.  
  676.     /* Try to match    the input with the menu    first chars. */
  677.     Duplicate = FALSE;
  678.     if (islower(LastGetChar)) LastGetChar =    toupper(LastGetChar);
  679.     for (i=1; i<=ActvMenuN;    i++)
  680.         if (LastGetChar == ActvMenu[i].string[0])
  681.         if (select) Duplicate =    TRUE;         /* More than one match! */
  682.         else select = i;
  683.     if (Duplicate) {
  684.         GGTone(2000, 100);                   /* Do some noise. */
  685.         GGTone(500, 100);
  686.         select = 0;
  687.         continue;
  688.     }
  689.     /* If fails try    to see if the arrow is on a valid menu item: */
  690.     if ((!select) && (x >= MENU_BASE_X && x <= MENU_BASE_X+MENU_ITEM_X)) {
  691.         /* Convert into integer item number    (still in double...). */
  692.         y =    1 - (y - MENU_TOP_Y + MENU_HEAD_Y) / MENU_ITEM_Y;
  693.         select = (int) y;
  694.         if (!((ActvMenuActive >> (select-1)) & 1))
  695.         select = 0;                   /* inactive item. */
  696.     }
  697.     }
  698.     while (!select);
  699.  
  700.     return select;
  701. }
  702.  
  703. /*****************************************************************************
  704. *   Routine to draw the    confrim    special    menu request                 *
  705. * Returns TRUE value if    Yes selected, FALSE if No selected.             *
  706. *****************************************************************************/
  707. int GGConfirm(char *s)
  708. {
  709.     static struct MenuItem ConfMenu[] =    {      /* Confirm Menu selection. */
  710.     YELLOW, "                   ",        /* Make space for everybody. */
  711.     MAGENTA, "Yes",
  712.     MAGENTA, "No"
  713.     };
  714.     int    select;
  715.  
  716.     GGClearMenuArea();
  717.     strcpy(ConfMenu[0].string, s);           /* Set up for new header. */
  718.     GGMenuDraw(2, ConfMenu, TRUE);
  719.     select = GGMenuPick();
  720.     GGClearMenuArea();
  721.  
  722.     return (select == 1);
  723. }
  724.  
  725. #endif    NOMENUS
  726.  
  727. #ifndef NOHELP
  728.  
  729. /*****************************************************************************
  730. *   Routine to print help on menu in the menu area. Input is from file         *
  731. * FileName , Which is scanned until MenuName is    found and until    $ sign         *
  732. * It is    the responsibility of this routine to clear the    Menu area before     *
  733. * and after the    print help ...                             *
  734. *****************************************************************************/
  735. void GGPrintHelpMenu(char *FileName, char *MenuName)
  736. {
  737. #ifndef    NOGRAPHICS
  738.     FILE *f;
  739.     char s[255];  /* Irregular high length but they are some lengthly lines. */
  740.     int    i, j, flag;
  741.     double Yaxis;
  742.     struct textsettingstype oldtext;
  743.  
  744.     gettextsettings(&oldtext);
  745.     settextstyle(DEFAULT_FONT, HORIZ_DIR, DefaultFontSize);
  746.  
  747.     GGClearMenuArea();
  748.  
  749.     if ((f = GGFindFile(FileName, "rt")) == NULL)
  750.     return;                       /* Search all the path names. */
  751.     do {
  752.     flag = fgets(s, 255, f) != NULL;
  753.     s[strlen(s)-1] = 0;                  /* Clear the new line. */
  754.     }
  755.     while (strcmp(MenuName, s) && (flag));     /* Skip until correct menu. */
  756.  
  757.     if (!flag) {
  758.     GGPutErrorMsg("No Such Menu in file");
  759.     fclose(f);
  760.     return;
  761.     }
  762.  
  763.     Yaxis = 0.93;                /* First line to start with. */
  764.     do {        /* If we are here then we found the menu - Print it. */
  765.     flag = (fgets(s, 255, f) != NULL);
  766.     s[strlen(s)-1] = NULL;                  /* Clear the new line. */
  767.     if (s[0] == '*') {
  768.         GGMySetColor(HELP_COLOR_HEADER);
  769.         HelpUpdateY(&Yaxis);
  770.         s[0] = ' ';
  771.     }
  772.     else GGMySetColor(HELP_COLOR);
  773.     if (s[0] != '$')                    /* Terminator... */
  774.     if (strlen(s) <    MAX_HELP_MENU_CHAR) {
  775.         GGPutMsgXY(s, MENU_BASE_X, Yaxis);
  776.         HelpUpdateY(&Yaxis);
  777.     }
  778.     else {
  779.         i =    0;
  780.         while ((strlen(&s[i]) > MAX_HELP_MENU_CHAR)) {
  781.         j = i +    MAX_HELP_MENU_CHAR;         /* Break the line.! */
  782.         while (s[j--] != ' ');            /* In the nearest space. */
  783.         s[++j] = 0;            /* Put EOL instead of Space. */
  784.         GGPutMsgXY(&s[i], MENU_BASE_X, Yaxis);
  785.         HelpUpdateY(&Yaxis);
  786.         i = j + 1;
  787.         }
  788.         if ((strlen(&s[i]) > 0) && (Yaxis >    -1.0)) {
  789.         GGPutMsgXY(&s[i], MENU_BASE_X, Yaxis);
  790.         HelpUpdateY(&Yaxis);
  791.         }
  792.     }
  793.     }
  794.     while ((flag) && (s[0] != '$'));
  795.  
  796.     fclose(f);
  797.  
  798.     GGPutErrorMsg("");                      /* Wait for keystroke. */
  799.  
  800.     GGClearMenuArea();
  801.     settextstyle(oldtext.font, oldtext.direction, oldtext.charsize);
  802. #endif NOGRAPHICS
  803. }
  804.  
  805. /*****************************************************************************
  806. *   Routine to decrease Y for next line in the help printing. Test is made   *
  807. * for last line, and wait and clear area is performed in that case.         *
  808. *****************************************************************************/
  809. static void HelpUpdateY(double *Yaxis)
  810. {
  811.     *Yaxis = (*Yaxis) - 0.08;
  812.     if (*Yaxis < -0.75) {
  813.     GGPutErrorMsg("");
  814.     GGClearMenuArea();
  815.     *Yaxis = 0.93;
  816.     GGMySetColor(HELP_COLOR);
  817.     }
  818. }
  819.  
  820. /*****************************************************************************
  821. *   Routine to search for a file and open it according to attribute at all   *
  822. * directories defined by PATH environment variable and current dir.         *
  823. *****************************************************************************/
  824. static FILE *GGFindFile(char *FileName, char *Attribute)
  825. {
  826.     FILE *f;
  827.     char *Path;
  828.  
  829.     Path = searchpath(FileName);
  830.     if ((f = fopen(Path, Attribute)) !=    0) return f;
  831.  
  832.     GGPutErrorMsg("No Help File Available");
  833.     return (FILE *) NULL;
  834. }
  835.  
  836. #endif NOHELP
  837.  
  838. /*****************************************************************************
  839. *   Routine to clear the Menu area, and set view port to it.             *
  840. *****************************************************************************/
  841. void GGClearMenuArea(void)
  842. {
  843. #ifndef    NOGRAPHICS
  844.  
  845. #ifdef  NOWINDOWS
  846.     setviewport(ViewPortX = (int) (GGScreenMaxY * GlblAspectRatio),
  847.         ViewPortY = 0,
  848.         GGScreenMaxX, GGScreenMaxY, FALSE);
  849.     clearviewport();
  850. #else
  851.     WndwClearWindow(WndwMenuWindow);
  852.     WndwAspectRatio = 1.0;
  853. #endif NOWINDOWS
  854.  
  855. #endif NOGRAPHICS
  856. }
  857.  
  858. /*****************************************************************************
  859. *   Routine to clear the Axes area, and set view port to it.             *
  860. *****************************************************************************/
  861. void GGClearViewArea(void)
  862. {
  863. #ifndef    NOGRAPHICS
  864.  
  865. #ifdef  NOWINDOWS
  866.     setviewport(ViewPortX = 0, ViewPortY = 0,
  867.         (int) (GGScreenMaxY * GlblAspectRatio), GGScreenMaxY, FALSE);
  868.     clearviewport();
  869. #else
  870.     WndwClearWindow(WndwViewWindow);
  871.     switch (GraphDriver) {
  872.     case HERCMONO:
  873.     case CGA:
  874.         WndwAspectRatio = 1.0;
  875.         break;
  876.     case EGA:
  877.     case EGA64:
  878.     case EGAMONO:
  879.     case VGA:
  880.         WndwAspectRatio = 1.2;
  881.         break;
  882.     }
  883. #endif NOWINDOWS
  884.  
  885. #endif NOGRAPHICS
  886. }
  887.  
  888. /*****************************************************************************
  889. *   Routine to clear all the screen.                         *
  890. *****************************************************************************/
  891. void GGClearAllScreen(void)
  892. {
  893. #ifndef    NOGRAPHICS
  894.     setviewport(ViewPortX = 0, ViewPortY = 0, getmaxx(), getmaxy(), FALSE);
  895.     clearviewport();
  896.     WndwAspectRatio = 1.0;
  897. #endif NOGRAPHICS
  898. }
  899.  
  900. /*****************************************************************************
  901. *   Routine to set the view port to the Menu area:                 *
  902. *****************************************************************************/
  903. void GGViewPortMenuArea(void)
  904. {
  905. #ifndef    NOGRAPHICS
  906.  
  907. #ifdef  NOWINDOWS
  908.     setviewport(ViewPortX = (int) (GGScreenMaxY * GlblAspectRatio),
  909.         ViewPortY = 0,
  910.         GGScreenMaxX, GGScreenMaxY, FALSE);
  911. #else
  912.     WndwSetViewPort(WndwMenuWindow -> MinX,
  913.             WndwMenuWindow -> MinY,
  914.             WndwMenuWindow -> MaxX,
  915.             WndwMenuWindow -> MaxY);
  916.     WndwAspectRatio = 1.0;
  917. #endif NOWINDOWS
  918.  
  919. #endif NOGRAPHICS
  920. }
  921.  
  922. /*****************************************************************************
  923. *   Routine to clear the Axes area, and set view port to it.             *
  924. *****************************************************************************/
  925. void GGViewPortViewArea(void)
  926. {
  927. #ifndef    NOGRAPHICS
  928.  
  929. #ifdef  NOWINDOWS
  930.     setviewport(ViewPortX = 0, ViewPortY = 0,
  931.         (int) (GGScreenMaxY * GlblAspectRatio), GGScreenMaxY, FALSE);
  932. #else
  933.     WndwSetViewPort(WndwViewWindow -> MinX,
  934.             WndwViewWindow -> MinY,
  935.             WndwViewWindow -> MaxX,
  936.             WndwViewWindow -> MaxY);
  937.     WndwAspectRatio = GlblAspectRatio * GlblAspectRatio;
  938. #endif NOWINDOWS
  939.  
  940. #endif NOGRAPHICS
  941. }
  942.  
  943. /*****************************************************************************
  944. *   Routine to clear all the screen.                         *
  945. *****************************************************************************/
  946. void GGViewPortAllScreen(void)
  947. {
  948. #ifndef    NOGRAPHICS
  949.     setviewport(ViewPortX = 0, ViewPortY = 0, getmaxx(), getmaxy(), FALSE);
  950. #endif NOGRAPHICS
  951. }
  952.  
  953. /*****************************************************************************
  954. * Routine to print an error message on the message area    :             *
  955. *****************************************************************************/
  956. void GGPutErrorMsg(char *s)
  957. {
  958. #ifndef    NOGRAPHICS
  959.     int Quit = FALSE, X, Y, Buttons;
  960.  
  961.     GGMySetColor(RED);
  962.     GGPutMsgXY(s, MSG_AREA_X, MSG_AREA_Y+0.1);
  963.     GGPutMsgXY("Press Return:", MSG_AREA_X, MSG_AREA_Y);
  964.  
  965.     if (MouseExists) MouseFlushBuffer();      /* No need of old garbage! */
  966.     do {
  967.     if (kbhit()) {
  968.         getch();
  969.         Quit = TRUE;
  970.     }
  971.     if (MouseExists && MouseQueryBuffer()) {
  972.         MouseGetBuffer(&X, &Y, &Buttons);
  973.         Quit = (Buttons != 0);
  974.     }
  975.     }
  976.     while (!Quit);
  977.  
  978.     GGMySetColor(BLACK);                    /* Erase that... */
  979.     GGPutMsgXY(s, MSG_AREA_X, MSG_AREA_Y + 0.1);
  980.     GGPutMsgXY("Press Return:", MSG_AREA_X, MSG_AREA_Y);
  981. #endif NOGRAPHICS
  982. }
  983.  
  984. /*****************************************************************************
  985. * Routine to print an message on the given location:                 *
  986. *****************************************************************************/
  987. void GGPutMsgXY(char *s, double x, double y)
  988. {
  989. #ifndef    NOGRAPHICS
  990.     GGMyMove(x, y);
  991.     outtext(s);
  992. #endif    NOGRAPHICS
  993. }
  994.  
  995. /*****************************************************************************
  996. * Routine to read one line terminated by <Enter> and visualized    on graphic   *
  997. * screen.                                     *
  998. * Full line editing is supported which includes:                 *
  999. * 1. Right and left arrow to move along the line.                 *
  1000. * 2. Delete to delete current character.                     *
  1001. * 3. Insert to toggle Insert/Overwrite mode.                     *
  1002. * 4. Backspace to delete character before current one.                 *
  1003. * 5. Home/End to move to beginning/End of string respectively.             *
  1004. * 6. Return to accept current line.                         *
  1005. * 7. Esc to clear current line.                             *
  1006. * If s is not empty it is used as starting string.                 *
  1007. * Line is drawn    starting from position x, y on screen (normalized -1..1).    *
  1008. *****************************************************************************/
  1009. void GGGetGraphicLine(double x, double y, char s[], int color)
  1010. {
  1011. #ifndef    NOGRAPHICS
  1012.     static int Insert = TRUE;
  1013.     int    NextKey, Xstep, CursorPos = 0, FirstVisible = 0, Len = strlen(s),
  1014.     EndOfString = FALSE;
  1015.     char *Cursor;
  1016.     struct textsettingstype oldtext;
  1017.     struct viewporttype    view;
  1018.  
  1019.     getviewsettings(&view);
  1020.     GGViewPortMenuArea();
  1021.  
  1022.     gettextsettings(&oldtext);
  1023.     settextstyle(DEFAULT_FONT, HORIZ_DIR, DefaultFontSize);
  1024.  
  1025.     Xstep = textwidth(" ");     /* Get the width is pixels of current font. */
  1026.  
  1027.     while (!EndOfString) {
  1028.     /* Set the first character in string to be displayed: */
  1029.     FirstVisible = CursorPos > 15 ? CursorPos - 10 : 0;
  1030.     GGMySetColor(color);          /* Draw the string and the cursor: */
  1031.     GGPutMsgXY(&s[FirstVisible], x, y);
  1032.     Cursor = (Insert ? "_" : "-");
  1033.     GGMySetColor(ScreenCursorColor);
  1034.     GGMyMove(x, y);
  1035.     moverel((CursorPos - FirstVisible) * Xstep, 0);
  1036.     outtext(Cursor);
  1037.  
  1038.     NextKey = GGGetKey();
  1039.  
  1040.     GGMySetColor(BLACK);         /* Erase the string and the cursor: */
  1041.     GGMyMove(x, y);
  1042.     moverel((CursorPos - FirstVisible) * Xstep, 0);
  1043.     outtext(Cursor);
  1044.     GGPutMsgXY(&s[FirstVisible], x, y);
  1045.  
  1046.     switch (NextKey) {
  1047.         case KEY_BSPACE:
  1048.         if (CursorPos == 0) {
  1049.             GGTone(1000, 100);             /* Do some noise... */
  1050.             break;
  1051.         }
  1052.         movmem(&s[CursorPos], &s[CursorPos - 1], Len - CursorPos + 1);
  1053.         CursorPos--;
  1054.         Len--;
  1055.         break;
  1056.         case KEY_DELETE:
  1057.         if (CursorPos >= Len) {
  1058.             GGTone(1000, 100);             /* Do some noise... */
  1059.             break;
  1060.         }
  1061.         movmem(&s[CursorPos + 1], &s[CursorPos], Len - CursorPos);
  1062.         Len--;
  1063.         break;
  1064.         case KEY_RIGHT:
  1065.         if (CursorPos >= Len) {
  1066.             GGTone(1000, 100);             /* Do some noise... */
  1067.             break;
  1068.         }
  1069.         CursorPos++;
  1070.         break;
  1071.         case KEY_LEFT:
  1072.         if (CursorPos <= 0) {
  1073.             GGTone(1000, 100);             /* Do some noise... */
  1074.             break;
  1075.         }
  1076.         CursorPos--;
  1077.         break;
  1078.         case KEY_RETURN:
  1079.         EndOfString = TRUE;
  1080.         break;
  1081.         case KEY_ESC:
  1082.         Len = 0;                /* Clear everything. */
  1083.         CursorPos = 0;
  1084.         s[0] = 0;
  1085.         break;
  1086.         case KEY_HOME:
  1087.         CursorPos = 0;
  1088.         break;
  1089.         case KEY_END:
  1090.         CursorPos = Len;
  1091.         break;
  1092.         case KEY_INSERT:
  1093.         Insert = !Insert;
  1094.         break;
  1095.         default:                      /* Regular ascii char. */
  1096.         if (Insert) {
  1097.             movmem(&s[CursorPos], &s[CursorPos + 1],
  1098.                             Len - CursorPos + 1);
  1099.             Len++;
  1100.         }
  1101.         else if (CursorPos == Len) Len++;/* We are on last character.*/
  1102.         s[CursorPos++] = NextKey;
  1103.         if (CursorPos == Len) s[CursorPos] = 0;
  1104.         break;
  1105.     }
  1106.     }
  1107.  
  1108.     settextstyle(oldtext.font, oldtext.direction, oldtext.charsize);
  1109.     setviewport(ViewPortX = view.left, ViewPortY = view.top,
  1110.         view.right, view.bottom, view.clip);
  1111. #endif NOGRAPHICS
  1112. }
  1113.  
  1114. /*****************************************************************************
  1115. * Get a key from keyboard, and translating operational keys into special     *
  1116. * codes (>255).                                     *
  1117. *****************************************************************************/
  1118. static int GGGetKey(void)
  1119. {
  1120.     char c;
  1121.  
  1122.     while (TRUE) switch (c = getch()) {
  1123.     case 0:              /* Extended code - get the next extended char. */
  1124.         switch (getch()) {
  1125.         case 75: return KEY_LEFT;
  1126.         case 77: return KEY_RIGHT;
  1127.         case 71: return KEY_HOME;
  1128.         case 79: return KEY_END;
  1129.         case 83: return KEY_DELETE;
  1130.         case 82: return KEY_INSERT;
  1131.         }
  1132.         break;
  1133.     case 8:
  1134.         return KEY_BSPACE;
  1135.     case 10:
  1136.     case 13:
  1137.         return KEY_RETURN;
  1138.     case 27:
  1139.         return KEY_ESC;
  1140.     default:
  1141.         if isprint(c) return c;
  1142.     }
  1143.  
  1144.     return KEY_RETURN;                    /* Make warnings silent. */
  1145. }
  1146.  
  1147. /*****************************************************************************
  1148. * Routine to make some sound with given Frequency, Time milliseconds:         *
  1149. *****************************************************************************/
  1150. void GGTone(int Frequency, int Duration)
  1151. {
  1152.     sound(Frequency);
  1153.     delay(Duration);
  1154.     nosound();
  1155. }
  1156.  
  1157. #ifndef  NOWINDOWS
  1158.  
  1159. /*****************************************************************************
  1160. *  Routine to setup all the window to zero state, assuming graphic mode.     *
  1161. *****************************************************************************/
  1162. static void WndwSetUpAllWndws(void)
  1163. {
  1164. #ifndef    NOGRAPHICS
  1165.     GGClearAllScreen();
  1166.  
  1167.     WndwDrawAllWndwFrames();             /* Draw the windows frames. */
  1168.  
  1169.     WndwViewWindow = &ViewWindow;
  1170.     WndwMenuWindow = &MenuWindow;
  1171. #endif    NOGRAPHICS
  1172. }
  1173.  
  1174. /*****************************************************************************
  1175. *  Routine to draw all the frames of all the windows defined in the system:  *
  1176. *****************************************************************************/
  1177. static void WndwDrawAllWndwFrames(void)
  1178. {
  1179. #ifndef    NOGRAPHICS
  1180.     WndwDrawWindowFrame(&MenuWindow);
  1181.     WndwDrawWindowFrame(&ViewWindow);
  1182. #endif    NOGRAPHICS
  1183. }
  1184.  
  1185. /*****************************************************************************
  1186. *  Routine to draw a frame for the window given:                 *
  1187. *****************************************************************************/
  1188. static void WndwDrawWindowFrame(WindowStruct *Window)
  1189. {
  1190.     int i;
  1191.     double MinX = Window -> MinX, MaxX = Window -> MaxX,
  1192.        MinY = Window -> MinY, MaxY = Window -> MaxY,
  1193.        Dx = FRAME_X_WIDTH / 10.0, Dy = FRAME_Y_WIDTH / 10.0;
  1194.  
  1195. #ifndef    NOGRAPHICS
  1196.     GGMySetColor(Window -> FrameColor);
  1197.  
  1198.     for (i=0; i<10; i++) {
  1199.     GGMyMove(MinX, MinY);
  1200.     GGMyDraw(MinX, MaxY);
  1201.     GGMyDraw(MaxX, MaxY);
  1202.     GGMyDraw(MaxX, MinY);
  1203.     GGMyDraw(MinX, MinY);
  1204.  
  1205.     MinX -= Dx;
  1206.     MinY -= Dy;
  1207.     MaxX += Dx;
  1208.     MaxY += Dy;
  1209.     }
  1210. #endif    NOGRAPHICS
  1211. }
  1212.  
  1213. /*****************************************************************************
  1214. *  Routine to clear the given window interior:                     *
  1215. *****************************************************************************/
  1216. static void WndwClearWindow(WindowStruct *W)
  1217. {
  1218. #ifndef    NOGRAPHICS
  1219.     WndwSetViewPort(W -> MinX, W -> MinY, W -> MaxX, W -> MaxY);
  1220.     clearviewport();
  1221. #endif    NOGRAPHICS
  1222. }
  1223.  
  1224. /*****************************************************************************
  1225. *    Routine to set up the view port.                         *
  1226. *****************************************************************************/
  1227. static void WndwSetViewPort(double XMin, double YMin, double XMax, double YMax)
  1228. {
  1229. #ifndef    NOGRAPHICS
  1230.     setviewport(
  1231.     (ViewPortX = (int) ((XMin * GGScreenMaxY2 + GGScreenMaxY2) *
  1232.                             GlblAspectRatio)),
  1233.     (ViewPortY = (int) (-YMax * GGScreenMaxY2 + GGScreenMaxY2)),
  1234.     (int) ((XMax * GGScreenMaxY2 + GGScreenMaxY2) * GlblAspectRatio),
  1235.     (int) (-YMin * GGScreenMaxY2 + GGScreenMaxY2),
  1236.     TRUE);
  1237. #endif    NOGRAPHICS
  1238. }
  1239.  
  1240. #endif  NOWINDOWS
  1241.