Annotation of quakeworld/client/gl_draw.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.