home *** CD-ROM | disk | FTP | other *** search
- /* This is file REGION.CC */
- /*
- ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
- **
- ** This file is distributed under the terms listed in the document
- ** "copying.dj", available from DJ Delorie at the address above.
- ** A copy of "copying.dj" should accompany this file; if not, a copy
- ** should be available from where this file was obtained. This file
- ** may not be distributed without a verbatim copy of "copying.dj".
- **
- ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
- ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- */
-
- /* History:251,33 */
- #include <std.h>
- #include <sys/registers.h>
- #include "graphics.h"
-
- static GrRegion *screen_region = 0;
- extern int _GrCurMode;
-
- static void SetModeHook()
- {
- screen_region->width = GrSizeX();
- screen_region->height = GrSizeY();
- screen_region->row_scale = GrSizeX();
- screen_region->data = (unsigned char *)0xd0000000;
- screen_region->rdata = (unsigned char *)0xd0100000;
- screen_region->wdata = (unsigned char *)0xd0200000;
- }
-
- extern int _GrSetModeHook;
-
- GrRegion *GrScreenRegion()
- {
- if (_GrCurMode < GR_320_200_graphics)
- GrSetMode(GR_default_graphics);
- if (!screen_region)
- screen_region = new GrRegion();
- _GrSetModeHook = (int)SetModeHook;
- SetModeHook();
- return screen_region;
- }
-
- GrRegion::GrRegion()
- {
- flags = width = height = row_scale = 0;
- rdata = wdata = data = 0;
- parent = 0;
- rel_x = rel_y = abs_x = abs_y = 0;
- color = GrWhite();
- }
-
- GrRegion::GrRegion(int w, int h)
- {
- flags = 1;
- rdata = wdata = data = (unsigned char *)malloc(w*h);
- bzero(data,w*h);
- width = w;
- height = h;
- row_scale = w;
- color = GrWhite();
- parent = 0;
- rel_x = rel_y = abs_x = abs_y = 0;
- }
-
- GrRegion::~GrRegion()
- {
- if (flags && data)
- free(data);
- }
-
- GrRegion *GrRegion::SubRegion(int x, int y, int w, int h)
- {
- if (!data) return 0;
- GrRegion *tmp = new GrRegion();
- if (!tmp) return 0;
- if ((x < 0) || (y < 0))
- return tmp;
- if ((x >= width) || (y >= height))
- return tmp;
- if (x+w > width)
- w = width - x;
- if (y+h > height)
- h = height - y;
- tmp->parent = this;
- tmp->rel_x = x;
- tmp->rel_y = y;
- tmp->abs_x = x + rel_x;
- tmp->abs_y = y + rel_y;
- tmp->data = data + y*row_scale + x;
- tmp->rdata = rdata + y*row_scale + x;
- tmp->wdata = wdata + y*row_scale + x;
- tmp->width = w;
- tmp->height = h;
- tmp->row_scale = row_scale;
- return tmp;
- }
-
- int GrRegion::MaxX()
- {
- return width-1;
- }
-
- int GrRegion::MaxY()
- {
- return height-1;
- }
-
- int GrRegion::SizeX()
- {
- return width;
- }
-
- int GrRegion::SizeY()
- {
- return height;
- }
-
- void GrRegion::Plot(int x, int y, int c)
- {
- if (!data) return;
- if (c == -1) c = color;
- if ((x < 0) || (y < 0) || (x >= width) || (y >= height))
- return;
- if (c & 0x100)
- data[x+y*row_scale] ^= c;
- else
- data[x+y*row_scale] = c;
- }
-
- void GrRegion::Line(int x1, int y1, int x2, int y2, int c)
- {
- if (!data) return;
- if (c == -1) c = color;
- if (x1 == x2)
- {
- VLine(x1, y1, y2, c);
- return;
- }
- if (y1 == y2)
- {
- HLine(x1, x2, y1, c);
- return;
- }
-
- int dx, dy, sx, sy;
- int count;
- int brc, brmax;
-
- sx = sy = 1;
- dx = x2 - x1;
- dy = y2 - y1;
- if (dx < 0)
- {
- dx *= -1;
- sx *= -1;
- }
- if (dy < 0)
- {
- dy *= -1;
- sy *= -1;
- }
- if (dx > dy)
- {
- brmax = dx;
- brc = dx / 2;
- Plot(x1, y1, c);
- for (count = dx; count; count--)
- {
- x1 += sx;
- brc += dy;
- if (brc > brmax)
- {
- brc -= dx;
- y1 += sy;
- }
- Plot(x1, y1, c);
- }
- }
- else
- {
- brmax = dy;
- brc = dy / 2;
- Plot(x1, y1, c);
- for (count = dy; count; count--)
- {
- y1 += sy;
- brc += dx;
- if (brc > brmax)
- {
- brc -= dy;
- x1 += sx;
- }
- Plot(x1, y1, c);
- }
- }
- }
-
- void GrRegion::HLine(int x1, int x2, int y, int c)
- {
- if (!data) return;
- if (c == -1) c = color;
- if ((y < 0) || (y >= height))
- return;
- if (x1 > x2)
- {
- x1 ^= x2; x2 ^= x1; x1 ^= x2;
- }
- if ((x1 >= width) || (x2 < 0))
- return;
- if (x1 < 0) x1 = 0;
- if (x2 >= width) x2 = width - 1;
- if (c & 0x100)
- {
- register int cnt=x2-x1+1;
- register unsigned char *ptr = data+x1+y*row_scale;
- while(cnt--)
- *ptr++ ^= c;
- }
- else
- memset(data + x1 + y * row_scale, c, x2 - x1 + 1);
- }
-
- void GrRegion::VLine(int x, int y1, int y2, int c)
- {
- if (!data) return;
- if (c == -1) c = color;
- if ((x < 0) || (x >= width))
- return;
- if (y1 > y2)
- {
- y1 ^= y2; y2 ^= y1; y1 ^= y2;
- }
- if ((y1 >= height) || (y2 < 0))
- return;
- if (y1 < 0) y1 = 0;
- if (y2 >= height) y2 = height-1;
- register unsigned char *ptr = data + y1 * row_scale + x;
- register int yc=y2-y1+1;
- register int rs = row_scale;
- if (c & 0x100)
- {
- for (; yc; yc--, ptr+=rs)
- *ptr ^= c;
- }
- else
- {
- for (; yc; yc--, ptr+=rs)
- *ptr = c;
- }
- }
-
- void GrRegion::Rectangle(int x1, int y1, int x2, int y2, int c)
- {
- if (!data) return;
- if (c == -1) c = color;
- if (x1 > x2)
- {
- x1 ^= x2; x2 ^= x1; x1 ^= x2;
- }
- if (y1 > y2)
- {
- y1 ^= y2; y2 ^= y1; y1 ^= y2;
- }
- if ((x1 == x2) || (y1 == y2))
- {
- Line(x1, y1, x2, y2, c);
- return;
- }
- Line(x1, y1, x2, y1, c); // top
- Line(x1, y1+1, x1, y2, c); // left
- Line(x2, y1+1, x2, y2, c); // right
- Line(x1+1, y2, x2-1, y2, c); // botton
- }
-
- void GrRegion::Box(int x, int y, int w, int h, int c)
- {
- if (!data) return;
- if (c == -1) c = color;
- if (x < 0)
- {
- w += x;
- x = 0;
- }
- if (y < 0)
- {
- h += y;
- y = 0;
- }
- if (x > width)
- return;
- if (y > height)
- return;
- if (w > width)
- w = width;
- if (h > height)
- h = height;
- if ((w <= 0) || (h <= 0))
- return;
- if (c & 0x100)
- {
- while (h--)
- HLine(x, x+w-1, y++, c);
- }
- else
- {
- while (h--)
- memset(data+x+(y++)*row_scale, c, w);
- }
- }
-
- static unsigned char *fontptr=0;
-
- extern "C" void int10(REGISTERS *);
-
- void GrRegion::Text(int x, int y, char *text, int fgc, int bgc)
- {
- if (!data) return;
- if (fgc == -1) fgc = color;
- if (!fontptr)
- {
- REGISTERS r;
- r.ax = 0x1130;
- #define CHARHEIGHT 16 /* must correspond to value below */
- r.bx = 0x0600;
- int10(&r);
- fontptr = (unsigned char *)r.bp;
- }
- int r, c, bits;
- unsigned char *fp;
- while (*text)
- {
- fp = fontptr + CHARHEIGHT * *text;
- for (r=0; r<CHARHEIGHT; r++)
- {
- bits = *fp++;
- for (c=0; c<8; c++)
- if (bits & (0x80>>c))
- Plot(x+c, y+r, fgc);
- else if (bgc != -1)
- Plot(x+c, y+r, bgc);
- }
- text++;
- x += 8;
- }
- }
-
- int GrRegion::Point(int x, int y)
- {
- if (!data) return 0;
- if ((x < 0) || (y < 0) || (x >= width) || (y >= height))
- return 0;
- return data[x+y*row_scale];
- }
-