home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / vg-2.03 / image.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  14.8 KB  |  884 lines

  1. /*
  2.  * Copyright (C) 1990-1992 Michael Davidson.
  3.  * All rights reserved.
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software
  6.  * and its documentation for any purpose and without fee is hereby
  7.  * granted, provided that the above copyright notice appear in all
  8.  * copies and that both that copyright notice and this permission
  9.  * notice appear in supporting documentation.
  10.  *
  11.  * This software is provided "as is" without express or implied warranty.
  12.  */
  13.  
  14. #include    <stdio.h>
  15. #include    <stdlib.h>
  16. #include    <setjmp.h>
  17. #include    <unistd.h>
  18. #include    <stdarg.h>
  19.  
  20. #include    "vg.h"
  21. #include    "image.h"
  22. #include    "kbd.h"
  23. #include    "text.h"
  24. #include    "video.h"
  25.  
  26.  
  27. image_t            *DisplayedImage    = NULL;
  28. image_t            *Image        = NULL;
  29.  
  30. STATIC int        ImageX        = 0;
  31. STATIC int        ImageY        = 0;
  32. STATIC color_t        ImageColorMap[256];
  33. STATIC int        ImageBackground    = 0;
  34.  
  35. STATIC int        ImageDefaultDelay    = -1;
  36.  
  37. STATIC unsigned long    ImageHistogram[32 * 1024];
  38.  
  39. STATIC int        ScreenMode    = -1;
  40. STATIC vmode_t        *ScreenModeInfo    = NULL;
  41.  
  42. STATIC char        ImageName[80];
  43. STATIC int        ImageInfoFlag    = 0;
  44. STATIC unsigned        ImageInfoX;
  45. STATIC unsigned        ImageInfoY;
  46. STATIC unsigned        ImageInfoWidth;
  47. STATIC unsigned        ImageInfoHeight;
  48. STATIC void        ImageInfo(int);
  49.  
  50. int        bestDisplayMode(int, int, int, int);
  51.  
  52. STATIC void    (*Redraw)();
  53. STATIC void    IRedraw8();
  54. STATIC void    IRedraw24();
  55. int        imageRedraw();
  56. void        imageShowInfo(int);
  57.  
  58. int
  59. imageInit()
  60. {
  61.     return 0;
  62. }
  63.  
  64. image_t    *
  65. imageAlloc(
  66.     int        width, 
  67.     int        height,
  68.     int        depth)
  69. {
  70.     image_t        *image;
  71.     int            nbytes;
  72.     int            bytes_per_pixel;
  73.     int            i;
  74.     unsigned char    *p;
  75.  
  76.     bytes_per_pixel    = (depth + 7) / 8;
  77.     nbytes        = sizeof(image_t)
  78.             + (height * sizeof(unsigned char *))
  79.             + (width * height * bytes_per_pixel);
  80.  
  81.     if ((image = malloc(nbytes)) == NULL)
  82.     return NULL;
  83.  
  84.     image->width    = width;
  85.     image->height    = height;
  86.     image->depth    = depth;
  87.     image->bytes_per_pixel    = bytes_per_pixel;
  88.     image->pixels    = (unsigned char **) (image + 1);
  89.  
  90.     p            = (unsigned char *)  (image->pixels + height);
  91.  
  92.     for (i = 0; i < height; i++)
  93.     {
  94.     image->pixels[i] = p;
  95.     p         += width * bytes_per_pixel;
  96.     }
  97.  
  98.     return image;
  99. }
  100.  
  101. STATIC void
  102. imagePixelLookupInit()
  103. {
  104.     int            i, j, k;
  105.     unsigned        r, g, b;
  106.     unsigned char    *l    = &VPixelLookup[0];
  107.  
  108.     for (i = 0, r = 0; i < 32; i++, r += 77)
  109.     for (j = 0, g = 0; j < 32; j++, g += 150)
  110.         for (k = 0, b = 0; k < 32; k++, b += 29)
  111.         {
  112.         *l++ = (r + g + b) / 32;
  113.         }
  114. }
  115.  
  116. void
  117. imageSetGrayColorMap(
  118.     unsigned    maxgray
  119.     )
  120. {
  121.     int        i;
  122.  
  123.     if (maxgray > 255)
  124.     fatal(-1, "imageSetGrayColorMap() - gray level > 255 (%d)", maxgray);
  125.  
  126.     for (i = 0; i <= maxgray; i++)
  127.     {
  128.     ImageColorMap[i].red    =
  129.     ImageColorMap[i].green    =
  130.     ImageColorMap[i].blue    = i;
  131.     }
  132.     vidSetPalette(ImageColorMap, 256);
  133. }
  134.  
  135. void
  136. imageSetName(
  137.     char    *name
  138.     )
  139. {
  140.     strncpy(ImageName, name, 40);
  141. }
  142.  
  143.  
  144. void
  145. imageSetDefaultDelay(
  146.     int        delay
  147.     )
  148. {
  149.     ImageDefaultDelay    = delay;
  150. }
  151.  
  152. void
  153. imageSetGamma(
  154.     long    RedGamma,
  155.     long    GreenGamma,
  156.     long    BlueGamma
  157.     )
  158. {
  159.     vidSetGamma(RedGamma, GreenGamma, BlueGamma);
  160.     vidSetPalette(ImageColorMap, 256);
  161.     if (ScreenModeInfo->depth > 8)
  162.     {
  163.     IRedraw(0, 0, ScreenModeInfo->width, ScreenModeInfo->height);
  164.     imageShowInfo(ImageInfoFlag);
  165.     }
  166. }
  167.  
  168. void
  169. imageShowInfo(
  170.     int        flag
  171.     )
  172. {
  173.     char    buf[120];
  174.     int        len;
  175.     font_t    *font        = DefaultFont;
  176.  
  177.     if (flag == 0)
  178.     {
  179.     if (ImageInfoFlag)
  180.     {
  181.         ImageInfoFlag = 0;
  182.         IRedraw(ImageInfoX, ImageInfoY, ImageInfoWidth, ImageInfoHeight);
  183.     }
  184.     return;
  185.     }
  186.  
  187.     sprintf(buf, "%s %dx%d-%d ", ImageName,
  188.     Image->width, Image->height, Image->depth);
  189.     len    = strlen(buf);
  190.  
  191.     if (   Image->width  > ScreenModeInfo->width
  192.         || Image->height > ScreenModeInfo->height
  193.         || Image->depth  > ScreenModeInfo->depth  )
  194.     {
  195.     sprintf(&buf[len], " (%dx%d-%d)", ScreenModeInfo->width,
  196.         ScreenModeInfo->height, ScreenModeInfo->depth);
  197.     len    = strlen(buf);
  198.     }
  199.  
  200.     if (len > ScreenModeInfo->width / font->f_width)
  201.     len = ScreenModeInfo->width / font->f_width;
  202.  
  203.     ImageInfoX        = (ScreenModeInfo->width - font->f_width * len) / 2;
  204.     ImageInfoY        = ScreenModeInfo->height - font->f_height * 2;
  205.     ImageInfoWidth    = len * font->f_width;
  206.     ImageInfoHeight    = font->f_height;
  207.  
  208.     vidDrawText(ImageInfoX, ImageInfoY, buf, len, font);
  209.  
  210.     ImageInfoFlag = flag;
  211. }
  212.  
  213. image_t *
  214. imageStart(
  215.     char    *name,
  216.     int        width,
  217.     int        height,
  218.     int        depth,
  219.     int        background
  220.     )
  221. {
  222.     int        i;
  223.     vmode_t    *m;
  224.     int        bpp;
  225.  
  226.     /*
  227.      * round up width to a multiple of 8 pixels
  228.      */
  229.     if (width & 7)
  230.     width = (width & ~7) + 8;
  231.  
  232.     i    = bestDisplayMode(V_GRAPHICS_MODE, width, height, depth);
  233.     m    = vidModeInfo(i);
  234.  
  235.     if (depth <= 8)
  236.     {
  237.     if (m->depth < depth || m->depth > 8)
  238.         return NULL;
  239.  
  240.     bpp    = 1;
  241.     Redraw    = IRedraw8;
  242.     }
  243.     else if (depth == 24)
  244.     {
  245.     bpp    = 3;
  246.     Redraw    = IRedraw24;
  247.     }
  248.     else
  249.     fatal(-1, "ImageStart(): bad depth = %d", depth);
  250.  
  251.     if (width < m->width)
  252.     width = m->width;
  253.     if (height < m->height)
  254.     height = m->height;
  255.  
  256.     /*
  257.      * try to re-use the existing image buffer if possible
  258.      */
  259.     if ( Image == NULL || width != Image->width || height != Image->height
  260.         || bpp != Image->bytes_per_pixel)
  261.     {
  262.     if (Image != NULL)
  263.         free(Image);
  264.  
  265.     if ((Image = imageAlloc(width, height, depth)) == NULL)
  266.         return NULL;
  267.     }
  268.  
  269.     DisplayedImage    = Image;
  270.     ImageX    = 0;
  271.     ImageY    = 0;
  272.  
  273.     ImageBackground    = background;
  274.  
  275.  
  276.     if (ScreenMode != i || vidGetMode() != i)
  277.     {
  278.     vidSetGraphicsRedraw(imageRedraw);
  279.     if (vidSetMode(i) != 0)
  280.         return NULL;
  281.     ScreenMode = i;
  282.     ScreenModeInfo = m;
  283.     }
  284.  
  285.     imageClear(Image, ImageBackground);
  286.  
  287.     imageSetGamma(70, 70, 70);
  288.  
  289.     if (Image->depth > 8)
  290.     {
  291.     imagePixelLookupInit();
  292.     imageSetGrayColorMap(255);
  293.     }
  294.  
  295.     imageSetName(name);
  296.  
  297.     return Image;
  298. }
  299.  
  300. imageClear(
  301.     image_t    *image,
  302.     int        color
  303.     )
  304. {
  305.     int        i;
  306.  
  307.     if (image == DisplayedImage)
  308.     vidClear(color);
  309.  
  310.     for (i = 0; i < image->height; i++)
  311.     memset(image->pixels[i], color, image->width * image->bytes_per_pixel);
  312. }
  313.  
  314. /*ARGSUSED*/
  315. void
  316. imageSetColorMap(
  317.     int        flag,
  318.     color_t    *cmap,
  319.     int        n
  320.     )
  321. {
  322.     vidSetPalette(cmap, n);
  323.     memcpy(ImageColorMap, cmap, n * sizeof(color_t));
  324. }
  325.  
  326. int
  327. imagePutPixels(
  328.     int        x,
  329.     int        y,
  330.     void    *pix,
  331.     int        n
  332.     )
  333. {
  334.     if (Image->bytes_per_pixel != 1)
  335.     return -1;
  336.  
  337.     memcpy(Image->pixels[y] + x, pix, n);
  338.     return imageRefresh(x, y, n, 1);
  339. }
  340.  
  341. int
  342. imagePutPixelsRGB(
  343.     int        x,
  344.     int        y,
  345.     void    *pix,
  346.     int        n
  347.     )
  348. {
  349.     if (Image->bytes_per_pixel != 3)
  350.     return -1;
  351.  
  352.     memcpy(Image->pixels[y] + x * 3, pix,  n * 3);
  353.  
  354.     return imageRefresh(x, y, n, 1);
  355. }
  356.  
  357.  
  358. int
  359. imageRefresh(
  360.     int        x,
  361.     int        y,
  362.     int        w,
  363.     int        h
  364.     )
  365. {
  366.     static int    count    = 0;
  367.  
  368.     IRedraw(x - ImageX, y - ImageY, w, h);
  369.  
  370.     if ((count += h) > 16)
  371.     {
  372.     count = 0;
  373.     return imageGetKey(0);
  374.     }
  375.     return 0;
  376. }
  377.  
  378. imageEnd()
  379. {
  380.     int        k;
  381.     int        r;
  382.  
  383.     if (Image->depth == 24 && ScreenModeInfo->depth == 8)
  384.     {
  385.     CreateHistogram24(Image->pixels, Image->width, Image->height,
  386.         ImageHistogram);
  387.     quantize(ImageHistogram, ImageColorMap, VPixelLookup, 256);
  388.     if ((r = imageRedraw()) != 0)
  389.         return r;
  390.     }
  391.  
  392.     if (ImageDefaultDelay == 0)
  393.     return F_NEXT;
  394.  
  395.     if (ImageDefaultDelay > 0 && ImageDefaultDelay < 2)
  396.     {
  397.     k = imageGetKey(ImageDefaultDelay);
  398.     return (k > 0) ? k : F_NEXT;
  399.     }
  400.  
  401.     k = imageGetKey(2);
  402.     imageShowInfo(0);
  403.  
  404.     if (k > 0)
  405.     return k;
  406.  
  407.     if (ImageDefaultDelay > 0)
  408.     {
  409.     k = imageGetKey(ImageDefaultDelay - 2);
  410.     return (k > 0) ? k : F_NEXT;
  411.     }
  412.  
  413.     r = imageGetKey(K_WAIT);
  414.     return r;
  415. }
  416.  
  417. imageGetKey(
  418.     int        delay
  419.     )
  420. {
  421.  
  422.     int        k;
  423.  
  424.     do
  425.     {
  426.     k    = kbdGetKey(delay);
  427.  
  428.     switch (k)
  429.     {
  430.         case K_ENTER:
  431.         case 'n':
  432.         case 'N':
  433.         return F_NEXT;
  434.  
  435.         case 'p':
  436.         case 'P':
  437.         return F_PREV;
  438.  
  439.         case 'r':
  440.         return F_REDRAW;
  441.  
  442.         case K_LEFT:
  443.         if (! imageScroll(-50, 0))
  444.             kbdBell();
  445.         break;
  446.  
  447.         case K_RIGHT:
  448.         if (! imageScroll(50, 0))
  449.             kbdBell();
  450.         break;
  451.  
  452.         case K_UP:
  453.         if (! imageScroll(0, -50))
  454.             kbdBell();
  455.         break;
  456.  
  457.         case K_DOWN:
  458.         if (! imageScroll(0, 50))
  459.             kbdBell();
  460.         break;
  461.  
  462.         case '?':
  463.         imageShowInfo(!ImageInfoFlag);
  464.         break;
  465.  
  466.         case 'g':
  467.         imageSetGamma(100, 100, 100);
  468.         break;
  469.  
  470.         case 'G':
  471.         imageSetGamma(70, 70, 70);
  472.         break;
  473.  
  474.         case K_ESCAPE:
  475.         return F_ESC;
  476.     }
  477.  
  478.     } while (delay == K_WAIT);
  479.  
  480.     return 0;
  481. }
  482.  
  483. /*
  484.  * imageWarning(format, ...)
  485.  */
  486. int
  487. imageWarning(
  488.     char    *fmt,        /* message format string        */
  489.     ...                /* optional arguments            */
  490.     )
  491. {
  492.     char    buf[120];
  493.     int        len;
  494.     font_t    *font        = DefaultFont;
  495.     int        r;
  496.  
  497.     va_list    args;
  498.  
  499.     va_start(args, fmt);
  500.  
  501.     (void) vsprintf(buf, fmt, args);
  502.     va_end(args);
  503.  
  504.     len        = strlen(buf);
  505.  
  506.     vidDrawText(0, 0, buf, len, font);
  507.     kbdBell();
  508.  
  509.     r = imageGetKey(2);
  510.  
  511.     IRedraw(0, 0, len * font->f_width, font->f_height);
  512.  
  513.     return r;
  514. }
  515.  
  516. /*
  517.  * imageError(format, ...)
  518.  */
  519. int
  520. imageError(
  521.     char    *fmt,        /* message format string        */
  522.     ...                /* optional arguments            */
  523.     )
  524. {
  525.     va_list    args;
  526.     static int    ErrorTextMode    = -1;
  527.     static vmode_t    *ErrorTextModeInfo    = NULL;
  528.     char    line[128];
  529.     int        x;
  530.     int        i;
  531.     int        n;
  532.     int        left, top;
  533.  
  534.     va_start(args, fmt);
  535.  
  536.     if (ErrorTextMode == -1)
  537.     {
  538.     ErrorTextMode        = bestDisplayMode(V_TEXT_MODE, 80, 25, 0);
  539.     ErrorTextModeInfo    = vidModeInfo(ErrorTextMode);
  540.     }
  541.  
  542.     vidSetMode(ErrorTextMode);
  543.     vidClear(0);
  544.  
  545.     left = (ErrorTextModeInfo->width - 60) / 2;
  546.     top     = (ErrorTextModeInfo->height - 6) / 2;
  547.  
  548.     memset(line, DBL_HORIZONTAL_LINE, 60);
  549.     line[0] = DBL_TOP_LEFT_CORNER;
  550.     line[59] = DBL_TOP_RIGHT_CORNER;
  551.     vidPutText(left, top, line, 60, 0x00, 0x04);
  552.  
  553.     line[0] = DBL_BOT_LEFT_CORNER;
  554.     line[59] = DBL_BOT_RIGHT_CORNER;
  555.     vidPutText(left, top+5, line, 60, 0x00, 0x04);
  556.  
  557.     memset(line, ' ', 60);
  558.     line[0] = DBL_VERTICAL_LINE;
  559.     line[59] = DBL_VERTICAL_LINE;
  560.     for (i = 1; i < 5; i++)
  561.         vidPutText(left, top + i, line, 60, 0x00, 0x04);
  562.  
  563.     (void) vsprintf(line, fmt, args);
  564.     va_end(args);
  565.  
  566.     n    = strlen(line);
  567.     if (n > 58)
  568.     n = 58;
  569.  
  570.     x = left + (60 - n) / 2;
  571.  
  572.     vidPutText(x, top+2, line, n, 0x0e, 0x04);
  573.  
  574. #if 0
  575.     if (err != 0)
  576.     {
  577.     fmt = errmsg(err);
  578.     n   = strlen(fmt);
  579.     if (n > 58)
  580.         n = 58;
  581.  
  582.     x = left + (60 - n) / 2;
  583.  
  584.     vidPutText(x, top+3, fmt, n, 0x0e, 0x04);
  585.     }
  586. #endif
  587.  
  588.     return imageGetKey(K_WAIT);
  589. }
  590.  
  591. /*
  592.  * bestDisplayMode()    - returns the "best" available mode for
  593.  *              the given resolution and # of colors
  594.  */
  595. int
  596. bestDisplayMode(
  597.     int        type,
  598.     int        width,
  599.     int        height,
  600.     int        depth
  601.     )
  602. {
  603.     vmode_t    *modes;
  604.     vmode_t    *m;
  605.     vmode_t    *best    = NULL;
  606.     extern int    maxdepth;
  607.  
  608.     modes = vidGetModes();
  609.  
  610.     /*
  611.      * first try for a mode that has enough colors
  612.      * and is at least as large as the image
  613.      */
  614.     for (m = modes; m->flags != 0; m++)
  615.     {
  616.     if ( !(m->flags & V_MODE_SUPPORTED) || !(m->flags & type) )
  617.         continue;
  618.  
  619.     if (m->depth > maxdepth)
  620.         continue;
  621.  
  622.     if (m->depth < depth)
  623.         continue;
  624.  
  625.     if (m->width >= width && m->height >= height)
  626.     {
  627.         if (best == NULL || (m->width <= best->width
  628.          && m->height <= best->height && m->depth <= best->depth) )
  629.         best = m;
  630.     }
  631.     }
  632.  
  633.     if (best)
  634.     return best - modes;
  635.  
  636.     /*
  637.      * now try for the best fit that has enough colors
  638.      */
  639.     for (m = modes; m->width != 0; m++)
  640.     {
  641.     if ( !(m->flags & V_MODE_SUPPORTED) || !(m->flags & type) )
  642.         continue;
  643.  
  644.     if (m->depth > maxdepth)
  645.         continue;
  646.  
  647.     if (m->depth < depth)
  648.         continue;
  649.  
  650.     if (best == NULL)
  651.     {
  652.         best = m;
  653.         continue;
  654.     }
  655.  
  656.     if (m->width < best->width || m->height < best->height)
  657.         continue;
  658.  
  659.     best = m;
  660.     }
  661.  
  662.     if (best)
  663.     return best - modes;
  664.  
  665.     /*
  666.      * now try for the best fit from among the modes that
  667.      * have the largest number of colors
  668.      */
  669.     for (m = modes; m->width != 0; m++)
  670.     {
  671.     if ( !(m->flags & V_MODE_SUPPORTED) || !(m->flags & type) )
  672.         continue;
  673.  
  674.     if (m->depth > maxdepth)
  675.         continue;
  676.  
  677.     if (best == NULL)
  678.     {
  679.         best = m;
  680.         continue;
  681.     }
  682.  
  683.     if (m->depth < best->depth)
  684.         continue;
  685.  
  686.     if (m->depth > best->depth)
  687.     {
  688.         best = m;
  689.         continue;
  690.     }
  691.  
  692.     if (best->width < width || best->height < height)
  693.     {
  694.         if (m->width >= best->width && m->height >= best->height)
  695.         best = m;
  696.     }
  697.     else
  698.     {
  699.         if (m->width >= width && m->width <= best->width
  700.            && m->height >= height && m->height <= best->height)
  701.             best = m;
  702.     }
  703.     }
  704.  
  705.     return best - modes;
  706. }
  707.  
  708. imageScroll(
  709.     int        dx,
  710.     int        dy
  711.     )
  712. {
  713.     int        x;
  714.     int        y;
  715.  
  716.     static int        scroll_in_progress    = 0;
  717.     static jmp_buf    scroll_unwind;
  718.  
  719.     if (scroll_in_progress)
  720.     longjmp(scroll_unwind, 1);
  721.  
  722.     scroll_in_progress = 1;
  723.     setjmp(scroll_unwind);
  724.  
  725.     x    = ImageX + dx;
  726.     if (x > DisplayedImage->width - ScreenModeInfo->width)
  727.     x = DisplayedImage->width - ScreenModeInfo->width;
  728.     if (x < 0)
  729.     x = 0;
  730.  
  731.     y    = ImageY + dy;
  732.     if (y > DisplayedImage->height - ScreenModeInfo->height)
  733.     y = DisplayedImage->height - ScreenModeInfo->height;
  734.     if (y < 0)
  735.     y = 0;
  736.  
  737.     if (x == ImageX && y == ImageY)
  738.     {
  739.     scroll_in_progress = 0;
  740.     return 0;
  741.     }
  742.     else
  743.     {
  744.     ImageX    = x;
  745.     ImageY    = y;
  746.  
  747.     IRedraw(0, 0, ScreenModeInfo->width, ScreenModeInfo->height);
  748.     scroll_in_progress = 0;
  749.     return 1;
  750.     }
  751. }
  752.  
  753. imageRedraw()
  754. {
  755.     int        r;
  756.  
  757.     vidClear(ImageBackground);
  758.     vidSetPalette(ImageColorMap, (Image->depth == 4) ? 16 : 256);
  759.     if ((r = IRedraw(0, 0, ScreenModeInfo->width, ScreenModeInfo->height)) != 0)
  760.     return r;
  761.     imageShowInfo(ImageInfoFlag);
  762.     return 0;
  763. }
  764.  
  765. /*
  766.  * IRedraw()    - redraw screen
  767.  */
  768.  
  769. IRedraw(
  770.     int        x,
  771.     int        y,
  772.     int        w,
  773.     int        h
  774.     )
  775. {
  776.     /*
  777.      * clip the request to the limits of the physical screen
  778.      */
  779.     if (x < 0)
  780.     {
  781.     w    += x;
  782.     x    = 0;
  783.     }
  784.  
  785.     if (y < 0)
  786.     {
  787.     h    += y;
  788.     y    = 0;
  789.     }
  790.  
  791. #if 1
  792.     if (x & 7)
  793.     {
  794.     w += (x & 7);
  795.     x &= ~7;
  796.     }
  797.  
  798.     if (w & 7)
  799.     w = (w & ~7) + 8;
  800. #endif
  801.  
  802.     if (DisplayedImage->width - ImageX - x < w)
  803.     w = DisplayedImage->width - ImageX - x;
  804.     if (DisplayedImage->height - ImageY - y < h)
  805.     h = DisplayedImage->height - ImageY - y;
  806.  
  807.     if (ImageInfoFlag && y < (ImageInfoY + ImageInfoHeight)
  808.     && (y + h) >= ImageInfoY)
  809.     {
  810.     while (y < ImageInfoY && h > 0)
  811.     {
  812.         Redraw(x, y, w, 1);
  813.         ++y;
  814.         --h;
  815.     }
  816.  
  817.     while (y < ImageInfoY + ImageInfoHeight && h > 0)
  818.     {
  819.         int        x0, x1;
  820.         int        w0, w1;
  821.  
  822.         x0 = x;
  823.         w0 = ImageInfoX - x0;
  824.         if (w0 > w)
  825.         w0 = w;
  826.  
  827.         if (w0 > 0)
  828.         Redraw(x0, y, w0, 1);
  829.  
  830.         x1 = ImageInfoX + ImageInfoWidth;
  831.         w1 = x + w - x1;
  832.  
  833.         if (w1 > 0)
  834.         Redraw(x1, y, w1, 1);
  835.  
  836.         ++y;
  837.         --h;
  838.     }
  839.     }
  840.  
  841.     if (w > 0 && h > 0)
  842.     Redraw(x, y, w, h);
  843.  
  844.     return 0;
  845. }
  846.  
  847. STATIC void
  848. IRedraw8(
  849.     int        x,
  850.     int        y,
  851.     int        w,
  852.     int        h
  853.     )
  854. {
  855.     unsigned char    *p;
  856.  
  857.  
  858.     while (--h >= 0)
  859.     {
  860.     p    = DisplayedImage->pixels[ImageY + y] + ImageX + x;
  861.     vidPutPixels8(x, y, p, w);
  862.     y++;
  863.     }
  864. }
  865.  
  866. STATIC void
  867. IRedraw24(
  868.     int        x,
  869.     int        y,
  870.     int        w,
  871.     int        h
  872.     )
  873. {
  874.     void    *p;
  875.  
  876.  
  877.     while (--h >= 0)
  878.     {
  879.     p    = DisplayedImage->pixels[ImageY + y] + (ImageX + x) * 3;
  880.     vidPutPixels24(x, y, p, w);
  881.     y++;
  882.     }
  883. }
  884.