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