Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20.  
  21. // draw.c -- this is the only file outside the refresh that touches the
  22. // vid buffer
  23.  
  24. #include "quakedef.h"
  25.  
  26. typedef struct {
  27.         vrect_t rect;
  28.         int             width;
  29.         int             height;
  30.         byte    *ptexbytes;
  31.         int             rowbytes;
  32. } rectdesc_t;
  33.  
  34. static rectdesc_t       r_rectdesc;
  35.  
  36. byte            *draw_chars;                            // 8*8 graphic characters
  37. qpic_t          *draw_disc;
  38. qpic_t          *draw_backtile;
  39.  
  40. //=============================================================================
  41. /* Support Routines */
  42.  
  43. typedef struct cachepic_s
  44. {
  45.         char            name[MAX_QPATH];
  46.         cache_user_t    cache;
  47. } cachepic_t;
  48.  
  49. #define MAX_CACHED_PICS         128
  50. cachepic_t      menu_cachepics[MAX_CACHED_PICS];
  51. int                     menu_numcachepics;
  52.  
  53.  
  54. qpic_t  *Draw_PicFromWad (char *name)
  55. {
  56.         return W_GetLumpName (name);
  57. }
  58.  
  59. /*
  60. ================
  61. Draw_CachePic
  62. ================
  63. */
  64. qpic_t  *Draw_CachePic (char *path)
  65. {
  66.         cachepic_t      *pic;
  67.         int                     i;
  68.         qpic_t          *dat;
  69.        
  70.         for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
  71.                 if (!strcmp (path, pic->name))
  72.                         break;
  73.  
  74.         if (i == menu_numcachepics)
  75.         {
  76.                 if (menu_numcachepics == MAX_CACHED_PICS)
  77.                         Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
  78.                 menu_numcachepics++;
  79.                 strcpy (pic->name, path);
  80.         }
  81.  
  82.         dat = Cache_Check (&pic->cache);
  83.  
  84.         if (dat)
  85.                 return dat;
  86.  
  87. //
  88. // load the pic from disk
  89. //
  90.         COM_LoadCacheFile (path, &pic->cache);
  91.        
  92.         dat = (qpic_t *)pic->cache.data;
  93.         if (!dat)
  94.         {
  95.                 Sys_Error ("Draw_CachePic: failed to load %s", path);
  96.         }
  97.  
  98.         SwapPic (dat);
  99.  
  100.         return dat;
  101. }
  102.  
  103.  
  104.  
  105. /*
  106. ===============
  107. Draw_Init
  108. ===============
  109. */
  110. void Draw_Init (void)
  111. {
  112.         int             i;
  113.  
  114.         draw_chars = W_GetLumpName ("conchars");
  115.         draw_disc = W_GetLumpName ("disc");
  116.         draw_backtile = W_GetLumpName ("backtile");
  117.  
  118.         r_rectdesc.width = draw_backtile->width;
  119.         r_rectdesc.height = draw_backtile->height;
  120.         r_rectdesc.ptexbytes = draw_backtile->data;
  121.         r_rectdesc.rowbytes = draw_backtile->width;
  122. }
  123.  
  124.  
  125.  
  126. /*
  127. ================
  128. Draw_Character
  129.  
  130. Draws one 8*8 graphics character with 0 being transparent.
  131. It can be clipped to the top of the screen to allow the console to be
  132. smoothly scrolled off.
  133. ================
  134. */
  135. void Draw_Character (int x, int y, int num)
  136. {
  137.         byte                    *dest;
  138.         byte                    *source;
  139.         unsigned short  *pusdest;
  140.         int                             drawline;      
  141.         int                             row, col;
  142.  
  143.         num &= 255;
  144.        
  145.         if (y <= -8)
  146.                 return;                 // totally off screen
  147.  
  148. #ifdef PARANOID
  149.         if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
  150.                 Sys_Error ("Con_DrawCharacter: (%i, %i)", x, y);
  151.         if (num < 0 || num > 255)
  152.                 Sys_Error ("Con_DrawCharacter: char %i", num);
  153. #endif
  154.  
  155.         row = num>>4;
  156.         col = num&15;
  157.         source = draw_chars + (row<<10) + (col<<3);
  158.  
  159.         if (y < 0)
  160.         {       // clipped
  161.                 drawline = 8 + y;
  162.                 source -= 128*y;
  163.                 y = 0;
  164.         }
  165.         else
  166.                 drawline = 8;
  167.  
  168.  
  169.         if (r_pixbytes == 1)
  170.         {
  171.                 dest = vid.conbuffer + y*vid.conrowbytes + x;
  172.        
  173.                 while (drawline--)
  174.                 {
  175.                         if (source[0])
  176.                                 dest[0] = source[0];
  177.                         if (source[1])
  178.                                 dest[1] = source[1];
  179.                         if (source[2])
  180.                                 dest[2] = source[2];
  181.                         if (source[3])
  182.                                 dest[3] = source[3];
  183.                         if (source[4])
  184.                                 dest[4] = source[4];
  185.                         if (source[5])
  186.                                 dest[5] = source[5];
  187.                         if (source[6])
  188.                                 dest[6] = source[6];
  189.                         if (source[7])
  190.                                 dest[7] = source[7];
  191.                         source += 128;
  192.                         dest += vid.conrowbytes;
  193.                 }
  194.         }
  195.         else
  196.         {
  197.         // FIXME: pre-expand to native format?
  198.                 pusdest = (unsigned short *)
  199.                                 ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1));
  200.  
  201.                 while (drawline--)
  202.                 {
  203.                         if (source[0])
  204.                                 pusdest[0] = d_8to16table[source[0]];
  205.                         if (source[1])
  206.                                 pusdest[1] = d_8to16table[source[1]];
  207.                         if (source[2])
  208.                                 pusdest[2] = d_8to16table[source[2]];
  209.                         if (source[3])
  210.                                 pusdest[3] = d_8to16table[source[3]];
  211.                         if (source[4])
  212.                                 pusdest[4] = d_8to16table[source[4]];
  213.                         if (source[5])
  214.                                 pusdest[5] = d_8to16table[source[5]];
  215.                         if (source[6])
  216.                                 pusdest[6] = d_8to16table[source[6]];
  217.                         if (source[7])
  218.                                 pusdest[7] = d_8to16table[source[7]];
  219.  
  220.                         source += 128;
  221.                         pusdest += (vid.conrowbytes >> 1);
  222.                 }
  223.         }
  224. }
  225.  
  226. /*
  227. ================
  228. Draw_String
  229. ================
  230. */
  231. void Draw_String (int x, int y, char *str)
  232. {
  233.         while (*str)
  234.         {
  235.                 Draw_Character (x, y, *str);
  236.                 str++;
  237.                 x += 8;
  238.         }
  239. }
  240.  
  241. /*
  242. ================
  243. Draw_DebugChar
  244.  
  245. Draws a single character directly to the upper right corner of the screen.
  246. This is for debugging lockups by drawing different chars in different parts
  247. of the code.
  248. ================
  249. */
  250. void Draw_DebugChar (char num)
  251. {
  252.         byte                    *dest;
  253.         byte                    *source;
  254.         int                             drawline;      
  255.         extern byte             *draw_chars;
  256.         int                             row, col;
  257.  
  258.         if (!vid.direct)
  259.                 return;         // don't have direct FB access, so no debugchars...
  260.  
  261.         drawline = 8;
  262.  
  263.         row = num>>4;
  264.         col = num&15;
  265.         source = draw_chars + (row<<10) + (col<<3);
  266.  
  267.         dest = vid.direct + 312;
  268.  
  269.         while (drawline--)
  270.         {
  271.                 dest[0] = source[0];
  272.                 dest[1] = source[1];
  273.                 dest[2] = source[2];
  274.                 dest[3] = source[3];
  275.                 dest[4] = source[4];
  276.                 dest[5] = source[5];
  277.                 dest[6] = source[6];
  278.                 dest[7] = source[7];
  279.                 source += 128;
  280.                 dest += 320;
  281.         }
  282. }
  283.  
  284. /*
  285. =============
  286. Draw_Pic
  287. =============
  288. */
  289. void Draw_Pic (int x, int y, qpic_t *pic)
  290. {
  291.         byte                    *dest, *source;
  292.         unsigned short  *pusdest;
  293.         int                             v, u;
  294.  
  295.         if ((x < 0) ||
  296.                 (x + pic->width > vid.width) ||
  297.                 (y < 0) ||
  298.                 (y + pic->height > vid.height))
  299.         {
  300.                 Sys_Error ("Draw_Pic: bad coordinates");
  301.         }
  302.  
  303.         source = pic->data;
  304.  
  305.         if (r_pixbytes == 1)
  306.         {
  307.                 dest = vid.buffer + y * vid.rowbytes + x;
  308.  
  309.                 for (v=0 ; v<pic->height ; v++)
  310.                 {
  311.                         Q_memcpy (dest, source, pic->width);
  312.                         dest += vid.rowbytes;
  313.                         source += pic->width;
  314.                 }
  315.         }
  316.         else
  317.         {
  318.         // FIXME: pretranslate at load time?
  319.                 pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  320.  
  321.                 for (v=0 ; v<pic->height ; v++)
  322.                 {
  323.                         for (u=0 ; u<pic->width ; u++)
  324.                         {
  325.                                 pusdest[u] = d_8to16table[source[u]];
  326.                         }
  327.  
  328.                         pusdest += vid.rowbytes >> 1;
  329.                         source += pic->width;
  330.                 }
  331.         }
  332. }
  333.  
  334.  
  335. /*
  336. =============
  337. Draw_TransPic
  338. =============
  339. */
  340. void Draw_TransPic (int x, int y, qpic_t *pic)
  341. {
  342.         byte    *dest, *source, tbyte;
  343.         unsigned short  *pusdest;
  344.         int                             v, u;
  345.  
  346.         if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
  347.                  (unsigned)(y + pic->height) > vid.height)
  348.         {
  349.                 Sys_Error ("Draw_TransPic: bad coordinates");
  350.         }
  351.                
  352.         source = pic->data;
  353.  
  354.         if (r_pixbytes == 1)
  355.         {
  356.                 dest = vid.buffer + y * vid.rowbytes + x;
  357.  
  358.                 if (pic->width & 7)
  359.                 {       // general
  360.                         for (v=0 ; v<pic->height ; v++)
  361.                         {
  362.                                 for (u=0 ; u<pic->width ; u++)
  363.                                         if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  364.                                                 dest[u] = tbyte;
  365.        
  366.                                 dest += vid.rowbytes;
  367.                                 source += pic->width;
  368.                         }
  369.                 }
  370.                 else
  371.                 {       // unwound
  372.                         for (v=0 ; v<pic->height ; v++)
  373.                         {
  374.                                 for (u=0 ; u<pic->width ; u+=8)
  375.                                 {
  376.                                         if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  377.                                                 dest[u] = tbyte;
  378.                                         if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
  379.                                                 dest[u+1] = tbyte;
  380.                                         if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
  381.                                                 dest[u+2] = tbyte;
  382.                                         if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
  383.                                                 dest[u+3] = tbyte;
  384.                                         if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
  385.                                                 dest[u+4] = tbyte;
  386.                                         if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
  387.                                                 dest[u+5] = tbyte;
  388.                                         if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
  389.                                                 dest[u+6] = tbyte;
  390.                                         if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
  391.                                                 dest[u+7] = tbyte;
  392.                                 }
  393.                                 dest += vid.rowbytes;
  394.                                 source += pic->width;
  395.                         }
  396.                 }
  397.         }
  398.         else
  399.         {
  400.         // FIXME: pretranslate at load time?
  401.                 pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  402.  
  403.                 for (v=0 ; v<pic->height ; v++)
  404.                 {
  405.                         for (u=0 ; u<pic->width ; u++)
  406.                         {
  407.                                 tbyte = source[u];
  408.  
  409.                                 if (tbyte != TRANSPARENT_COLOR)
  410.                                 {
  411.                                         pusdest[u] = d_8to16table[tbyte];
  412.                                 }
  413.                         }
  414.  
  415.                         pusdest += vid.rowbytes >> 1;
  416.                         source += pic->width;
  417.                 }
  418.         }
  419. }
  420.  
  421.  
  422. /*
  423. =============
  424. Draw_TransPicTranslate
  425. =============
  426. */
  427. void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
  428. {
  429.         byte    *dest, *source, tbyte;
  430.         unsigned short  *pusdest;
  431.         int                             v, u;
  432.  
  433.         if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
  434.                  (unsigned)(y + pic->height) > vid.height)
  435.         {
  436.                 Sys_Error ("Draw_TransPic: bad coordinates");
  437.         }
  438.                
  439.         source = pic->data;
  440.  
  441.         if (r_pixbytes == 1)
  442.         {
  443.                 dest = vid.buffer + y * vid.rowbytes + x;
  444.  
  445.                 if (pic->width & 7)
  446.                 {       // general
  447.                         for (v=0 ; v<pic->height ; v++)
  448.                         {
  449.                                 for (u=0 ; u<pic->width ; u++)
  450.                                         if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  451.                                                 dest[u] = translation[tbyte];
  452.  
  453.                                 dest += vid.rowbytes;
  454.                                 source += pic->width;
  455.                         }
  456.                 }
  457.                 else
  458.                 {       // unwound
  459.                         for (v=0 ; v<pic->height ; v++)
  460.                         {
  461.                                 for (u=0 ; u<pic->width ; u+=8)
  462.                                 {
  463.                                         if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
  464.                                                 dest[u] = translation[tbyte];
  465.                                         if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
  466.                                                 dest[u+1] = translation[tbyte];
  467.                                         if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
  468.                                                 dest[u+2] = translation[tbyte];
  469.                                         if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
  470.                                                 dest[u+3] = translation[tbyte];
  471.                                         if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
  472.                                                 dest[u+4] = translation[tbyte];
  473.                                         if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
  474.                                                 dest[u+5] = translation[tbyte];
  475.                                         if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
  476.                                                 dest[u+6] = translation[tbyte];
  477.                                         if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
  478.                                                 dest[u+7] = translation[tbyte];
  479.                                 }
  480.                                 dest += vid.rowbytes;
  481.                                 source += pic->width;
  482.                         }
  483.                 }
  484.         }
  485.         else
  486.         {
  487.         // FIXME: pretranslate at load time?
  488.                 pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  489.  
  490.                 for (v=0 ; v<pic->height ; v++)
  491.                 {
  492.                         for (u=0 ; u<pic->width ; u++)
  493.                         {
  494.                                 tbyte = source[u];
  495.  
  496.                                 if (tbyte != TRANSPARENT_COLOR)
  497.                                 {
  498.                                         pusdest[u] = d_8to16table[tbyte];
  499.                                 }
  500.                         }
  501.  
  502.                         pusdest += vid.rowbytes >> 1;
  503.                         source += pic->width;
  504.                 }
  505.         }
  506. }
  507.  
  508.  
  509. void Draw_CharToConback (int num, byte *dest)
  510. {
  511.         int             row, col;
  512.         byte    *source;
  513.         int             drawline;
  514.         int             x;
  515.  
  516.         row = num>>4;
  517.         col = num&15;
  518.         source = draw_chars + (row<<10) + (col<<3);
  519.  
  520.         drawline = 8;
  521.  
  522.         while (drawline--)
  523.         {
  524.                 for (x=0 ; x<8 ; x++)
  525.                         if (source[x])
  526.                                 dest[x] = 0x60 + source[x];
  527.                 source += 128;
  528.                 dest += 320;
  529.         }
  530.  
  531. }
  532.  
  533. /*
  534. ================
  535. Draw_ConsoleBackground
  536.  
  537. ================
  538. */
  539. void Draw_ConsoleBackground (int lines)
  540. {
  541.         int                             x, y, v;
  542.         byte                    *src, *dest;
  543.         unsigned short  *pusdest;
  544.         int                             f, fstep;
  545.         qpic_t                  *conback;
  546.         char                    ver[100];
  547.  
  548.         conback = Draw_CachePic ("gfx/conback.lmp");
  549.  
  550. // hack the version number directly into the pic
  551. #ifdef _WIN32
  552.         sprintf (ver, "(WinQuake) %4.2f", (float)VERSION);
  553.         dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver);
  554. #elif defined(X11)
  555.         sprintf (ver, "(X11 Quake %2.2f) %4.2f", (float)X11_VERSION, (float)VERSION);
  556.         dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver);
  557. #elif defined(__linux__)
  558.         sprintf (ver, "(Linux Quake %2.2f) %4.2f", (float)LINUX_VERSION, (float)VERSION);
  559.         dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver);
  560. #else
  561.         dest = conback->data + 320 - 43 + 320*186;
  562.         sprintf (ver, "%4.2f", VERSION);
  563. #endif
  564.  
  565.         for (x=0 ; x<strlen(ver) ; x++)
  566.                 Draw_CharToConback (ver[x], dest+(x<<3));
  567.        
  568. // draw the pic
  569.         if (r_pixbytes == 1)
  570.         {
  571.                 dest = vid.conbuffer;
  572.  
  573.                 for (y=0 ; y<lines ; y++, dest += vid.conrowbytes)
  574.                 {
  575.                         v = (vid.conheight - lines + y)*200/vid.conheight;
  576.                         src = conback->data + v*320;
  577.                         if (vid.conwidth == 320)
  578.                                 memcpy (dest, src, vid.conwidth);
  579.                         else
  580.                         {
  581.                                 f = 0;
  582.                                 fstep = 320*0x10000/vid.conwidth;
  583.                                 for (x=0 ; x<vid.conwidth ; x+=4)
  584.                                 {
  585.                                         dest[x] = src[f>>16];
  586.                                         f += fstep;
  587.                                         dest[x+1] = src[f>>16];
  588.                                         f += fstep;
  589.                                         dest[x+2] = src[f>>16];
  590.                                         f += fstep;
  591.                                         dest[x+3] = src[f>>16];
  592.                                         f += fstep;
  593.                                 }
  594.                         }
  595.                 }
  596.         }
  597.         else
  598.         {
  599.                 pusdest = (unsigned short *)vid.conbuffer;
  600.  
  601.                 for (y=0 ; y<lines ; y++, pusdest += (vid.conrowbytes >> 1))
  602.                 {
  603.                 // FIXME: pre-expand to native format?
  604.                 // FIXME: does the endian switching go away in production?
  605.                         v = (vid.conheight - lines + y)*200/vid.conheight;
  606.                         src = conback->data + v*320;
  607.                         f = 0;
  608.                         fstep = 320*0x10000/vid.conwidth;
  609.                         for (x=0 ; x<vid.conwidth ; x+=4)
  610.                         {
  611.                                 pusdest[x] = d_8to16table[src[f>>16]];
  612.                                 f += fstep;
  613.                                 pusdest[x+1] = d_8to16table[src[f>>16]];
  614.                                 f += fstep;
  615.                                 pusdest[x+2] = d_8to16table[src[f>>16]];
  616.                                 f += fstep;
  617.                                 pusdest[x+3] = d_8to16table[src[f>>16]];
  618.                                 f += fstep;
  619.                         }
  620.                 }
  621.         }
  622. }
  623.  
  624.  
  625. /*
  626. ==============
  627. R_DrawRect8
  628. ==============
  629. */
  630. void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc,
  631.         int transparent)
  632. {
  633.         byte    t;
  634.         int             i, j, srcdelta, destdelta;
  635.         byte    *pdest;
  636.  
  637.         pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x;
  638.  
  639.         srcdelta = rowbytes - prect->width;
  640.         destdelta = vid.rowbytes - prect->width;
  641.  
  642.         if (transparent)
  643.         {
  644.                 for (i=0 ; i<prect->height ; i++)
  645.                 {
  646.                         for (j=0 ; j<prect->width ; j++)
  647.                         {
  648.                                 t = *psrc;
  649.                                 if (t != TRANSPARENT_COLOR)
  650.                                 {
  651.                                         *pdest = t;
  652.                                 }
  653.  
  654.                                 psrc++;
  655.                                 pdest++;
  656.                         }
  657.  
  658.                         psrc += srcdelta;
  659.                         pdest += destdelta;
  660.                 }
  661.         }
  662.         else
  663.         {
  664.                 for (i=0 ; i<prect->height ; i++)
  665.                 {
  666.                         memcpy (pdest, psrc, prect->width);
  667.                         psrc += rowbytes;
  668.                         pdest += vid.rowbytes;
  669.                 }
  670.         }
  671. }
  672.  
  673.  
  674. /*
  675. ==============
  676. R_DrawRect16
  677. ==============
  678. */
  679. void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc,
  680.         int transparent)
  681. {
  682.         byte                    t;
  683.         int                             i, j, srcdelta, destdelta;
  684.         unsigned short  *pdest;
  685.  
  686. // FIXME: would it be better to pre-expand native-format versions?
  687.  
  688.         pdest = (unsigned short *)vid.buffer +
  689.                         (prect->y * (vid.rowbytes >> 1)) + prect->x;
  690.  
  691.         srcdelta = rowbytes - prect->width;
  692.         destdelta = (vid.rowbytes >> 1) - prect->width;
  693.  
  694.         if (transparent)
  695.         {
  696.                 for (i=0 ; i<prect->height ; i++)
  697.                 {
  698.                         for (j=0 ; j<prect->width ; j++)
  699.                         {
  700.                                 t = *psrc;
  701.                                 if (t != TRANSPARENT_COLOR)
  702.                                 {
  703.                                         *pdest = d_8to16table[t];
  704.                                 }
  705.  
  706.                                 psrc++;
  707.                                 pdest++;
  708.                         }
  709.  
  710.                         psrc += srcdelta;
  711.                         pdest += destdelta;
  712.                 }
  713.         }
  714.         else
  715.         {
  716.                 for (i=0 ; i<prect->height ; i++)
  717.                 {
  718.                         for (j=0 ; j<prect->width ; j++)
  719.                         {
  720.                                 *pdest = d_8to16table[*psrc];
  721.                                 psrc++;
  722.                                 pdest++;
  723.                         }
  724.  
  725.                         psrc += srcdelta;
  726.                         pdest += destdelta;
  727.                 }
  728.         }
  729. }
  730.  
  731.  
  732. /*
  733. =============
  734. Draw_TileClear
  735.  
  736. This repeats a 64*64 tile graphic to fill the screen around a sized down
  737. refresh window.
  738. =============
  739. */
  740. void Draw_TileClear (int x, int y, int w, int h)
  741. {
  742.         int                             width, height, tileoffsetx, tileoffsety;
  743.         byte                    *psrc;
  744.         vrect_t                 vr;
  745.  
  746.         r_rectdesc.rect.x = x;
  747.         r_rectdesc.rect.y = y;
  748.         r_rectdesc.rect.width = w;
  749.         r_rectdesc.rect.height = h;
  750.  
  751.         vr.y = r_rectdesc.rect.y;
  752.         height = r_rectdesc.rect.height;
  753.  
  754.         tileoffsety = vr.y % r_rectdesc.height;
  755.  
  756.         while (height > 0)
  757.         {
  758.                 vr.x = r_rectdesc.rect.x;
  759.                 width = r_rectdesc.rect.width;
  760.  
  761.                 if (tileoffsety != 0)
  762.                         vr.height = r_rectdesc.height - tileoffsety;
  763.                 else
  764.                         vr.height = r_rectdesc.height;
  765.  
  766.                 if (vr.height > height)
  767.                         vr.height = height;
  768.  
  769.                 tileoffsetx = vr.x % r_rectdesc.width;
  770.  
  771.                 while (width > 0)
  772.                 {
  773.                         if (tileoffsetx != 0)
  774.                                 vr.width = r_rectdesc.width - tileoffsetx;
  775.                         else
  776.                                 vr.width = r_rectdesc.width;
  777.  
  778.                         if (vr.width > width)
  779.                                 vr.width = width;
  780.  
  781.                         psrc = r_rectdesc.ptexbytes +
  782.                                         (tileoffsety * r_rectdesc.rowbytes) + tileoffsetx;
  783.  
  784.                         if (r_pixbytes == 1)
  785.                         {
  786.                                 R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0);
  787.                         }
  788.                         else
  789.                         {
  790.                                 R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0);
  791.                         }
  792.  
  793.                         vr.x += vr.width;
  794.                         width -= vr.width;
  795.                         tileoffsetx = 0;        // only the left tile can be left-clipped
  796.                 }
  797.  
  798.                 vr.y += vr.height;
  799.                 height -= vr.height;
  800.                 tileoffsety = 0;                // only the top tile can be top-clipped
  801.         }
  802. }
  803.  
  804.  
  805. /*
  806. =============
  807. Draw_Fill
  808.  
  809. Fills a box of pixels with a single color
  810. =============
  811. */
  812. void Draw_Fill (int x, int y, int w, int h, int c)
  813. {
  814.         byte                    *dest;
  815.         unsigned short  *pusdest;
  816.         unsigned                uc;
  817.         int                             u, v;
  818.  
  819.         if (r_pixbytes == 1)
  820.         {
  821.                 dest = vid.buffer + y*vid.rowbytes + x;
  822.                 for (v=0 ; v<h ; v++, dest += vid.rowbytes)
  823.                         for (u=0 ; u<w ; u++)
  824.                                 dest[u] = c;
  825.         }
  826.         else
  827.         {
  828.                 uc = d_8to16table[c];
  829.  
  830.                 pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x;
  831.                 for (v=0 ; v<h ; v++, pusdest += (vid.rowbytes >> 1))
  832.                         for (u=0 ; u<w ; u++)
  833.                                 pusdest[u] = uc;
  834.         }
  835. }
  836. //=============================================================================
  837.  
  838. /*
  839. ================
  840. Draw_FadeScreen
  841.  
  842. ================
  843. */
  844. void Draw_FadeScreen (void)
  845. {
  846.         int                     x,y;
  847.         byte            *pbuf;
  848.  
  849.         VID_UnlockBuffer ();
  850.         S_ExtraUpdate ();
  851.         VID_LockBuffer ();
  852.  
  853.         for (y=0 ; y<vid.height ; y++)
  854.         {
  855.                 int     t;
  856.  
  857.                 pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
  858.                 t = (y & 1) << 1;
  859.  
  860.                 for (x=0 ; x<vid.width ; x++)
  861.                 {
  862.                         if ((x & 3) != t)
  863.                                 pbuf[x] = 0;
  864.                 }
  865.         }
  866.  
  867.         VID_UnlockBuffer ();
  868.         S_ExtraUpdate ();
  869.         VID_LockBuffer ();
  870. }
  871.  
  872. //=============================================================================
  873.  
  874. /*
  875. ================
  876. Draw_BeginDisc
  877.  
  878. Draws the little blue disc in the corner of the screen.
  879. Call before beginning any disc IO.
  880. ================
  881. */
  882. void Draw_BeginDisc (void)
  883. {
  884.  
  885.         D_BeginDirectRect (vid.width - 24, 0, draw_disc->data, 24, 24);
  886. }
  887.  
  888.  
  889. /*
  890. ================
  891. Draw_EndDisc
  892.  
  893. Erases the disc icon.
  894. Call after completing any disc IO
  895. ================
  896. */
  897. void Draw_EndDisc (void)
  898. {
  899.  
  900.         D_EndDirectRect (vid.width - 24, 0, 24, 24);
  901. }
  902.  
  903.