home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Low level graphics routines(DJGPP driver). *
- * *
- * This file is compiled in C++ mode. *
- * *
- * Written by Gershon Elber, Feb. 1992 *
- *******************************************************************************
- * Supported device: *
- * DJGPP devices. *
- *******************************************************************************
- * History: *
- * 17 Feb 92 - Version 1.0 by Gershon Elber - support for DJGPP. *
- ******************************************************************************/
-
- #include <string.h>
- #include <stdio.h>
- #include <math.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <graphics.h>
-
- #ifdef DJGCC
- #include <pc.h>
- #endif /* DJGCC */
-
- #include "intr_loc.h"
- #include "intr_gr.h"
-
- #define POINT_SIZE 0.05 /* Size of + marker drawn. */
- #define POINT_TITLE 0.02 /* Distance between point title and + marker. */
-
- #define HISTORY_SIZE 10 /* History buffer length for GRGetGraphicLine. */
- #define GR_LINE_LEN 80 /* Maximum chars read by GRGetGraphicLine. */
-
- #define CURSOR_IMAGE_X 24
- #define CURSOR_IMAGE_Y 24
-
- #define CURSOR_TYPE_STACK_SIZE 20 /* Size of stack to save cursor types. */
- #define VIEW_PORT_STACK_SIZE 20 /* Depth of view port setting stack. */
- #define TEXT_SETTING_STACK_SIZE 10 /* Depth of text setting stack. */
-
- #define MAP_UP_X(x) ((((x) - GRPanFactorX) << GRZoomFactor) + GRWidth2)
- #define MAP_UP_Y(y) ((((y) - GRPanFactorY) << GRZoomFactor) + GRHeight2)
- #define MAP_DN_X(x) ((((x) - GRPanFactorX) >> GRIZoomFactor) + GRWidth2)
- #define MAP_DN_Y(y) ((((y) - GRPanFactorY) >> GRIZoomFactor) + GRHeight2)
- #define INVMAP_UP_X(x) ((((x) - GRWidth2) >> GRZoomFactor) + GRPanFactorX)
- #define INVMAP_UP_Y(y) ((((y) - GRHeight2) >> GRZoomFactor) + GRPanFactorY)
- #define INVMAP_DN_X(x) ((((x) - GRWidth2) << GRIZoomFactor) + GRPanFactorX)
- #define INVMAP_DN_Y(y) ((((y) - GRHeight2) << GRIZoomFactor) + GRPanFactorY)
-
- typedef struct TextJustifyStruct {
- GRTextHorizJustifyType HorizJustify;
- GRTextVertJustifyType VertJustify;
- } TextJustifyStruct;
-
- typedef struct ImageSaveStruct {
- int Width, Height;
- char *Data;
- } ImageSaveStruct;
-
- int GRScreenMaxX, GRScreenMaxY; /* The maximum resolution of the screen. */
- int GRScreenMaxColors; /* The maximum # of colors available. */
- IntrRType GRScreenAspect = 1.0; /* Screen aspect ratio (pixel width/height). */
- int GRCurrentCursorX, GRCurrentCursorY; /* Cursor current position. */
- int GRFontName, GRFontSize; /* Global information on font used. */
- int GRDrawText; /* If can not zoom down text, force draw. */
- int GRGraphMode = 0, GRGraphDriver = 0; /* What driver/mode are we in. */
-
- static int GRScreenMaxX2, GRScreenMaxY2; /* Half of maximum resolution. */
- static VoidPtr GRPutImage = NULL; /* If not null, used to save getimage. */
- static int GRScreenGraphicMode;
- static int GRTextSize = 1; /* Current text size: 1 = 8x8, 2 = 16x16 etc.. */
- static int GRWidth2 = 100;
- static int GRHeight2 = 100;
- static int GRMinX = 0;
- static int GRMinY = 0;
- static int GRZoomFactor = 0;
- static int GRIZoomFactor = 0;
- static int GRPanFactorX = 0;
- static int GRPanFactorY = 0;
- static int ViewPortStackPtr = 0;
- static int GRCrntColor = WHITE; /* Current drawing color. */
- static int GRDrawMode = 0x00; /* 0x00 for COPY, 0x100 for XOR mode. */
- static int GRLastMoveToX , GRLastMoveToY;
- static int CrntHorizCenter = GR_TEXT_HJUSTIFY_CENTER;
- static int CrntVertCenter = GR_TEXT_VJUSTIFY_CENTER;
-
- static struct ImageSaveStruct *CursorImageBuffer = NULL;
-
- static struct GrRegion *ViewPortStack[VIEW_PORT_STACK_SIZE];
- static int TextSettingStackPtr = 0;
- static struct TextJustifyStruct TextSettingStack[TEXT_SETTING_STACK_SIZE];
- IntrInt2PtrFunc GlblGetChFunc = IntrGetEventWait;
-
- static char HistoryBuffer[HISTORY_SIZE][GR_LINE_LEN + 1];
- static int HistoryBufLen = 0;
-
- static struct GrRegion *ScrnRegion, *CrntRegion;
-
- static void GRComputeTextOffset(char *s, int *x, int *y);
- static void MoveOverlapMem(char *Dest, char *Src, int Len);
- static int GRGetKey(void);
-
- /****************************************************************************
- * Routine to reset all the system to starting condition : *
- ****************************************************************************/
- void GRInitGraph()
- {
- int i, j, GRScreenErrorCode;
-
- if (GRScreenGraphicMode) return;
-
- ViewPortStackPtr = 0; /* Make sure view port stack is empty. */
-
- GrSetMode(GR_default_graphics);
-
- ScrnRegion = GrScreenRegion();
-
- GRScreenMaxX = ScrnRegion->width;
- GRScreenMaxY = ScrnRegion->height;
- GRScreenMaxX2 = GRScreenMaxX / 2;
- GRScreenMaxY2 = GRScreenMaxY / 2;
-
- GRCurrentCursorX = GRScreenMaxX2;
- GRCurrentCursorY = GRScreenMaxY2;
-
- GRScreenMaxColors = 256;
-
- ScrnRegion->Box(0, 0, GRScreenMaxX, GRScreenMaxY, BLACK);
- CrntRegion = ScrnRegion;
-
- /* Prepare the cursor (Arrow) image : */
- GRSetColor(GRScreenMaxColors - 1);
- GRSLine(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y);
- j = CURSOR_IMAGE_X / 3;
- for (i = 1; i <= 7; i++) GRSLine(0, 0, j, j + i);/* Draw the arrow head. */
- j = CURSOR_IMAGE_Y / 3;
- for (i = 1; i <= 7; i++) GRSLine(0, 0, j + i, j);
-
- CursorImageBuffer = (struct ImageSaveStruct *)
- GRGetImageBuffer(0, 0, CURSOR_IMAGE_X, CURSOR_IMAGE_Y);
-
- GRClearAllScreen();
-
- GRScreenGraphicMode = TRUE;
- }
-
- /****************************************************************************
- * Routine to close and shutdown graphic mode : *
- ****************************************************************************/
- void GRCloseGraph(void)
- {
- if (!GRScreenGraphicMode) return;
-
- GrSetMode(GR_default_text);
- }
-
- /****************************************************************************
- * Routine to set line style parameters. *
- ****************************************************************************/
- void GRSetLineStyle(int LineStyle, unsigned int Pattern, int Thickness)
- {
- }
-
- /****************************************************************************
- * Routine to set fill style parameters. *
- ****************************************************************************/
- void GRSetFillStyle(int Pattern, int Color)
- {
- GRCrntColor = Color;
- }
-
- /****************************************************************************
- * Routine to set write mode parameters - non zero XOR mode, zero COPY mode. *
- ****************************************************************************/
- void GRSetWriteMode(int DrawMode)
- {
- GRDrawMode = DrawMode ? 0x100 : 0x00;
- }
-
- /****************************************************************************
- * Routine to set text horizontal and vertical justification. *
- ****************************************************************************/
- void GRSetTextJustify(int HorizCenter, int VertCenter)
- {
- CrntHorizCenter = HorizCenter;
- CrntVertCenter = VertCenter;
- }
-
- /****************************************************************************
- * Routine to set zoom factor for drawing. *
- * Zoom factor of 0 means regular drawing while each inc/decremenet zooms *
- * up/down respectively by a factor of 2. *
- ****************************************************************************/
- void GRSetZoomFactor(int ZoomFactor)
- {
- GRZoomFactor = ZoomFactor;
- GRIZoomFactor = -GRZoomFactor;
- }
-
- /****************************************************************************
- * Routine to set pan factors for drawing space. *
- ****************************************************************************/
- void GRSetPanFactors(int PanFactorX, int PanFactorY)
- {
- GRPanFactorX = PanFactorX;
- GRPanFactorY = PanFactorY;
- }
-
- /****************************************************************************
- * Routine to set text drawing parameters, in drawing space. *
- ****************************************************************************/
- void GRSetTextStyle(int GRFontName, int Direction, int Size)
- {
- GRTextSize = Size + GRZoomFactor;
- }
-
- /****************************************************************************
- * Routine to set text drawing parameters, in screen space. *
- ****************************************************************************/
- void GRSetSTextStyle(int GRFontName, int Direction, int Size)
- {
- }
-
- /****************************************************************************
- * Routine to get an image rectangle into real memory. *
- ****************************************************************************/
- void *GRGetImageBuffer(int x1, int y1, int x2, int y2)
- {
- int i, Width;
- struct ImageSaveStruct
- *Buffer = new struct ImageSaveStruct;
- char *p,
- *Visual = (char *) (0xd0000000 +
- (CrntRegion -> abs_y + y1) * GRScreenMaxX +
- (CrntRegion -> abs_x + x1));
-
- Width = Buffer -> Width = x2 - x1 + 1;
- Buffer -> Height = y2 - y1 + 1;
- Buffer -> Data = p = new char[Buffer -> Width * Buffer -> Height];
-
- for (i = Buffer -> Height; i > 0; i--) {
- memcpy(p, Visual, Width);
- p += Width;
- Visual += GRScreenMaxX;
- }
-
- return (void *) Buffer;
- }
-
- /****************************************************************************
- * Routine to put an image rectangle from real memory into the display. *
- ****************************************************************************/
- void GRPutImageBuffer(int x1, int y1, void *Buffer)
- {
- struct ImageSaveStruct
- *IBuffer = (ImageSaveStruct *) Buffer;
- int i,
- Width = IBuffer -> Width;
- char
- *p = IBuffer -> Data,
- *Visual = (char *) (0xd0000000 +
- (CrntRegion -> abs_y + y1) * GRScreenMaxX +
- (CrntRegion -> abs_x + x1));
-
- for (i = IBuffer -> Height; i > 0; i--) {
- memcpy(Visual, p, Width);
- p += Width;
- Visual += GRScreenMaxX;
- }
-
- delete IBuffer -> Data;
- delete IBuffer;
- }
-
- /****************************************************************************
- * Routine to draw the cursor as an arrow. *
- ****************************************************************************/
- void GRPutArrowCursor(int x, int y)
- {
- int i, j,
- CursorWidth = CursorImageBuffer -> Width,
- Width = MIN(CursorWidth, GRScreenMaxX - x);
- char *cp, *vp,
- *CursorData = CursorImageBuffer -> Data,
- *VisualData = (char *) (0xd0000000 + y * GRScreenMaxX + x);
-
- for (i = CursorImageBuffer -> Height; i > 0; i--) {
- cp = CursorData;
- vp = VisualData;
- for (j = 0; j < Width; j++) *vp++ ^= *cp++;
-
- CursorData += CursorWidth;
- VisualData += GRScreenMaxX;
- }
- }
-
- /****************************************************************************
- * Routine to XOR a rectangle area on screen using current color. *
- ****************************************************************************/
- void GRXORRectangle(int x1, int y1, int x2, int y2)
- {
- ScrnRegion->Box(x1, y1, x2 - x1 + 1, y2 - y1 + 1, GRCrntColor | 0x100);
- }
-
- /****************************************************************************
- * External reference for the mappings. *
- ****************************************************************************/
- int GRMapX(int x)
- {
- return (GRZoomFactor > 0 ? MAP_UP_X(x) : MAP_DN_X(x)) + GRMinX;
- }
-
- int GRMapY(int y)
- {
- return (GRZoomFactor > 0 ? MAP_UP_Y(y) : MAP_DN_Y(y)) + GRMinY;
- }
-
- /****************************************************************************
- * External reference for the inverse mapping. *
- ****************************************************************************/
- int GRInvMapX(int x)
- {
- x -= GRMinX;
- return (GRZoomFactor > 0 ? INVMAP_UP_X(x) : INVMAP_DN_X(x));
- }
-
- int GRInvMapY(int y)
- {
- y -= GRMinY;
- return (GRZoomFactor > 0 ? INVMAP_UP_Y(y) : INVMAP_DN_Y(y));
- }
-
- /****************************************************************************
- * Routine to draw a line, in Object spaces. *
- ****************************************************************************/
- void GRLine(int x1, int y1, int x2, int y2)
- {
- if (GRZoomFactor > 0) {
- CrntRegion->Line(MAP_UP_X(x1),
- MAP_UP_Y(y1),
- GRLastMoveToX = MAP_UP_X(x2),
- GRLastMoveToY = MAP_UP_Y(y2),
- GRCrntColor);
- }
- else {
- CrntRegion->Line(MAP_DN_X(x1),
- MAP_DN_Y(y1),
- GRLastMoveToX = MAP_DN_X(x2),
- GRLastMoveToY = MAP_DN_Y(y2),
- GRCrntColor);
- }
- }
-
- /****************************************************************************
- * Routine to move to a new position, in Object space. *
- ****************************************************************************/
- void GRMoveTo(int x, int y)
- {
- if (GRZoomFactor > 0) {
- GRLastMoveToX = MAP_UP_X(x);
- GRLastMoveToY = MAP_UP_Y(y);
- }
- else {
- GRLastMoveToX = MAP_DN_X(x);
- GRLastMoveToY = MAP_DN_Y(y);
- }
- }
-
- /****************************************************************************
- * Routine to draw to a new position, in Object space. *
- ****************************************************************************/
- void GRLineTo(int x, int y)
- {
- int GRLineToX, GRLineToY;
-
- if (GRZoomFactor > 0) {
- GRLineToX = MAP_UP_X(x);
- GRLineToY = MAP_UP_Y(y);
- }
- else {
- GRLineToX = MAP_DN_X(x);
- GRLineToY = MAP_DN_Y(y);
- }
-
- CrntRegion->Line(GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY,
- GRCrntColor | GRDrawMode);
- GRLastMoveToX = GRLineToX;
- GRLastMoveToY = GRLineToY;
- }
-
- /****************************************************************************
- * Routine to move to a new position, in Screen (pixels) space. *
- ****************************************************************************/
- void GRSMoveTo(int x, int y)
- {
- GRLastMoveToX = x;
- GRLastMoveToY = y;
- }
-
- /****************************************************************************
- * Routine to draw to a new position, in Screen (pixels) space. *
- ****************************************************************************/
- void GRSLineTo(int x, int y)
- {
- CrntRegion->Line(GRLastMoveToX, GRLastMoveToY, x, y,
- GRCrntColor | GRDrawMode);
- GRLastMoveToX = x;
- GRLastMoveToY = y;
- }
-
- /****************************************************************************
- * Routine to draw to a new position, in Screen (pixels) space. *
- ****************************************************************************/
- void GRSLine(int x1, int y1, int x2, int y2)
- {
- CrntRegion->Line(x1, y1, x2, y2, GRCrntColor | GRDrawMode);
- GRLastMoveToX = x2;
- GRLastMoveToY = y2;
- }
-
- /****************************************************************************
- * Routine to move to a new position relative to current one, as in Object *
- * space. *
- ****************************************************************************/
- void GRMoveRel(int x, int y)
- {
- if (GRZoomFactor > 0) {
- GRLastMoveToX += x << GRZoomFactor;
- GRLastMoveToY += y << GRZoomFactor;
- }
- else {
- GRLastMoveToX += x >> GRIZoomFactor;
- GRLastMoveToY += y >> GRIZoomFactor;
- }
- }
-
- /****************************************************************************
- * Routine to line to a new position relative to current one, as in Object *
- * space. *
- ****************************************************************************/
- void GRLineRel(int x, int y)
- {
- int GRLineToX = GRLastMoveToX,
- GRLineToY = GRLastMoveToY;
-
- if (GRZoomFactor > 0) {
- GRLineToX += x << GRZoomFactor;
- GRLineToY += y << GRZoomFactor;
- }
- else {
- GRLineToX += x >> GRIZoomFactor;
- GRLineToY += y >> GRIZoomFactor;
- }
-
- CrntRegion->Line(GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY,
- GRCrntColor | GRDrawMode);
- GRLastMoveToX = GRLineToX;
- GRLastMoveToY = GRLineToY;
- }
-
- /****************************************************************************
- * Routine to move to a new position relative to current one, as in Screen *
- * space (pixel coords.). *
- ****************************************************************************/
- void GRSMoveRel(int x, int y)
- {
- GRLastMoveToX += x;
- GRLastMoveToY += y;
- }
-
- /****************************************************************************
- * Routine to line to a new position relative to current one, as in Screen *
- * space (pixel coords.). *
- ****************************************************************************/
- void GRSLineRel(int x, int y)
- {
- int GRLineToX = GRLastMoveToX + x,
- GRLineToY = GRLastMoveToY + y;
-
- CrntRegion->Line(GRLastMoveToX, GRLastMoveToY, GRLineToX, GRLineToY,
- GRCrntColor | GRDrawMode);
- GRLastMoveToX = GRLineToX;
- GRLastMoveToY = GRLineToY;
- }
-
- /****************************************************************************
- * Routine to draw a new polyline and fill it if Fill, in screen space. *
- ****************************************************************************/
- void GRPoly(int n, int *Points, int Fill)
- {
- int i, ii;
-
- if (GRZoomFactor > 0)
- for (i = 0; i < n; i++) {
- ii = i << 1;
- Points[ii] = MAP_UP_X(Points[ii]);
- Points[ii + 1] = MAP_UP_Y(Points[ii + 1]);
- }
- else
- for (i = 0; i < n; i++) {
- ii = i << 1;
- Points[ii] = MAP_DN_X(Points[ii]);
- Points[ii + 1] = MAP_DN_Y(Points[ii + 1]);
- }
-
- if (Fill) {
- /* There is a problem with BLACK color that fillpoly sometime does */
- /* not clear the border properly, so we need to redo it by drawpoly. */
- IntrFatalError("Fill not supported in this driver.\n");
- }
- else {
- GRSMoveTo(Points[n * 2 - 2], Points[n * 2 - 1]);
- for (i = 0; i < n; i++) {
- ii = i << 1;
- GRSLineTo(Points[ii], Points[ii + 1]);
- }
- }
- }
-
- /****************************************************************************
- * Routine to draw a bar, in drawing space. *
- ****************************************************************************/
- void GRBar(int x1, int y1, int x2, int y2)
- {
- if (GRZoomFactor > 0) {
- x1 = MAP_UP_X(x1);
- y1 = MAP_UP_Y(y1);
- x2 = MAP_UP_X(x2);
- y2 = MAP_UP_Y(y2);
- }
- else {
- x1 = MAP_DN_X(x1);
- y1 = MAP_DN_Y(y1);
- x2 = MAP_DN_X(x2);
- y2 = MAP_DN_Y(y2);
- }
-
- CrntRegion->Box(x1, y1, x2 - x1 + 1, y2 - y1 + 1, GRCrntColor | GRDrawMode);
- }
-
- /****************************************************************************
- * Routine to draw a bar, in screen space. *
- ****************************************************************************/
- void GRSBar(int x1, int y1, int x2, int y2)
- {
- CrntRegion->Box(x1, y1, x2 - x1 + 1, y2 - y1 + 1, GRCrntColor | GRDrawMode);
- }
-
- /****************************************************************************
- * Routine to draw a circle, in drawing space. *
- ****************************************************************************/
- void GRCircle(int x, int y, int r)
- {
- IntrFatalError("Fill not supported in this driver.\n");
- }
-
- /****************************************************************************
- * Routine to draw an arc, in drawing space. *
- * As the Y axes is inverted the Angles should be inverted as well. *
- ****************************************************************************/
- void GRArc(int x, int y, int StAngle, int EndAngle, int r)
- {
- IntrFatalError("Fill not supported in this driver.\n");
- }
-
- /****************************************************************************
- * Routine to draw the given text in given drawing space coordinates. *
- ****************************************************************************/
- IntrBType GRDrawingText(void)
- {
- return GRTextSize > 0 || GRDrawText;
- }
-
- /****************************************************************************
- * Routine to compute text justification offset according to given string. *
- ****************************************************************************/
- static void GRComputeTextOffset(char *s, int *x, int *y)
- {
- int Width = GRGetTextWidth(s),
- Height = GRGetTextHeight(s);
-
- switch (CrntHorizCenter) {
- case GR_TEXT_HJUSTIFY_LEFT:
- *x = 0;
- break;
- case GR_TEXT_HJUSTIFY_CENTER:
- *x = -Width/ 2;
- break;
- case GR_TEXT_HJUSTIFY_RIGHT:
- *x = -Width;
- break;
- }
-
- switch (CrntVertCenter) {
- case GR_TEXT_VJUSTIFY_BOTTOM:
- *y = -Height;
- break;
- case GR_TEXT_VJUSTIFY_CENTER:
- *y = -Height / 2;
- break;
- case GR_TEXT_VJUSTIFY_TOP:
- *y = 0;
- break;
- }
- }
-
- /****************************************************************************
- * Routine to draw the given text in given drawing space coordinates. *
- ****************************************************************************/
- void GRText(int x, int y, char *s)
- {
- int XOffset, YOffset;
-
- GRComputeTextOffset(s, &XOffset, &YOffset);
-
- /* If text can not be zoom down and we are not forced to draw - dont. */
- if (GRTextSize < 1 && !GRDrawText) return;
-
- if (GRZoomFactor > 0)
- CrntRegion->Text(MAP_UP_X(x) + XOffset, MAP_UP_Y(y) + YOffset,
- s, GRCrntColor, -1);
- else
- CrntRegion->Text(MAP_DN_X(x) + XOffset, MAP_DN_Y(y) + YOffset,
- s, GRCrntColor, -1);
- }
-
- /****************************************************************************
- * Routine to draw the given text in given screen space coordinates. *
- ****************************************************************************/
- void GRSText(int x, int y, char *s)
- {
- int XOffset, YOffset;
-
- GRComputeTextOffset(s, &XOffset, &YOffset);
-
- CrntRegion->Text(x + XOffset, y + YOffset, s, GRCrntColor, -1);
- }
-
- /****************************************************************************
- * Routine to draw the given text in given screen space coordinates. *
- * A Black shadow is drawn for the given string. *
- ****************************************************************************/
- void GRSTextShadow(int x, int y, int Color, char *s)
- {
- int XOffset, YOffset;
-
- GRComputeTextOffset(s, &XOffset, &YOffset);
-
- CrntRegion->Text(x + 2 + XOffset, y + 2 + YOffset, s, BLACK, -1);
- CrntRegion->Text(x + XOffset, y + YOffset, s, Color, -1);
- }
-
- /****************************************************************************
- * Routine to get string width in pixel. *
- ****************************************************************************/
- int GRGetTextWidth(char *Str)
- {
- return 8 * strlen(Str);
- }
-
- /****************************************************************************
- * Routine to get string height in pixel. *
- ****************************************************************************/
- int GRGetTextHeight(char *Str)
- {
- return 16;
- }
-
- /****************************************************************************
- * Routine to push current font type and text attributes. *
- ****************************************************************************/
- void GRPushTextSetting(void)
- {
- if (TextSettingStackPtr >= TEXT_SETTING_STACK_SIZE)
- IntrFatalError("Text setting stack overflow.");
-
- TextSettingStack[TextSettingStackPtr].HorizJustify = CrntHorizCenter;
- TextSettingStack[TextSettingStackPtr++].VertJustify = CrntVertCenter;
- }
-
- /****************************************************************************
- * Routine to pop current font type and text attributes. *
- ****************************************************************************/
- void GRPopTextSetting(void)
- {
- if (--TextSettingStackPtr < 0)
- IntrFatalError("Text setting stack underflow.");
-
- CrntHorizCenter = TextSettingStack[TextSettingStackPtr].HorizJustify;
- CrntVertCenter = TextSettingStack[TextSettingStackPtr].VertJustify;
- }
-
- /****************************************************************************
- * Routine to set color to color within range. *
- ****************************************************************************/
- void GRSetColor(int Color)
- {
- if (Color >= GRScreenMaxColors)
- Color = Color % (GRScreenMaxColors - 1) + 1;
- GRCrntColor = Color;
- }
-
- /****************************************************************************
- * Routine to get current active color. *
- ****************************************************************************/
- int GRGetColor(void)
- {
- return GRCrntColor;
- }
-
- /****************************************************************************
- * Routine to set one color index RGB values. *
- ****************************************************************************/
- void GRSetRGBPalette(int Index, int Red, int Green, int Blue)
- {
- GrSetColor(Index, Red, Green, Blue);
- }
-
- /*****************************************************************************
- * Routine to clear all the screen. *
- *****************************************************************************/
- void GRClearAllScreen(void)
- {
- ScrnRegion->Box(0, 0, GRScreenMaxX, GRScreenMaxY, BLACK);
- }
-
- /*****************************************************************************
- * Routine to clear given rectangle viewport. *
- *****************************************************************************/
- void GRClearViewPort(int x1, int y1, int x2, int y2)
- {
- ScrnRegion->Box(x1, y1, x2, y2, BLACK);
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void _GRSetViewPort(int x1, int y1, int x2, int y2)
- {
- _GRSetViewPort2(x1, y1, x2, y2, TRUE);
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void _GRSetViewPort2(int x1, int y1, int x2, int y2, IntrBType Clip)
- {
- if (CrntRegion != ScrnRegion)
- delete CrntRegion;
- CrntRegion = ScrnRegion->SubRegion(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void GRGetViewPort(int *x1, int *y1, int *x2, int *y2)
- {
- *x1 = CrntRegion -> abs_x;
- *y1 = CrntRegion -> abs_y;
- *x2 = CrntRegion -> width + CrntRegion -> abs_x - 1;
- *y2 = CrntRegion -> height + CrntRegion -> abs_y - 1;
- }
-
- /*****************************************************************************
- * Routine to set given rectangle viewport. *
- *****************************************************************************/
- void GRSetViewPort(int x1, int y1, int x2, int y2)
- {
- _GRSetViewPort2(x1, y1, x2, y2, TRUE);
- GRWidth2 = (x2 - x1) / 2;
- GRHeight2 = (y2 - y1) / 2;
- GRMinX = x1;
- GRMinY = y1;
- }
-
- /*****************************************************************************
- * Routine to push current view port. *
- *****************************************************************************/
- void GRPushViewPort(void)
- {
- if (ViewPortStackPtr >= VIEW_PORT_STACK_SIZE)
- IntrFatalError("View port stack overflow.");
-
- ViewPortStack[ViewPortStackPtr++] = CrntRegion;
- CrntRegion = ScrnRegion;
- }
-
- /*****************************************************************************
- * Routine to pop current view port. *
- *****************************************************************************/
- void GRPopViewPort(void)
- {
- if (--ViewPortStackPtr < 0)
- IntrFatalError("View port stack underflow.");
-
- CrntRegion = ViewPortStack[ViewPortStackPtr];
- GRWidth2 = CrntRegion->width / 2;
- GRHeight2 = CrntRegion->height / 2;
- GRMinX = CrntRegion->abs_x;
- GRMinY = CrntRegion->abs_y;
- }
-
- /*****************************************************************************
- * Routine to read one line terminated by <Enter> and visualized on graphic *
- * screen. *
- * Full line editing is supported which includes: *
- * 1. Right and left arrows to move along the line. *
- * 2. Up and down arrows to cirlce along a history buffer. *
- * 3. Delete to delete current character. *
- * 4. Insert to toggle Insert/Overwrite mode. *
- * 5. Backspace to delete character before current one. *
- * 6. Home/End to move to beginning/End of string respectively. *
- * 7. Return to accept current line. *
- * 8. Esc to clear current line. *
- * If s is not empty it is used as starting string. *
- * Line is drawn starting from position x, y on screen (normalized -1..1). *
- *****************************************************************************/
- void GRGetGraphicLine(int WindowID, int x, int y, char s[], int SLen,
- int WindowLen, int ForeColor, int BackColor)
- {
- static int
- Insert = TRUE;
- int NextKey, FirstVisible, i,
- Xstep = 8, /* Basically the font size. */
- Len = strlen(s),
- CursorPos = Len,
- FirstTime = TRUE,
- EndOfString = FALSE,
- HistoryBufCrnt = -1;
- char DisplayLine[GR_LINE_LEN], *Cursor;
- _IntrWindowStruct
- *Window = WindowID ? _IntrFindWndwUsingID(WindowID) : NULL;
- IntrBBoxStruct
- *BBox = Window ? &Window -> BBox : NULL;
- struct GrRegion
- *WRegion = BBox ? ScrnRegion->SubRegion(BBox -> Xmin,
- BBox -> Ymin,
- BBox -> Xmax - BBox -> Xmin + 1,
- BBox -> Ymax - BBox -> Ymin + 1)
- : ScrnRegion;
-
- GRPushTextSetting();
- GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
-
- while (!EndOfString) {
- /* Can not display the whole string, so set first visible char: */
- FirstVisible = CursorPos > WindowLen - 2 ? CursorPos - WindowLen + 2
- : 0;
-
- /* Prepare the part of s to be displayed: */
- strncpy(DisplayLine, &s[FirstVisible], GR_LINE_LEN - 1);
- DisplayLine[MIN(WindowLen, GR_LINE_LEN - 1)] = 0;
-
- Cursor = (Insert ? "_" : "-");
-
- WRegion->Text(x, y, DisplayLine, ForeColor, BackColor);
- WRegion->Text(x + (CursorPos - FirstVisible) * Xstep, y, Cursor,
- WHITE, -1);
-
- if ((NextKey = GRGetKey()) != KEY_REFRESH || FirstTime) {
- WRegion->Text(x, y, DisplayLine, BackColor, BackColor);
- WRegion->Text(x + (CursorPos - FirstVisible) * Xstep, y, Cursor,
- BackColor, -1);
- }
- FirstTime = FALSE;
-
- switch (NextKey) {
- case KEY_BSPACE:
- if (CursorPos == 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- MoveOverlapMem(&s[CursorPos - 1], &s[CursorPos],
- Len - CursorPos + 1);
- CursorPos--;
- Len--;
- break;
- case KEY_DELETE:
- if (CursorPos >= Len) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- MoveOverlapMem(&s[CursorPos], &s[CursorPos + 1],
- Len - CursorPos);
- Len--;
- break;
- case KEY_RIGHT:
- if (CursorPos >= Len) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- CursorPos++;
- break;
- case KEY_LEFT:
- if (CursorPos <= 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
- CursorPos--;
- break;
- case KEY_UP:
- if (HistoryBufLen == 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
-
- if (++HistoryBufCrnt >= HistoryBufLen) HistoryBufCrnt = 0;
-
- strcpy(s, HistoryBuffer[HistoryBufCrnt]);
- CursorPos = Len = strlen(s);
- break;
- case KEY_DOWN:
- if (HistoryBufLen == 0) {
- GRTone(1000, 100); /* Do some noise... */
- break;
- }
-
- if (--HistoryBufCrnt < 0) HistoryBufCrnt = HistoryBufLen - 1;
-
- strcpy(s, HistoryBuffer[HistoryBufCrnt]);
- CursorPos = Len = strlen(s);
- break;
- case KEY_RETURN:
- EndOfString = TRUE;
- break;
- case KEY_ESC:
- Len = 0; /* Clear everything. */
- CursorPos = 0;
- s[0] = 0;
- break;
- case KEY_HOME:
- CursorPos = 0;
- break;
- case KEY_END:
- CursorPos = Len;
- break;
- case KEY_INSERT:
- Insert = !Insert;
- break;
- case KEY_NONE:
- GRTone(1000, 100); /* Do some noise... */
- GRTone(500, 200);
- break;
- case KEY_REFRESH: /* Internal event to intr_lib. */
- if (Window != NULL) {
- _GRSetViewPort(Window -> BBox.Xmin, Window -> BBox.Ymin,
- Window -> BBox.Xmax, Window -> BBox.Ymax);
- x = TEXT_BORDER,
- y = Window -> BBox.Ymax - Window -> BBox.Ymin -
- TEXT_BORDER - GRGetTextHeight("M");
- }
- GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
- break;
- default: /* Regular ascii char. */
- if (Insert) {
- MoveOverlapMem(&s[CursorPos + 1], &s[CursorPos],
- Len - CursorPos + 1);
- Len++;
- }
- else if (CursorPos == Len)
- Len++; /* We are on last character. */
- s[CursorPos++] = NextKey;
- if (CursorPos == Len) s[CursorPos] = 0;
- break;
- }
- if (SLen <= Len - 1) { /* End of buffer - can not save more info. */
- Len = SLen - 1;
- if (CursorPos > Len) CursorPos = Len;
- GRTone(1000, 100); /* Do some noise... */
- }
- }
-
- GRPopTextSetting();
-
- /* Update the history buffer: */
- for (i = HISTORY_SIZE - 1; i > 0; i--)
- strncpy(HistoryBuffer[i], HistoryBuffer[i - 1], GR_LINE_LEN);
- strncpy(HistoryBuffer[0], s, GR_LINE_LEN);
- HistoryBufLen = MIN(HISTORY_SIZE, HistoryBufLen + 1);
-
- if (WRegion != ScrnRegion) delete WRegion;
- }
-
- /*****************************************************************************
- * Same as memcpy but allow Src and Dest to overlap. *
- *****************************************************************************/
- static void MoveOverlapMem(char *Dest, char *Src, int Len)
- {
- char TempStr[GR_LINE_LEN];
-
- memcpy(TempStr, Src, Len);
- memcpy(Dest, TempStr, Len);
- }
-
- /*****************************************************************************
- * Sets the function invoked to get a kbd event in GRGetKey. *
- * NULL will recover the internal default - IntrGetEventWait. *
- *****************************************************************************/
- void GRSetGetKeyFunc(IntrInt2PtrFunc GetChFunc)
- {
- if (GetChFunc == NULL)
- GlblGetChFunc = IntrGetEventWait;
- else
- GlblGetChFunc = GetChFunc;
- }
-
- /*****************************************************************************
- * Get a key from keyboard, and translating operational keys into special *
- * codes (>255). *
- *****************************************************************************/
- static int GRGetKey(void)
- {
- int x, y;
-
- /* Detach the keyboard from moving the mouse so keyboard can be used to */
- /* edit the input line instead. */
- _IntrDetachKbdFromMouse = TRUE;
- while (GlblGetChFunc(&x, &y) != INTR_EVNT_KEY);
- _IntrDetachKbdFromMouse = FALSE;
-
- if (x >= 256) {
- switch (x - 256) { /* Extended code - get the next extended char. */
- case 72:
- return KEY_UP;
- case 80:
- return KEY_DOWN;
- case 75:
- return KEY_LEFT;
- case 77:
- return KEY_RIGHT;
- case 71:
- return KEY_HOME;
- case 79:
- return KEY_END;
- case 83:
- return KEY_DELETE;
- case 82:
- return KEY_INSERT;
- case KEY_REFRESH - 256:
- return KEY_REFRESH;
- }
- }
- else {
- switch (x) {
- case 8:
- return KEY_BSPACE;
- case 10:
- case 13:
- return KEY_RETURN;
- case 27:
- return KEY_ESC;
- default:
- if (isprint(x)) return x;
- }
- }
-
- return KEY_NONE;
- }
-
- /*****************************************************************************
- * Routine to delay the specified amount in millisec. *
- *****************************************************************************/
- extern "C" void delay(int time)
- {
- int i,
- j = 0;
-
- for (i = 0; i < 50000; i++) j += i + 5; /* basically wait. */
- }
-
- /*****************************************************************************
- * Routine to make some sound with given Frequency, Time milliseconds: *
- *****************************************************************************/
- void GRTone(int Frequency, int Duration)
- {
- sound(Frequency);
-
- delay(Duration);
-
- sound(0);
- }
-