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

unix.superglobalmegacorp.com

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