|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.