home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / gl_draw.c < prev    next >
C/C++ Source or Header  |  2000-06-17  |  29KB  |  1,298 lines

  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. #define GL_COLOR_INDEX8_EXT     0x80E5
  27.  
  28. extern unsigned char d_15to8table[65536];
  29.  
  30. cvar_t    gl_nobind = {"gl_nobind", "0"};
  31. cvar_t    gl_max_size = {"gl_max_size", "1024"};
  32. cvar_t    gl_picmip = {"gl_picmip", "0"};
  33.  
  34. byte    *draw_chars;        // 8*8 graphic characters
  35. qpic_t    *draw_disc;
  36. qpic_t    *draw_backtile;
  37.  
  38. int     translate_texture;
  39. int     char_texture;
  40.  
  41. typedef struct
  42. {
  43.   int   texnum;
  44.   float sl, tl, sh, th;
  45. } glpic_t;
  46.  
  47. byte    conback_buffer[sizeof(qpic_t) + sizeof(glpic_t)];
  48. qpic_t    *conback = (qpic_t *)&conback_buffer;
  49.  
  50. int   gl_lightmap_format = 4;
  51. int   gl_solid_format = 3;
  52. int   gl_alpha_format = 4;
  53.  
  54. int   gl_filter_min = GL_LINEAR_MIPMAP_NEAREST;
  55. int   gl_filter_max = GL_LINEAR;
  56.  
  57.  
  58. int   texels;
  59.  
  60. typedef struct
  61. {
  62.   int   texnum;
  63.   char  identifier[64];
  64.   int   width, height;
  65.   qboolean  mipmap;
  66. } gltexture_t;
  67.  
  68. #define MAX_GLTEXTURES  1024
  69. gltexture_t gltextures[MAX_GLTEXTURES];
  70. int     numgltextures;
  71.  
  72.  
  73. void GL_Bind (int texnum)
  74. {
  75.   if (gl_nobind.value)
  76.     texnum = char_texture;
  77.   if (currenttexture == texnum)
  78.     return;
  79.   currenttexture = texnum;
  80. #ifdef _WIN32
  81.   bindTexFunc (GL_TEXTURE_2D, texnum);
  82. #else
  83.   glBindTexture(GL_TEXTURE_2D, texnum);
  84. #endif
  85. }
  86.  
  87.  
  88. /*
  89. =============================================================================
  90.  
  91.   scrap allocation
  92.  
  93.   Allocate all the little status bar obejcts into a single texture
  94.   to crutch up stupid hardware / drivers
  95.  
  96. =============================================================================
  97. */
  98.  
  99. #define MAX_SCRAPS    2
  100. #define BLOCK_WIDTH   256
  101. #define BLOCK_HEIGHT  256
  102.  
  103. int     scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH];
  104. byte    scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT*4];
  105. qboolean  scrap_dirty;
  106. int     scrap_texnum;
  107.  
  108. // returns a texture number and the position inside it
  109. int Scrap_AllocBlock (int w, int h, int *x, int *y)
  110. {
  111.   int   i, j;
  112.   int   best, best2;
  113.   int   bestx;
  114.   int   texnum;
  115.  
  116.   for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++)
  117.   {
  118.     best = BLOCK_HEIGHT;
  119.  
  120.     for (i=0 ; i<BLOCK_WIDTH-w ; i++)
  121.     {
  122.       best2 = 0;
  123.  
  124.       for (j=0 ; j<w ; j++)
  125.       {
  126.         if (scrap_allocated[texnum][i+j] >= best)
  127.           break;
  128.         if (scrap_allocated[texnum][i+j] > best2)
  129.           best2 = scrap_allocated[texnum][i+j];
  130.       }
  131.       if (j == w)
  132.       { // this is a valid spot
  133.         *x = i;
  134.         *y = best = best2;
  135.       }
  136.     }
  137.  
  138.     if (best + h > BLOCK_HEIGHT)
  139.       continue;
  140.  
  141.     for (i=0 ; i<w ; i++)
  142.       scrap_allocated[texnum][*x + i] = best + h;
  143.  
  144.     return texnum;
  145.   }
  146.  
  147.   Sys_Error ("Scrap_AllocBlock: full");
  148. }
  149.  
  150. int scrap_uploads;
  151.  
  152. void Scrap_Upload (void)
  153. {
  154.   int   texnum;
  155.  
  156.   scrap_uploads++;
  157.  
  158.   for (texnum=0 ; texnum<MAX_SCRAPS ; texnum++) {
  159.     GL_Bind(scrap_texnum + texnum);
  160.     GL_Upload8 (scrap_texels[texnum], BLOCK_WIDTH, BLOCK_HEIGHT, false, true);
  161.   }
  162.   scrap_dirty = false;
  163. }
  164.  
  165. //=============================================================================
  166. /* Support Routines */
  167.  
  168. typedef struct cachepic_s
  169. {
  170.   char    name[MAX_QPATH];
  171.   qpic_t    pic;
  172.   byte    padding[32];  // for appended glpic
  173. } cachepic_t;
  174.  
  175. #define MAX_CACHED_PICS   128
  176. cachepic_t  menu_cachepics[MAX_CACHED_PICS];
  177. int     menu_numcachepics;
  178.  
  179. byte    menuplyr_pixels[4096];
  180.  
  181. int   pic_texels;
  182. int   pic_count;
  183.  
  184. qpic_t *Draw_PicFromWad (char *name)
  185. {
  186.   qpic_t  *p;
  187.   glpic_t *gl;
  188.  
  189.   p = W_GetLumpName (name);
  190.   gl = (glpic_t *)p->data;
  191.  
  192.   // load little ones into the scrap
  193.   if (p->width < 64 && p->height < 64)
  194.   {
  195.     int   x, y;
  196.     int   i, j, k;
  197.     int   texnum;
  198.  
  199.     texnum = Scrap_AllocBlock (p->width, p->height, &x, &y);
  200.     scrap_dirty = true;
  201.     k = 0;
  202.     for (i=0 ; i<p->height ; i++)
  203.       for (j=0 ; j<p->width ; j++, k++)
  204.         scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = p->data[k];
  205.     texnum += scrap_texnum;
  206.     gl->texnum = texnum;
  207.     gl->sl = (x+0.01)/(float)BLOCK_WIDTH;
  208.     gl->sh = (x+p->width-0.01)/(float)BLOCK_WIDTH;
  209.     gl->tl = (y+0.01)/(float)BLOCK_WIDTH;
  210.     gl->th = (y+p->height-0.01)/(float)BLOCK_WIDTH;
  211.  
  212.     pic_count++;
  213.     pic_texels += p->width*p->height;
  214.   }
  215.   else
  216.   {
  217.     gl->texnum = GL_LoadPicTexture (p);
  218.     gl->sl = 0;
  219.     gl->sh = 1;
  220.     gl->tl = 0;
  221.     gl->th = 1;
  222.   }
  223.   return p;
  224. }
  225.  
  226.  
  227. /*
  228. ================
  229. Draw_CachePic
  230. ================
  231. */
  232. qpic_t  *Draw_CachePic (char *path)
  233. {
  234.   cachepic_t  *pic;
  235.   int     i;
  236.   qpic_t    *dat;
  237.   glpic_t   *gl;
  238.  
  239.   for (pic=menu_cachepics, i=0 ; i<menu_numcachepics ; pic++, i++)
  240.     if (!strcmp (path, pic->name))
  241.       return &pic->pic;
  242.  
  243.   if (menu_numcachepics == MAX_CACHED_PICS)
  244.     Sys_Error ("menu_numcachepics == MAX_CACHED_PICS");
  245.   menu_numcachepics++;
  246.   strcpy (pic->name, path);
  247.  
  248. //
  249. // load the pic from disk
  250. //
  251.   dat = (qpic_t *)COM_LoadTempFile (path);  
  252.   if (!dat)
  253.     Sys_Error ("Draw_CachePic: failed to load %s", path);
  254.   SwapPic (dat);
  255.  
  256.   // HACK HACK HACK --- we need to keep the bytes for
  257.   // the translatable player picture just for the menu
  258.   // configuration dialog
  259.   if (!strcmp (path, "gfx/menuplyr.lmp"))
  260.     memcpy (menuplyr_pixels, dat->data, dat->width*dat->height);
  261.  
  262.   pic->pic.width = dat->width;
  263.   pic->pic.height = dat->height;
  264.  
  265.   gl = (glpic_t *)pic->pic.data;
  266.   gl->texnum = GL_LoadPicTexture (dat);
  267.   gl->sl = 0;
  268.   gl->sh = 1;
  269.   gl->tl = 0;
  270.   gl->th = 1;
  271.  
  272.   return &pic->pic;
  273. }
  274.  
  275.  
  276. void Draw_CharToConback (int num, byte *dest)
  277. {
  278.   int   row, col;
  279.   byte  *source;
  280.   int   drawline;
  281.   int   x;
  282.  
  283.   row = num>>4;
  284.   col = num&15;
  285.   source = draw_chars + (row<<10) + (col<<3);
  286.  
  287.   drawline = 8;
  288.  
  289.   while (drawline--)
  290.   {
  291.     for (x=0 ; x<8 ; x++)
  292.       if (source[x] != 255)
  293.         dest[x] = 0x60 + source[x];
  294.     source += 128;
  295.     dest += 320;
  296.   }
  297.  
  298. }
  299.  
  300. typedef struct
  301. {
  302.   char *name;
  303.   int minimize, maximize;
  304. } glmode_t;
  305.  
  306. glmode_t modes[] = {
  307.   {"GL_NEAREST", GL_NEAREST, GL_NEAREST},
  308.   {"GL_LINEAR", GL_LINEAR, GL_LINEAR},
  309.   {"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
  310.   {"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
  311.   {"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
  312.   {"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
  313. };
  314.  
  315. /*
  316. ===============
  317. Draw_TextureMode_f
  318. ===============
  319. */
  320. void Draw_TextureMode_f (void)
  321. {
  322.   int   i;
  323.   gltexture_t *glt;
  324.  
  325.   if (Cmd_Argc() == 1)
  326.   {
  327.     for (i=0 ; i< 6 ; i++)
  328.       if (gl_filter_min == modes[i].minimize)
  329.       {
  330.         Con_Printf ("%s\n", modes[i].name);
  331.         return;
  332.       }
  333.     Con_Printf ("current filter is unknown???\n");
  334.     return;
  335.   }
  336.  
  337.   for (i=0 ; i< 6 ; i++)
  338.   {
  339.     if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) )
  340.       break;
  341.   }
  342.   if (i == 6)
  343.   {
  344.     Con_Printf ("bad filter name\n");
  345.     return;
  346.   }
  347.  
  348.   gl_filter_min = modes[i].minimize;
  349.   gl_filter_max = modes[i].maximize;
  350.  
  351.   // change all the existing mipmap texture objects
  352.   for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  353.   {
  354.     if (glt->mipmap)
  355.     {
  356.       GL_Bind (glt->texnum);
  357.       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  358.       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  359.     }
  360.   }
  361. }
  362.  
  363. /*
  364. ===============
  365. Draw_Init
  366. ===============
  367. */
  368. void Draw_Init (void)
  369. {
  370.   int   i;
  371.   qpic_t  *cb;
  372.   byte  *dest, *src;
  373.   int   x, y;
  374.   char  ver[40];
  375.   glpic_t *gl;
  376.   int   start;
  377.   byte  *ncdata;
  378.   int   f, fstep;
  379.  
  380.  
  381.   Cvar_RegisterVariable (&gl_nobind);
  382.   Cvar_RegisterVariable (&gl_max_size);
  383.   Cvar_RegisterVariable (&gl_picmip);
  384.  
  385.   // 3dfx can only handle 256 wide textures
  386.   if (!Q_strncasecmp ((char *)gl_renderer, "3dfx",4) ||
  387.     strstr((char *)gl_renderer, "Glide"))
  388.     Cvar_Set ("gl_max_size", "256");
  389.  
  390.   Cmd_AddCommand ("gl_texturemode", &Draw_TextureMode_f);
  391.  
  392.   // load the console background and the charset
  393.   // by hand, because we need to write the version
  394.   // string into the background before turning
  395.   // it into a texture
  396.   draw_chars = W_GetLumpName ("conchars");
  397.   for (i=0 ; i<256*64 ; i++)
  398.     if (draw_chars[i] == 0)
  399.       draw_chars[i] = 255;  // proper transparent color
  400.  
  401.   // now turn them into textures
  402.   char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true);
  403.  
  404.   start = Hunk_LowMark();
  405.  
  406.   cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp");  
  407.   if (!cb)
  408.     Sys_Error ("Couldn't load gfx/conback.lmp");
  409.   SwapPic (cb);
  410.  
  411.   // hack the version number directly into the pic
  412. #if defined(__linux__)
  413.   sprintf (ver, "(Linux %2.2f, gl %4.2f) %4.2f", (float)LINUX_VERSION, (float)GLQUAKE_VERSION, (float)VERSION);
  414. #else
  415.   sprintf (ver, "(gl %4.2f) %4.2f", (float)GLQUAKE_VERSION, (float)VERSION);
  416. #endif
  417.   dest = cb->data + 320*186 + 320 - 11 - 8*strlen(ver);
  418.   y = strlen(ver);
  419.   for (x=0 ; x<y ; x++)
  420.     Draw_CharToConback (ver[x], dest+(x<<3));
  421.  
  422. #if 0
  423.   conback->width = vid.conwidth;
  424.   conback->height = vid.conheight;
  425.  
  426.   // scale console to vid size
  427.   dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback");
  428.  
  429.   for (y=0 ; y<vid.conheight ; y++, dest += vid.conwidth)
  430.   {
  431.     src = cb->data + cb->width * (y*cb->height/vid.conheight);
  432.     if (vid.conwidth == cb->width)
  433.       memcpy (dest, src, vid.conwidth);
  434.     else
  435.     {
  436.       f = 0;
  437.       fstep = cb->width*0x10000/vid.conwidth;
  438.       for (x=0 ; x<vid.conwidth ; x+=4)
  439.       {
  440.         dest[x] = src[f>>16];
  441.         f += fstep;
  442.         dest[x+1] = src[f>>16];
  443.         f += fstep;
  444.         dest[x+2] = src[f>>16];
  445.         f += fstep;
  446.         dest[x+3] = src[f>>16];
  447.         f += fstep;
  448.       }
  449.     }
  450.   }
  451. #else
  452.   conback->width = cb->width;
  453.   conback->height = cb->height;
  454.   ncdata = cb->data;
  455. #endif
  456.  
  457.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  458.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  459.  
  460.   gl = (glpic_t *)conback->data;
  461.   gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false);
  462.   gl->sl = 0;
  463.   gl->sh = 1;
  464.   gl->tl = 0;
  465.   gl->th = 1;
  466.   conback->width = vid.width;
  467.   conback->height = vid.height;
  468.  
  469.   // free loaded console
  470.   Hunk_FreeToLowMark(start);
  471.  
  472.   // save a texture slot for translated picture
  473.   translate_texture = texture_extension_number++;
  474.  
  475.   // save slots for scraps
  476.   scrap_texnum = texture_extension_number;
  477.   texture_extension_number += MAX_SCRAPS;
  478.  
  479.   //
  480.   // get the other pics we need
  481.   //
  482.   draw_disc = Draw_PicFromWad ("disc");
  483.   draw_backtile = Draw_PicFromWad ("backtile");
  484. }
  485.  
  486.  
  487.  
  488. /*
  489. ================
  490. Draw_Character
  491.  
  492. Draws one 8*8 graphics character with 0 being transparent.
  493. It can be clipped to the top of the screen to allow the console to be
  494. smoothly scrolled off.
  495. ================
  496. */
  497. void Draw_Character (int x, int y, int num)
  498. {
  499.   byte      *dest;
  500.   byte      *source;
  501.   unsigned short  *pusdest;
  502.   int       drawline; 
  503.   int       row, col;
  504.   float     frow, fcol, size;
  505.  
  506.   if (num == 32)
  507.     return;   // space
  508.  
  509.   num &= 255;
  510.   
  511.   if (y <= -8)
  512.     return;     // totally off screen
  513.  
  514.   row = num>>4;
  515.   col = num&15;
  516.  
  517.   frow = row*0.0625;
  518.   fcol = col*0.0625;
  519.   size = 0.0625;
  520.  
  521.   GL_Bind (char_texture);
  522.  
  523.   glBegin (GL_QUADS);
  524.   glTexCoord2f (fcol, frow);
  525.   glVertex2f (x, y);
  526.   glTexCoord2f (fcol + size, frow);
  527.   glVertex2f (x+8, y);
  528.   glTexCoord2f (fcol + size, frow + size);
  529.   glVertex2f (x+8, y+8);
  530.   glTexCoord2f (fcol, frow + size);
  531.   glVertex2f (x, y+8);
  532.   glEnd ();
  533. }
  534.  
  535. /*
  536. ================
  537. Draw_String
  538. ================
  539. */
  540. void Draw_String (int x, int y, char *str)
  541. {
  542.   while (*str)
  543.   {
  544.     Draw_Character (x, y, *str);
  545.     str++;
  546.     x += 8;
  547.   }
  548. }
  549.  
  550. /*
  551. ================
  552. Draw_DebugChar
  553.  
  554. Draws a single character directly to the upper right corner of the screen.
  555. This is for debugging lockups by drawing different chars in different parts
  556. of the code.
  557. ================
  558. */
  559. void Draw_DebugChar (char num)
  560. {
  561. }
  562.  
  563. /*
  564. =============
  565. Draw_AlphaPic
  566. =============
  567. */
  568. void Draw_AlphaPic (int x, int y, qpic_t *pic, float alpha)
  569. {
  570.   byte      *dest, *source;
  571.   unsigned short  *pusdest;
  572.   int       v, u;
  573.   glpic_t     *gl;
  574.  
  575.   if (scrap_dirty)
  576.     Scrap_Upload ();
  577.   gl = (glpic_t *)pic->data;
  578.   glDisable(GL_ALPHA_TEST);
  579.   glEnable (GL_BLEND);
  580. //  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  581. //  glCullFace(GL_FRONT);
  582.   glColor4f (1,1,1,alpha);
  583.   GL_Bind (gl->texnum);
  584.   glBegin (GL_QUADS);
  585.   glTexCoord2f (gl->sl, gl->tl);
  586.   glVertex2f (x, y);
  587.   glTexCoord2f (gl->sh, gl->tl);
  588.   glVertex2f (x+pic->width, y);
  589.   glTexCoord2f (gl->sh, gl->th);
  590.   glVertex2f (x+pic->width, y+pic->height);
  591.   glTexCoord2f (gl->sl, gl->th);
  592.   glVertex2f (x, y+pic->height);
  593.   glEnd ();
  594.   glColor4f (1,1,1,1);
  595.   glEnable(GL_ALPHA_TEST);
  596.   glDisable (GL_BLEND);
  597. }
  598.  
  599.  
  600. /*
  601. =============
  602. Draw_Pic
  603. =============
  604. */
  605. void Draw_Pic (int x, int y, qpic_t *pic)
  606. {
  607.   byte      *dest, *source;
  608.   unsigned short  *pusdest;
  609.   int       v, u;
  610.   glpic_t     *gl;
  611.  
  612.   if (scrap_dirty)
  613.     Scrap_Upload ();
  614.   gl = (glpic_t *)pic->data;
  615.   glColor4f (1,1,1,1);
  616.   GL_Bind (gl->texnum);
  617.   glBegin (GL_QUADS);
  618.   glTexCoord2f (gl->sl, gl->tl);
  619.   glVertex2f (x, y);
  620.   glTexCoord2f (gl->sh, gl->tl);
  621.   glVertex2f (x+pic->width, y);
  622.   glTexCoord2f (gl->sh, gl->th);
  623.   glVertex2f (x+pic->width, y+pic->height);
  624.   glTexCoord2f (gl->sl, gl->th);
  625.   glVertex2f (x, y+pic->height);
  626.   glEnd ();
  627. }
  628.  
  629.  
  630. /*
  631. =============
  632. Draw_TransPic
  633. =============
  634. */
  635. void Draw_TransPic (int x, int y, qpic_t *pic)
  636. {
  637.   byte  *dest, *source, tbyte;
  638.   unsigned short  *pusdest;
  639.   int       v, u;
  640.  
  641.   if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 ||
  642.      (unsigned)(y + pic->height) > vid.height)
  643.   {
  644.     Sys_Error ("Draw_TransPic: bad coordinates");
  645.   }
  646.     
  647.   Draw_Pic (x, y, pic);
  648. }
  649.  
  650.  
  651. /*
  652. =============
  653. Draw_TransPicTranslate
  654.  
  655. Only used for the player color selection menu
  656. =============
  657. */
  658. void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation)
  659. {
  660.   int       v, u, c;
  661.   unsigned    trans[64*64], *dest;
  662.   byte      *src;
  663.   int       p;
  664.  
  665.   GL_Bind (translate_texture);
  666.  
  667.   c = pic->width * pic->height;
  668.  
  669.   dest = trans;
  670.   for (v=0 ; v<64 ; v++, dest += 64)
  671.   {
  672.     src = &menuplyr_pixels[ ((v*pic->height)>>6) *pic->width];
  673.     for (u=0 ; u<64 ; u++)
  674.     {
  675.       p = src[(u*pic->width)>>6];
  676.       if (p == 255)
  677.         dest[u] = p;
  678.       else
  679.         dest[u] =  d_8to24table[translation[p]];
  680.     }
  681.   }
  682.  
  683.   glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  684.  
  685.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  686.   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  687.  
  688.   glColor3f (1,1,1);
  689.   glBegin (GL_QUADS);
  690.   glTexCoord2f (0, 0);
  691.   glVertex2f (x, y);
  692.   glTexCoord2f (1, 0);
  693.   glVertex2f (x+pic->width, y);
  694.   glTexCoord2f (1, 1);
  695.   glVertex2f (x+pic->width, y+pic->height);
  696.   glTexCoord2f (0, 1);
  697.   glVertex2f (x, y+pic->height);
  698.   glEnd ();
  699. }
  700.  
  701.  
  702. /*
  703. ================
  704. Draw_ConsoleBackground
  705.  
  706. ================
  707. */
  708. void Draw_ConsoleBackground (int lines)
  709. {
  710.   int y = (vid.height * 3) >> 2;
  711.  
  712.   if (lines > y)
  713.     Draw_Pic(0, lines - vid.height, conback);
  714.   else
  715.     Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y);
  716. }
  717.  
  718.  
  719. /*
  720. =============
  721. Draw_TileClear
  722.  
  723. This repeats a 64*64 tile graphic to fill the screen around a sized down
  724. refresh window.
  725. =============
  726. */
  727. void Draw_TileClear (int x, int y, int w, int h)
  728. {
  729.   glColor3f (1,1,1);
  730.   GL_Bind (*(int *)draw_backtile->data);
  731.   glBegin (GL_QUADS);
  732.   glTexCoord2f (x/64.0, y/64.0);
  733.   glVertex2f (x, y);
  734.   glTexCoord2f ( (x+w)/64.0, y/64.0);
  735.   glVertex2f (x+w, y);
  736.   glTexCoord2f ( (x+w)/64.0, (y+h)/64.0);
  737.   glVertex2f (x+w, y+h);
  738.   glTexCoord2f ( x/64.0, (y+h)/64.0 );
  739.   glVertex2f (x, y+h);
  740.   glEnd ();
  741. }
  742.  
  743.  
  744. /*
  745. =============
  746. Draw_Fill
  747.  
  748. Fills a box of pixels with a single color
  749. =============
  750. */
  751. void Draw_Fill (int x, int y, int w, int h, int c)
  752. {
  753.   glDisable (GL_TEXTURE_2D);
  754.   glColor3f (host_basepal[c*3]/255.0,
  755.     host_basepal[c*3+1]/255.0,
  756.     host_basepal[c*3+2]/255.0);
  757.  
  758.   glBegin (GL_QUADS);
  759.  
  760.   glVertex2f (x,y);
  761.   glVertex2f (x+w, y);
  762.   glVertex2f (x+w, y+h);
  763.   glVertex2f (x, y+h);
  764.  
  765.   glEnd ();
  766.   glColor3f (1,1,1);
  767.   glEnable (GL_TEXTURE_2D);
  768. }
  769. //=============================================================================
  770.  
  771. /*
  772. ================
  773. Draw_FadeScreen
  774.  
  775. ================
  776. */
  777. void Draw_FadeScreen (void)
  778. {
  779.   glEnable (GL_BLEND);
  780.   glDisable (GL_TEXTURE_2D);
  781.   glColor4f (0, 0, 0, 0.8);
  782.   glBegin (GL_QUADS);
  783.  
  784.   glVertex2f (0,0);
  785.   glVertex2f (vid.width, 0);
  786.   glVertex2f (vid.width, vid.height);
  787.   glVertex2f (0, vid.height);
  788.  
  789.   glEnd ();
  790.   glColor4f (1,1,1,1);
  791.   glEnable (GL_TEXTURE_2D);
  792.   glDisable (GL_BLEND);
  793.  
  794.   Sbar_Changed();
  795. }
  796.  
  797. //=============================================================================
  798.  
  799. /*
  800. ================
  801. Draw_BeginDisc
  802.  
  803. Draws the little blue disc in the corner of the screen.
  804. Call before beginning any disc IO.
  805. ================
  806. */
  807. void Draw_BeginDisc (void)
  808. {
  809.   if (!draw_disc)
  810.     return;
  811.   glDrawBuffer  (GL_FRONT);
  812.   Draw_Pic (vid.width - 24, 0, draw_disc);
  813.   glDrawBuffer  (GL_BACK);
  814. }
  815.  
  816.  
  817. /*
  818. ================
  819. Draw_EndDisc
  820.  
  821. Erases the disc icon.
  822. Call after completing any disc IO
  823. ================
  824. */
  825. void Draw_EndDisc (void)
  826. {
  827. }
  828.  
  829. /*
  830. ================
  831. GL_Set2D
  832.  
  833. Setup as if the screen was 320*200
  834. ================
  835. */
  836. void GL_Set2D (void)
  837. {
  838.   glViewport (glx, gly, glwidth, glheight);
  839.  
  840.   glMatrixMode(GL_PROJECTION);
  841.     glLoadIdentity ();
  842.   glOrtho  (0, vid.width, vid.height, 0, -99999, 99999);
  843.  
  844.   glMatrixMode(GL_MODELVIEW);
  845.     glLoadIdentity ();
  846.  
  847.   glDisable (GL_DEPTH_TEST);
  848.   glDisable (GL_CULL_FACE);
  849.   glDisable (GL_BLEND);
  850.   glEnable (GL_ALPHA_TEST);
  851. //  glDisable (GL_ALPHA_TEST);
  852.  
  853.   glColor4f (1,1,1,1);
  854. }
  855.  
  856. //====================================================================
  857.  
  858. /*
  859. ================
  860. GL_FindTexture
  861. ================
  862. */
  863. int GL_FindTexture (char *identifier)
  864. {
  865.   int   i;
  866.   gltexture_t *glt;
  867.  
  868.   for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  869.   {
  870.     if (!strcmp (identifier, glt->identifier))
  871.       return gltextures[i].texnum;
  872.   }
  873.  
  874.   return -1;
  875. }
  876.  
  877. /*
  878. ================
  879. GL_ResampleTexture
  880. ================
  881. */
  882. void GL_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight)
  883. {
  884.   int   i, j;
  885.   unsigned  *inrow;
  886.   unsigned  frac, fracstep;
  887.  
  888.   fracstep = inwidth*0x10000/outwidth;
  889.   for (i=0 ; i<outheight ; i++, out += outwidth)
  890.   {
  891.     inrow = in + inwidth*(i*inheight/outheight);
  892.     frac = fracstep >> 1;
  893.     for (j=0 ; j<outwidth ; j+=4)
  894.     {
  895.       out[j] = inrow[frac>>16];
  896.       frac += fracstep;
  897.       out[j+1] = inrow[frac>>16];
  898.       frac += fracstep;
  899.       out[j+2] = inrow[frac>>16];
  900.       frac += fracstep;
  901.       out[j+3] = inrow[frac>>16];
  902.       frac += fracstep;
  903.     }
  904.   }
  905. }
  906.  
  907. /*
  908. ================
  909. GL_Resample8BitTexture -- JACK
  910. ================
  911. */
  912. void GL_Resample8BitTexture (unsigned char *in, int inwidth, int inheight, unsigned char *out,  int outwidth, int outheight)
  913. {
  914.   int   i, j;
  915.   unsigned  char *inrow;
  916.   unsigned  frac, fracstep;
  917.  
  918.   fracstep = inwidth*0x10000/outwidth;
  919.   for (i=0 ; i<outheight ; i++, out += outwidth)
  920.   {
  921.     inrow = in + inwidth*(i*inheight/outheight);
  922.     frac = fracstep >> 1;
  923.     for (j=0 ; j<outwidth ; j+=4)
  924.     {
  925.       out[j] = inrow[frac>>16];
  926.       frac += fracstep;
  927.       out[j+1] = inrow[frac>>16];
  928.       frac += fracstep;
  929.       out[j+2] = inrow[frac>>16];
  930.       frac += fracstep;
  931.       out[j+3] = inrow[frac>>16];
  932.       frac += fracstep;
  933.     }
  934.   }
  935. }
  936.  
  937.  
  938. /*
  939. ================
  940. GL_MipMap
  941.  
  942. Operates in place, quartering the size of the texture
  943. ================
  944. */
  945. void GL_MipMap (byte *in, int width, int height)
  946. {
  947.   int   i, j;
  948.   byte  *out;
  949.  
  950.   width <<=2;
  951.   height >>= 1;
  952.   out = in;
  953.   for (i=0 ; i<height ; i++, in+=width)
  954.   {
  955.     for (j=0 ; j<width ; j+=8, out+=4, in+=8)
  956.     {
  957.       out[0] = (in[0] + in[4] + in[width+0] + in[width+4])>>2;
  958.       out[1] = (in[1] + in[5] + in[width+1] + in[width+5])>>2;
  959.       out[2] = (in[2] + in[6] + in[width+2] + in[width+6])>>2;
  960.       out[3] = (in[3] + in[7] + in[width+3] + in[width+7])>>2;
  961.     }
  962.   }
  963. }
  964.  
  965. /*
  966. ================
  967. GL_MipMap8Bit
  968.  
  969. Mipping for 8 bit textures
  970. ================
  971. */
  972. void GL_MipMap8Bit (byte *in, int width, int height)
  973. {
  974.   int   i, j;
  975.   unsigned short     r,g,b;
  976.   byte  *out, *at1, *at2, *at3, *at4;
  977.  
  978. //  width <<=2;
  979.   height >>= 1;
  980.   out = in;
  981.   for (i=0 ; i<height ; i++, in+=width)
  982.   {
  983.     for (j=0 ; j<width ; j+=2, out+=1, in+=2)
  984.     {
  985.       at1 = (byte *) (d_8to24table + in[0]);
  986.       at2 = (byte *) (d_8to24table + in[1]);
  987.       at3 = (byte *) (d_8to24table + in[width+0]);
  988.       at4 = (byte *) (d_8to24table + in[width+1]);
  989.  
  990.       r = (at1[0]+at2[0]+at3[0]+at4[0]); r>>=5;
  991.       g = (at1[1]+at2[1]+at3[1]+at4[1]); g>>=5;
  992.       b = (at1[2]+at2[2]+at3[2]+at4[2]); b>>=5;
  993.  
  994.       out[0] = d_15to8table[(r<<0) + (g<<5) + (b<<10)];
  995.     }
  996.   }
  997. }
  998.  
  999. /*
  1000. ===============
  1001. GL_Upload32
  1002. ===============
  1003. */
  1004. void GL_Upload32 (unsigned *data, int width, int height,  qboolean mipmap, qboolean alpha)
  1005. {
  1006.   int     samples;
  1007. static  unsigned  scaled[1024*512]; // [512*256];
  1008.   int     scaled_width, scaled_height;
  1009.  
  1010.   for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  1011.     ;
  1012.   for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  1013.     ;
  1014.  
  1015.   scaled_width >>= (int)gl_picmip.value;
  1016.   scaled_height >>= (int)gl_picmip.value;
  1017.  
  1018.   if (scaled_width > gl_max_size.value)
  1019.     scaled_width = gl_max_size.value;
  1020.   if (scaled_height > gl_max_size.value)
  1021.     scaled_height = gl_max_size.value;
  1022.  
  1023.   if (scaled_width * scaled_height > sizeof(scaled)/4)
  1024.     Sys_Error ("GL_LoadTexture: too big");
  1025.  
  1026.   samples = alpha ? gl_alpha_format : gl_solid_format;
  1027.  
  1028. #if 0
  1029.   if (mipmap)
  1030.     gluBuild2DMipmaps (GL_TEXTURE_2D, samples, width, height, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1031.   else if (scaled_width == width && scaled_height == height)
  1032.     glTexImage2D (GL_TEXTURE_2D, 0, samples, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans);
  1033.   else
  1034.   {
  1035.     gluScaleImage (GL_RGBA, width, height, GL_UNSIGNED_BYTE, trans,
  1036.       scaled_width, scaled_height, GL_UNSIGNED_BYTE, scaled);
  1037.     glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  1038.   }
  1039. #else
  1040. texels += scaled_width * scaled_height;
  1041.  
  1042.   if (scaled_width == width && scaled_height == height)
  1043.   {
  1044.     if (!mipmap)
  1045.     {
  1046.       glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  1047.       goto done;
  1048.     }
  1049.     memcpy (scaled, data, width*height*4);
  1050.   }
  1051.   else
  1052.     GL_ResampleTexture (data, width, height, scaled, scaled_width, scaled_height);
  1053.  
  1054.   glTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  1055.   if (mipmap)
  1056.   {
  1057.     int   miplevel;
  1058.  
  1059.     miplevel = 0;
  1060.     while (scaled_width > 1 || scaled_height > 1)
  1061.     {
  1062.       GL_MipMap ((byte *)scaled, scaled_width, scaled_height);
  1063.       scaled_width >>= 1;
  1064.       scaled_height >>= 1;
  1065.       if (scaled_width < 1)
  1066.         scaled_width = 1;
  1067.       if (scaled_height < 1)
  1068.         scaled_height = 1;
  1069.       miplevel++;
  1070.       glTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled);
  1071.     }
  1072.   }
  1073. done: ;
  1074. #endif
  1075.  
  1076.  
  1077.   if (mipmap)
  1078.   {
  1079.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  1080.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1081.   }
  1082.   else
  1083.   {
  1084.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  1085.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1086.   }
  1087. }
  1088.  
  1089. void GL_Upload8_EXT (byte *data, int width, int height,  qboolean mipmap, qboolean alpha) 
  1090. {
  1091.   int     i, s;
  1092.   qboolean  noalpha;
  1093.   int     p;
  1094.   static unsigned j;
  1095.   int     samples;
  1096.     static  unsigned char scaled[1024*512]; // [512*256];
  1097.   int     scaled_width, scaled_height;
  1098.  
  1099.   s = width*height;
  1100.   // if there are no transparent pixels, make it a 3 component
  1101.   // texture even if it was specified as otherwise
  1102.   if (alpha)
  1103.   {
  1104.     noalpha = true;
  1105.     for (i=0 ; i<s ; i++)
  1106.     {
  1107.       if (data[i] == 255)
  1108.         noalpha = false;
  1109.     }
  1110.  
  1111.     if (alpha && noalpha)
  1112.       alpha = false;
  1113.   }
  1114.   for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1)
  1115.     ;
  1116.   for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1)
  1117.     ;
  1118.  
  1119.   scaled_width >>= (int)gl_picmip.value;
  1120.   scaled_height >>= (int)gl_picmip.value;
  1121.  
  1122.   if (scaled_width > gl_max_size.value)
  1123.     scaled_width = gl_max_size.value;
  1124.   if (scaled_height > gl_max_size.value)
  1125.     scaled_height = gl_max_size.value;
  1126.  
  1127.   if (scaled_width * scaled_height > sizeof(scaled))
  1128.     Sys_Error ("GL_LoadTexture: too big");
  1129.  
  1130.   samples = 1; // alpha ? gl_alpha_format : gl_solid_format;
  1131.  
  1132.   texels += scaled_width * scaled_height;
  1133.  
  1134.   if (scaled_width == width && scaled_height == height)
  1135.   {
  1136.     if (!mipmap)
  1137.     {
  1138.       glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX , GL_UNSIGNED_BYTE, data);
  1139.       goto done;
  1140.     }
  1141.     memcpy (scaled, data, width*height);
  1142.   }
  1143.   else
  1144.     GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height);
  1145.  
  1146.   glTexImage2D (GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
  1147.   if (mipmap)
  1148.   {
  1149.     int   miplevel;
  1150.  
  1151.     miplevel = 0;
  1152.     while (scaled_width > 1 || scaled_height > 1)
  1153.     {
  1154.       GL_MipMap8Bit ((byte *)scaled, scaled_width, scaled_height);
  1155.       scaled_width >>= 1;
  1156.       scaled_height >>= 1;
  1157.       if (scaled_width < 1)
  1158.         scaled_width = 1;
  1159.       if (scaled_height < 1)
  1160.         scaled_height = 1;
  1161.       miplevel++;
  1162.       glTexImage2D (GL_TEXTURE_2D, miplevel, GL_COLOR_INDEX8_EXT, scaled_width, scaled_height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, scaled);
  1163.     }
  1164.   }
  1165. done: ;
  1166.  
  1167.  
  1168.   if (mipmap)
  1169.   {
  1170.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
  1171.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1172.   }
  1173.   else
  1174.   {
  1175.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max);
  1176.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);
  1177.   }
  1178. }
  1179.  
  1180. /*
  1181. ===============
  1182. GL_Upload8
  1183. ===============
  1184. */
  1185. void GL_Upload8 (byte *data, int width, int height,  qboolean mipmap, qboolean alpha)
  1186. {
  1187. static  unsigned  trans[640*480];   // FIXME, temporary
  1188.   int     i, s;
  1189.   qboolean  noalpha;
  1190.   int     p;
  1191.  
  1192.   s = width*height;
  1193.   // if there are no transparent pixels, make it a 3 component
  1194.   // texture even if it was specified as otherwise
  1195.   if (alpha)
  1196.   {
  1197.     noalpha = true;
  1198.     for (i=0 ; i<s ; i++)
  1199.     {
  1200.       p = data[i];
  1201.       if (p == 255)
  1202.         noalpha = false;
  1203.       trans[i] = d_8to24table[p];
  1204.     }
  1205.  
  1206.     if (alpha && noalpha)
  1207.       alpha = false;
  1208.   }
  1209.   else
  1210.   {
  1211.     if (s&3)
  1212.       Sys_Error ("GL_Upload8: s&3");
  1213.     for (i=0 ; i<s ; i+=4)
  1214.     {
  1215.       trans[i] = d_8to24table[data[i]];
  1216.       trans[i+1] = d_8to24table[data[i+1]];
  1217.       trans[i+2] = d_8to24table[data[i+2]];
  1218.       trans[i+3] = d_8to24table[data[i+3]];
  1219.     }
  1220.   }
  1221.  
  1222.   if (VID_Is8bit() && !alpha && (data!=scrap_texels[0])) {
  1223.     GL_Upload8_EXT (data, width, height, mipmap, alpha);
  1224.     return;
  1225.   }
  1226.   GL_Upload32 (trans, width, height, mipmap, alpha);
  1227. }
  1228.  
  1229. /*
  1230. ================
  1231. GL_LoadTexture
  1232. ================
  1233. */
  1234. int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha)
  1235. {
  1236.   qboolean  noalpha;
  1237.   int     i, p, s;
  1238.   gltexture_t *glt;
  1239.  
  1240.   // see if the texture is allready present
  1241.   if (identifier[0])
  1242.   {
  1243.     for (i=0, glt=gltextures ; i<numgltextures ; i++, glt++)
  1244.     {
  1245.       if (!strcmp (identifier, glt->identifier))
  1246.       {
  1247.         if (width != glt->width || height != glt->height)
  1248.           Sys_Error ("GL_LoadTexture: cache mismatch");
  1249.         return gltextures[i].texnum;
  1250.       }
  1251.     }
  1252.   }
  1253.   else {
  1254.     glt = &gltextures[numgltextures];
  1255.     numgltextures++;
  1256.   }
  1257.  
  1258.   strcpy (glt->identifier, identifier);
  1259.   glt->texnum = texture_extension_number;
  1260.   glt->width = width;
  1261.   glt->height = height;
  1262.   glt->mipmap = mipmap;
  1263.  
  1264.   GL_Bind(texture_extension_number );
  1265.  
  1266.   GL_Upload8 (data, width, height, mipmap, alpha);
  1267.  
  1268.   texture_extension_number++;
  1269.  
  1270.   return texture_extension_number-1;
  1271. }
  1272.  
  1273. /*
  1274. ================
  1275. GL_LoadPicTexture
  1276. ================
  1277. */
  1278. int GL_LoadPicTexture (qpic_t *pic)
  1279. {
  1280.   return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true);
  1281. }
  1282.  
  1283. /****************************************/
  1284.  
  1285. static GLenum oldtarget = TEXTURE0_SGIS;
  1286.  
  1287. void GL_SelectTexture (GLenum target) 
  1288. {
  1289.   if (!gl_mtexable)
  1290.     return;
  1291.   qglSelectTextureSGIS(target);
  1292.   if (target == oldtarget) 
  1293.     return;
  1294.   cnttextures[oldtarget-TEXTURE0_SGIS] = currenttexture;
  1295.   currenttexture = cnttextures[target-TEXTURE0_SGIS];
  1296.   oldtarget = target;
  1297. }
  1298.