home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Programmierung / SOURCE.mdf / programm / msdos / c / djgpp / libsrc / gr / region.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-10  |  6.9 KB  |  357 lines

  1. /* This is file REGION.CC */
  2. /*
  3. ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  4. **
  5. ** This file is distributed under the terms listed in the document
  6. ** "copying.dj", available from DJ Delorie at the address above.
  7. ** A copy of "copying.dj" should accompany this file; if not, a copy
  8. ** should be available from where this file was obtained.  This file
  9. ** may not be distributed without a verbatim copy of "copying.dj".
  10. **
  11. ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  12. ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. */
  14.  
  15. /* History:251,33 */
  16. #include <std.h>
  17. #include <sys/registers.h>
  18. #include "graphics.h"
  19.  
  20. static GrRegion *screen_region = 0;
  21. extern int _GrCurMode;
  22.  
  23. static void SetModeHook()
  24. {
  25.   screen_region->width = GrSizeX();
  26.   screen_region->height = GrSizeY();
  27.   screen_region->row_scale = GrSizeX();
  28.   screen_region->data = (unsigned char *)0xd0000000;
  29.   screen_region->rdata = (unsigned char *)0xd0100000;
  30.   screen_region->wdata = (unsigned char *)0xd0200000;
  31. }
  32.  
  33. extern int _GrSetModeHook;
  34.  
  35. GrRegion *GrScreenRegion()
  36. {
  37.   if (_GrCurMode < GR_320_200_graphics)
  38.     GrSetMode(GR_default_graphics);
  39.   if (!screen_region)
  40.     screen_region = new GrRegion();
  41.   _GrSetModeHook = (int)SetModeHook;
  42.   SetModeHook();
  43.   return screen_region;
  44. }
  45.  
  46. GrRegion::GrRegion()
  47. {
  48.   flags = width = height = row_scale = 0;
  49.   rdata = wdata = data = 0;
  50.   parent = 0;
  51.   rel_x = rel_y = abs_x = abs_y = 0;
  52.   color = GrWhite();
  53. }
  54.  
  55. GrRegion::GrRegion(int w, int h)
  56. {
  57.   flags = 1;
  58.   rdata = wdata = data = (unsigned char *)malloc(w*h);
  59.   bzero(data,w*h);
  60.   width = w;
  61.   height = h;
  62.   row_scale = w;
  63.   color = GrWhite();
  64.   parent = 0;
  65.   rel_x = rel_y = abs_x = abs_y = 0;
  66. }
  67.  
  68. GrRegion::~GrRegion()
  69. {
  70.   if (flags && data)
  71.     free(data);
  72. }
  73.  
  74. GrRegion *GrRegion::SubRegion(int x, int y, int w, int h)
  75. {
  76.   if (!data) return 0;
  77.   GrRegion *tmp = new GrRegion();
  78.   if (!tmp) return 0;
  79.   if ((x < 0) || (y < 0))
  80.     return tmp;
  81.   if ((x >= width) || (y >= height))
  82.     return tmp;
  83.   if (x+w > width)
  84.     w = width - x;
  85.   if (y+h > height)
  86.     h = height - y;
  87.   tmp->parent = this;
  88.   tmp->rel_x = x;
  89.   tmp->rel_y = y;
  90.   tmp->abs_x = x + rel_x;
  91.   tmp->abs_y = y + rel_y;
  92.   tmp->data = data + y*row_scale + x;
  93.   tmp->rdata = rdata + y*row_scale + x;
  94.   tmp->wdata = wdata + y*row_scale + x;
  95.   tmp->width = w;
  96.   tmp->height = h;
  97.   tmp->row_scale = row_scale;
  98.   return tmp;
  99. }
  100.  
  101. int GrRegion::MaxX()
  102. {
  103.   return width-1;
  104. }
  105.  
  106. int GrRegion::MaxY()
  107. {
  108.   return height-1;
  109. }
  110.  
  111. int GrRegion::SizeX()
  112. {
  113.   return width;
  114. }
  115.  
  116. int GrRegion::SizeY()
  117. {
  118.   return height;
  119. }
  120.  
  121. void GrRegion::Plot(int x, int y, int c)
  122. {
  123.   if (!data) return;
  124.   if (c == -1) c = color;
  125.   if ((x < 0) || (y < 0) || (x >= width) || (y >= height))
  126.     return;
  127.   if (c & 0x100)
  128.     data[x+y*row_scale] ^= c;
  129.   else
  130.     data[x+y*row_scale] = c;
  131. }
  132.  
  133. void GrRegion::Line(int x1, int y1, int x2, int y2, int c)
  134. {
  135.   if (!data) return;
  136.   if (c == -1) c = color;
  137.   if (x1 == x2)
  138.   {
  139.     VLine(x1, y1, y2, c);
  140.     return;
  141.   }
  142.   if (y1 == y2)
  143.   {
  144.     HLine(x1, x2, y1, c);
  145.     return;
  146.   }
  147.  
  148.   int dx, dy, sx, sy;
  149.   int count;
  150.   int brc, brmax;
  151.  
  152.   sx = sy = 1;
  153.   dx = x2 - x1;
  154.   dy = y2 - y1;
  155.   if (dx < 0)
  156.   {
  157.     dx *= -1;
  158.     sx *= -1;
  159.   }
  160.   if (dy < 0)
  161.   {
  162.     dy *= -1;
  163.     sy *= -1;
  164.   }
  165.   if (dx > dy)
  166.   {
  167.     brmax = dx;
  168.     brc = dx / 2;
  169.     Plot(x1, y1, c);
  170.     for (count = dx; count; count--)
  171.     {
  172.       x1 += sx;
  173.       brc += dy;
  174.       if (brc > brmax)
  175.       {
  176.         brc -= dx;
  177.         y1 += sy;
  178.       }
  179.       Plot(x1, y1, c);
  180.     }
  181.   }
  182.   else
  183.   {
  184.     brmax = dy;
  185.     brc = dy / 2;
  186.     Plot(x1, y1, c);
  187.     for (count = dy; count; count--)
  188.     {
  189.       y1 += sy;
  190.       brc += dx;
  191.       if (brc > brmax)
  192.       {
  193.         brc -= dy;
  194.         x1 += sx;
  195.       }
  196.       Plot(x1, y1, c);
  197.     }
  198.   }
  199. }
  200.  
  201. void GrRegion::HLine(int x1, int x2, int y, int c)
  202. {
  203.   if (!data) return;
  204.   if (c == -1) c = color;
  205.   if ((y < 0) || (y >= height))
  206.     return;
  207.   if (x1 > x2)
  208.   {
  209.     x1 ^= x2; x2 ^= x1; x1 ^= x2;
  210.   }
  211.   if ((x1 >= width) || (x2 < 0))
  212.     return;
  213.   if (x1 < 0) x1 = 0;
  214.   if (x2 >= width) x2 = width - 1;
  215.   if (c & 0x100)
  216.   {
  217.     register int cnt=x2-x1+1;
  218.     register unsigned char *ptr = data+x1+y*row_scale;
  219.     while(cnt--)
  220.       *ptr++ ^= c;
  221.   }
  222.   else
  223.     memset(data + x1 + y * row_scale, c, x2 - x1 + 1);
  224. }
  225.  
  226. void GrRegion::VLine(int x, int y1, int y2, int c)
  227. {
  228.   if (!data) return;
  229.   if (c == -1) c = color;
  230.   if ((x < 0) || (x >= width))
  231.     return;
  232.   if (y1 > y2)
  233.   {
  234.     y1 ^= y2; y2 ^= y1; y1 ^= y2;
  235.   }
  236.   if ((y1 >= height) || (y2 < 0))
  237.     return;
  238.   if (y1 < 0) y1 = 0;
  239.   if (y2 >= height) y2 = height-1;
  240.   register unsigned char *ptr = data + y1 * row_scale + x;
  241.   register int yc=y2-y1+1;
  242.   register int rs = row_scale;
  243.   if (c & 0x100)
  244.   {
  245.     for (; yc; yc--, ptr+=rs)
  246.       *ptr ^= c;
  247.   }
  248.   else
  249.   {
  250.     for (; yc; yc--, ptr+=rs)
  251.       *ptr = c;
  252.   }
  253. }
  254.  
  255. void GrRegion::Rectangle(int x1, int y1, int x2, int y2, int c)
  256. {
  257.   if (!data) return;
  258.   if (c == -1) c = color;
  259.   if (x1 > x2)
  260.   {
  261.     x1 ^= x2; x2 ^= x1; x1 ^= x2;
  262.   }
  263.   if (y1 > y2)
  264.   {
  265.     y1 ^= y2; y2 ^= y1; y1 ^= y2;
  266.   }
  267.   if ((x1 == x2) || (y1 == y2))
  268.   {
  269.     Line(x1, y1, x2, y2, c);
  270.     return;
  271.   }
  272.   Line(x1, y1, x2, y1, c);    // top
  273.   Line(x1, y1+1, x1, y2, c);    // left
  274.   Line(x2, y1+1, x2, y2, c);    // right
  275.   Line(x1+1, y2, x2-1, y2, c);    // botton
  276. }
  277.  
  278. void GrRegion::Box(int x, int y, int w, int h, int c)
  279. {
  280.   if (!data) return;
  281.   if (c == -1) c = color;
  282.   if (x < 0)
  283.   {
  284.     w += x;
  285.     x = 0;
  286.   }
  287.   if (y < 0)
  288.   {
  289.     h += y;
  290.     y = 0;
  291.   }
  292.   if (x > width)
  293.     return;
  294.   if (y > height)
  295.     return;
  296.   if (w > width)
  297.     w = width;
  298.   if (h > height)
  299.     h = height;
  300.   if ((w <= 0) || (h <= 0))
  301.     return;
  302.   if (c & 0x100)
  303.   {
  304.     while (h--)
  305.       HLine(x, x+w-1, y++, c);
  306.   }
  307.   else
  308.   {
  309.     while (h--)
  310.       memset(data+x+(y++)*row_scale, c, w);
  311.   }
  312. }
  313.  
  314. static unsigned char *fontptr=0;
  315.  
  316. extern "C" void int10(REGISTERS *);
  317.  
  318. void GrRegion::Text(int x, int y, char *text, int fgc, int bgc)
  319. {
  320.   if (!data) return;
  321.   if (fgc == -1) fgc = color;
  322.   if (!fontptr)
  323.   {
  324.     REGISTERS r;
  325.     r.ax = 0x1130;
  326. #define CHARHEIGHT 16 /* must correspond to value below */
  327.     r.bx = 0x0600;
  328.     int10(&r);
  329.     fontptr = (unsigned char *)r.bp;
  330.   }
  331.   int r, c, bits;
  332.   unsigned char *fp;
  333.   while (*text)
  334.   {
  335.     fp = fontptr + CHARHEIGHT * *text;
  336.     for (r=0; r<CHARHEIGHT; r++)
  337.     {
  338.       bits = *fp++;
  339.       for (c=0; c<8; c++)
  340.         if (bits & (0x80>>c))
  341.           Plot(x+c, y+r, fgc);
  342.         else if (bgc != -1)
  343.           Plot(x+c, y+r, bgc);
  344.     }
  345.     text++;
  346.     x += 8;
  347.   }
  348. }
  349.  
  350. int GrRegion::Point(int x, int y)
  351. {
  352.   if (!data) return 0;
  353.   if ((x < 0) || (y < 0) || (x >= width) || (y >= height))
  354.     return 0;
  355.   return data[x+y*row_scale];
  356. }
  357.