home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1992 / 06 / dflt12 / video.c < prev    next >
Text File  |  1992-04-17  |  8KB  |  303 lines

  1. /* --------------------- video.c -------------------- */
  2.  
  3. #include "dflat.h"
  4.  
  5. BOOL ClipString;
  6.  
  7. static unsigned video_address;
  8.  
  9. /* -- swap a rectangle of video memory with a save buffer -- */
  10. void swapvideo(WINDOW wnd, void far *bf, BOOL Hiding, BOOL Noload)
  11. {
  12.     char *hd, *hadr;
  13.     int ht, bytes_row, bytestobuf, bytesfrbuf, bufferwidth;
  14.     RECT rc = WindowRect(wnd);
  15.     unsigned vadr = vad(RectLeft(rc), RectTop(rc));
  16.     BOOL TopLine = TRUE, Htrimmed, Vtrimmed;
  17.  
  18.     if (TestAttribute(wnd, SHADOW))    {
  19.         RectBottom(rc)++;
  20.         RectRight(rc)++;
  21.     }
  22.     ht = RectBottom(rc)-RectTop(rc)+1;
  23.  
  24.     if ((Vtrimmed = RectTop(rc) + ht > SCREENHEIGHT) == TRUE)
  25.         ht = SCREENHEIGHT - RectTop(rc);
  26.  
  27.     bufferwidth = bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2;
  28.  
  29.     if ((Htrimmed = RectLeft(rc) + bytes_row/2 > SCREENWIDTH) == TRUE)
  30.         bytes_row = (SCREENWIDTH - RectLeft(rc)) * 2;
  31.  
  32.     hd = hadr = DFmalloc(bytes_row);
  33.  
  34.     hide_mousecursor();
  35.     while (ht--)    {
  36.         bytestobuf = bytesfrbuf = bytes_row;
  37.         if (TestAttribute(wnd, SHADOW))    {
  38.             if (TopLine)    {
  39.                 if (!Htrimmed)    {
  40.                     bytestobuf -= 2;
  41.                     bytesfrbuf -= 2;
  42.                 }
  43.             }
  44.             else if (ht == 0 && !Vtrimmed)    {
  45.                 bytestobuf -= 2;
  46.                 bytesfrbuf -= 2;
  47.                 vadr += 2;
  48.                 hadr += 2;
  49.                 bf = (char far *)bf + 2;
  50.             }
  51.             if (!TopLine && !Hiding && !Htrimmed)
  52.                 bytesfrbuf -= 2;
  53.             TopLine = FALSE;
  54.         }
  55.         else
  56.             bytestobuf = bytesfrbuf = bytes_row;
  57.         /* ----- getvideo | swapvideo ------- */
  58.         if (!Noload)
  59.             movedata(video_address, vadr, FP_SEG(hadr),
  60.                 FP_OFF(hadr), bytestobuf);
  61.         /* ----- storevideo | swapvideo ------- */
  62.         if (ht || Hiding || !TestAttribute(wnd, SHADOW) || Vtrimmed)
  63.             movedata(FP_SEG(bf), FP_OFF(bf), video_address,
  64.                 vadr, bytesfrbuf);
  65.         /* ----- swapvideo ------- */
  66.         if (!Noload)
  67.             movedata(FP_SEG(hadr), FP_OFF(hadr), FP_SEG(bf),
  68.                 FP_OFF(bf), bytestobuf);
  69.         vadr += SCREENWIDTH*2;
  70.         bf = (char far *)bf + bufferwidth;
  71.     }
  72.     free(hd);
  73.     if (Noload)    {
  74.         free(wnd->videosave);
  75.         wnd->videosave = NULL;
  76.     }
  77.     if (!Hiding)
  78.         PaintShadow(wnd);
  79.     show_mousecursor();
  80. }
  81.  
  82. /* -- read a rectangle of video memory into a save buffer -- */
  83. void getvideo(RECT rc, void far *bf)
  84. {
  85.     int ht = RectBottom(rc)-RectTop(rc)+1;
  86.     int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2;
  87.     unsigned vadr = vad(RectLeft(rc), RectTop(rc));
  88.     hide_mousecursor();
  89.     while (ht--)    {
  90.         movedata(video_address, vadr, FP_SEG(bf),
  91.                 FP_OFF(bf), bytes_row);
  92.         vadr += SCREENWIDTH*2;
  93.         bf = (char far *)bf + bytes_row;
  94.     }
  95.     show_mousecursor();
  96. }
  97.  
  98. /* -- write a rectangle of video memory from a save buffer -- */
  99. void storevideo(RECT rc, void far *bf)
  100. {
  101.     int ht = RectBottom(rc)-RectTop(rc)+1;
  102.     int bytes_row = (RectRight(rc)-RectLeft(rc)+1) * 2;
  103.     unsigned vadr = vad(RectLeft(rc), RectTop(rc));
  104.     hide_mousecursor();
  105.     while (ht--)    {
  106.         movedata(FP_SEG(bf), FP_OFF(bf), video_address,
  107.                 vadr, bytes_row);
  108.         vadr += SCREENWIDTH*2;
  109.         bf = (char far *)bf + bytes_row;
  110.     }
  111.     show_mousecursor();
  112. }
  113.  
  114. /* -------- read a character of video memory ------- */
  115. unsigned int GetVideoChar(int x, int y)
  116. {
  117.     int c;
  118.     hide_mousecursor();
  119.     c = peek(video_address, vad(x,y));
  120.     show_mousecursor();
  121.     return c;
  122. }
  123.  
  124. /* -------- write a character of video memory ------- */
  125. void PutVideoChar(int x, int y, int c)
  126. {
  127.     if (x < SCREENWIDTH && y < SCREENHEIGHT)    {
  128.         hide_mousecursor();
  129.         poke(video_address, vad(x,y), c);
  130.         show_mousecursor();
  131.     }
  132. }
  133.  
  134. static BOOL isAncestor(WINDOW wnd, WINDOW awnd)
  135. {
  136.     while (wnd != NULL)    {
  137.         if (wnd == awnd)
  138.             return TRUE;
  139.         wnd = GetParent(wnd);
  140.     }
  141.     return FALSE;
  142. }
  143.  
  144. BOOL CharInView(WINDOW wnd, int x, int y)
  145. {
  146.     WINDOW nwnd = NextWindow(wnd);
  147.     WINDOW pwnd;
  148.     RECT rc;
  149.     int x1 = GetLeft(wnd)+x;
  150.     int y1 = GetTop(wnd)+y;
  151.  
  152.     if (!TestAttribute(wnd, VISIBLE))
  153.         return FALSE;
  154.     if (!TestAttribute(wnd, NOCLIP))    {
  155.         WINDOW wnd1 = GetParent(wnd);
  156.         while (wnd1 != NULL)    {
  157.             /* --- clip character to parent's borders -- */
  158.             if (!TestAttribute(wnd1, VISIBLE))
  159.                 return FALSE;
  160.             if (!InsideRect(x1, y1, ClientRect(wnd1)))
  161.                 return FALSE;
  162.             wnd1 = GetParent(wnd1);
  163.         }
  164.     }
  165.     while (nwnd != NULL)    {
  166.         if (!isHidden(nwnd) && !isAncestor(wnd, nwnd))    {
  167.             rc = WindowRect(nwnd);
  168.             if (TestAttribute(nwnd, SHADOW))    {
  169.                 RectBottom(rc)++;
  170.                 RectRight(rc)++;
  171.             }
  172.             if (!TestAttribute(nwnd, NOCLIP))    {
  173.                 pwnd = nwnd;
  174.                 while (GetParent(pwnd))    {
  175.                     pwnd = GetParent(pwnd);
  176.                     rc = subRectangle(rc, ClientRect(pwnd));
  177.                 }
  178.             }
  179.             if (InsideRect(x1,y1,rc))
  180.                 return FALSE;
  181.         }
  182.         nwnd = NextWindow(nwnd);
  183.     }
  184.     return (x1 < SCREENWIDTH && y1 < SCREENHEIGHT);
  185. }
  186.  
  187. /* -------- write a character to a window ------- */
  188. void wputch(WINDOW wnd, int c, int x, int y)
  189. {
  190.     if (CharInView(wnd, x, y))    {
  191.         hide_mousecursor();
  192.         poke(video_address,
  193.             vad(GetLeft(wnd)+x,GetTop(wnd)+y),(c & 255) |
  194.                 (clr(foreground, background) << 8));
  195.         show_mousecursor();
  196.     }
  197. }
  198.  
  199. /* ------- write a string to a window ---------- */
  200. void wputs(WINDOW wnd, void *s, int x, int y)
  201. {
  202.     int x1 = GetLeft(wnd)+x;
  203.     int x2 = x1;
  204.     int y1 = GetTop(wnd)+y;
  205.     if (x1 < SCREENWIDTH && y1 < SCREENHEIGHT && isVisible(wnd))    {
  206.         int ln[200];
  207.         int *cp1 = ln;
  208.         unsigned char *str = s;
  209.         int fg = foreground;
  210.         int bg = background;
  211.         int len;
  212.         int off = 0;
  213.         while (*str)    {
  214.             if (*str == CHANGECOLOR)    {
  215.                 str++;
  216.                 foreground = (*str++) & 0x7f;
  217.                 background = (*str++) & 0x7f;
  218.                 continue;
  219.             }
  220.             if (*str == RESETCOLOR)    {
  221.                 foreground = fg & 0x7f;
  222.                 background = bg & 0x7f;
  223.                 str++;
  224.                 continue;
  225.             }
  226.                *cp1 = (*str & 255) | (clr(foreground, background) << 8);
  227.             if (ClipString)
  228.                 if (!CharInView(wnd, x, y))
  229.                     *cp1 = peek(video_address, vad(x2,y1));
  230.             cp1++;
  231.             str++;
  232.             x++;
  233.             x2++;
  234.         }
  235.         foreground = fg;
  236.         background = bg;
  237.            len = (int)(cp1-ln);
  238.            if (x1+len > SCREENWIDTH)
  239.                len = SCREENWIDTH-x1;
  240.  
  241.         if (!ClipString && !TestAttribute(wnd, NOCLIP))    {
  242.             /* -- clip the line to within ancestor windows -- */
  243.             RECT rc = WindowRect(wnd);
  244.             WINDOW nwnd = GetParent(wnd);
  245.             while (len > 0 && nwnd != NULL)    {
  246.                 if (!isVisible(nwnd))    {
  247.                     len = 0;
  248.                     break;
  249.                 }
  250.                 rc = subRectangle(rc, ClientRect(nwnd));
  251.                 nwnd = GetParent(nwnd);
  252.             }
  253.             while (len > 0 && !InsideRect(x1+off,y1,rc))    {
  254.                 off++;
  255.                 --len;
  256.             }
  257.             if (len > 0)    {
  258.                 x2 = x1+len-1;
  259.                 while (len && !InsideRect(x2,y1,rc))    {
  260.                     --x2;
  261.                     --len;
  262.                 }
  263.             }
  264.         }
  265.         if (len > 0)    {
  266.             hide_mousecursor();
  267.             movedata(FP_SEG(ln), FP_OFF(ln+off),
  268.                 video_address, vad(x1+off,y1), len*2);
  269.             show_mousecursor();
  270.         }
  271.     }
  272. }
  273.  
  274. /* --------- get the current video mode -------- */
  275. void get_videomode(void)
  276. {
  277.     videomode();
  278.     /* ---- Monochrome Display Adaptor or text mode ---- */
  279.     if (ismono())
  280.         video_address = 0xb000;
  281.     else
  282.         /* ------ Text mode -------- */
  283.         video_address = 0xb800 + video_page;
  284. }
  285.  
  286. /* --------- scroll the window. d: 1 = up, 0 = dn ---------- */
  287. void scroll_window(WINDOW wnd, RECT rc, int d)
  288. {
  289.     union REGS regs;
  290.     hide_mousecursor();
  291.     regs.h.cl = RectLeft(rc);
  292.     regs.h.ch = RectTop(rc);
  293.     regs.h.dl = RectRight(rc);
  294.     regs.h.dh = RectBottom(rc);
  295.     regs.h.bh = clr(WndForeground(wnd),WndBackground(wnd));
  296.     regs.h.ah = 7 - d;
  297.     regs.h.al = 1;
  298.     int86(VIDEO, ®s, ®s);
  299.     show_mousecursor();
  300. }
  301.  
  302.  
  303.