|
|
1.1.1.3 ! root 1: // Emacs style mode select -*- C++ -*- ! 2: //----------------------------------------------------------------------------- ! 3: // ! 4: // $Id:$ ! 5: // ! 6: // Copyright (C) 1993-1996 by id Software, Inc. ! 7: // ! 8: // This source is available for distribution and/or modification ! 9: // only under the terms of the DOOM Source Code License as ! 10: // published by id Software. All rights reserved. ! 11: // ! 12: // The source is distributed in the hope that it will be useful, ! 13: // but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License ! 15: // for more details. ! 16: // ! 17: // $Log:$ ! 18: // ! 19: // DESCRIPTION: ! 20: // The actual span/column drawing functions. ! 21: // Here find the main potential for optimization, ! 22: // e.g. inline assembly, different algorithms. ! 23: // ! 24: //----------------------------------------------------------------------------- 1.1 root 25: 26: 1.1.1.3 ! root 27: static const char ! 28: rcsid[] = "$Id: r_draw.c,v 1.4 1997/02/03 16:47:55 b1 Exp $"; 1.1 root 29: 30: 1.1.1.3 ! root 31: #include "doomdef.h" 1.1 root 32: 1.1.1.3 ! root 33: #include "i_system.h" ! 34: #include "z_zone.h" ! 35: #include "w_wad.h" 1.1 root 36: 1.1.1.3 ! root 37: #include "r_local.h" 1.1 root 38: 1.1.1.3 ! root 39: // Needs access to LFB (guess what). ! 40: #include "v_video.h" 1.1 root 41: 1.1.1.3 ! root 42: // State. ! 43: #include "doomstat.h" 1.1 root 44: 45: 1.1.1.3 ! root 46: // ? ! 47: #define MAXWIDTH 1120 ! 48: #define MAXHEIGHT 832 1.1 root 49: 1.1.1.3 ! root 50: // status bar height at bottom of screen ! 51: #define SBARHEIGHT 32 1.1 root 52: 1.1.1.3 ! root 53: // ! 54: // All drawing to the view buffer is accomplished in this file. ! 55: // The other refresh files only know about ccordinates, ! 56: // not the architecture of the frame buffer. ! 57: // Conveniently, the frame buffer is a linear one, ! 58: // and we need only the base address, ! 59: // and the total size == width*height*depth/8., ! 60: // 1.1 root 61: 62: 1.1.1.3 ! root 63: byte* viewimage; ! 64: int viewwidth; ! 65: int scaledviewwidth; ! 66: int viewheight; ! 67: int viewwindowx; ! 68: int viewwindowy; ! 69: byte* ylookup[MAXHEIGHT]; ! 70: int columnofs[MAXWIDTH]; ! 71: ! 72: // Color tables for different players, ! 73: // translate a limited part to another ! 74: // (color ramps used for suit colors). ! 75: // ! 76: byte translations[3][256]; ! 77: ! 78: 1.1 root 79: 1.1.1.2 root 80: 81: // 1.1.1.3 ! root 82: // R_DrawColumn ! 83: // Source is the top of the column to scale. 1.1.1.2 root 84: // 1.1.1.3 ! root 85: lighttable_t* dc_colormap; ! 86: int dc_x; ! 87: int dc_yl; ! 88: int dc_yh; ! 89: fixed_t dc_iscale; ! 90: fixed_t dc_texturemid; 1.1.1.2 root 91: 1.1.1.3 ! root 92: // first pixel in a column (possibly virtual) ! 93: byte* dc_source; 1.1 root 94: 1.1.1.3 ! root 95: // just for profiling ! 96: int dccount; 1.1 root 97: 1.1.1.3 ! root 98: // ! 99: // A column is a vertical slice/span from a wall texture that, ! 100: // given the DOOM style restrictions on the view orientation, ! 101: // will always have constant z depth. ! 102: // Thus a special case loop for very fast rendering can ! 103: // be used. It has also been used with Wolfenstein 3D. ! 104: // ! 105: void R_DrawColumn (void) ! 106: { ! 107: int count; ! 108: byte* dest; ! 109: fixed_t frac; ! 110: fixed_t fracstep; ! 111: ! 112: count = dc_yh - dc_yl; ! 113: ! 114: // Zero length, column does not exceed a pixel. ! 115: if (count < 0) ! 116: return; ! 117: ! 118: #ifdef RANGECHECK ! 119: if ((unsigned)dc_x >= SCREENWIDTH ! 120: || dc_yl < 0 ! 121: || dc_yh >= SCREENHEIGHT) ! 122: I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); ! 123: #endif ! 124: ! 125: // Framebuffer destination address. ! 126: // Use ylookup LUT to avoid multiply with ScreenWidth. ! 127: // Use columnofs LUT for subwindows? ! 128: dest = ylookup[dc_yl] + columnofs[dc_x]; ! 129: ! 130: // Determine scaling, ! 131: // which is the only mapping to be done. ! 132: fracstep = dc_iscale; ! 133: frac = dc_texturemid + (dc_yl-centery)*fracstep; ! 134: ! 135: // Inner loop that does the actual texture mapping, ! 136: // e.g. a DDA-lile scaling. ! 137: // This is as fast as it gets. ! 138: do ! 139: { ! 140: // Re-map color indices from wall texture column ! 141: // using a lighting/special effects LUT. ! 142: *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; ! 143: ! 144: dest += SCREENWIDTH; ! 145: frac += fracstep; ! 146: ! 147: } while (count--); ! 148: } ! 149: ! 150: ! 151: ! 152: // UNUSED. ! 153: // Loop unrolled. ! 154: #if 0 ! 155: void R_DrawColumn (void) ! 156: { ! 157: int count; ! 158: byte* source; ! 159: byte* dest; ! 160: byte* colormap; ! 161: ! 162: unsigned frac; ! 163: unsigned fracstep; ! 164: unsigned fracstep2; ! 165: unsigned fracstep3; ! 166: unsigned fracstep4; ! 167: ! 168: count = dc_yh - dc_yl + 1; ! 169: ! 170: source = dc_source; ! 171: colormap = dc_colormap; ! 172: dest = ylookup[dc_yl] + columnofs[dc_x]; ! 173: ! 174: fracstep = dc_iscale<<9; ! 175: frac = (dc_texturemid + (dc_yl-centery)*dc_iscale)<<9; ! 176: ! 177: fracstep2 = fracstep+fracstep; ! 178: fracstep3 = fracstep2+fracstep; ! 179: fracstep4 = fracstep3+fracstep; ! 180: ! 181: while (count >= 8) ! 182: { ! 183: dest[0] = colormap[source[frac>>25]]; ! 184: dest[SCREENWIDTH] = colormap[source[(frac+fracstep)>>25]]; ! 185: dest[SCREENWIDTH*2] = colormap[source[(frac+fracstep2)>>25]]; ! 186: dest[SCREENWIDTH*3] = colormap[source[(frac+fracstep3)>>25]]; ! 187: ! 188: frac += fracstep4; ! 189: ! 190: dest[SCREENWIDTH*4] = colormap[source[frac>>25]]; ! 191: dest[SCREENWIDTH*5] = colormap[source[(frac+fracstep)>>25]]; ! 192: dest[SCREENWIDTH*6] = colormap[source[(frac+fracstep2)>>25]]; ! 193: dest[SCREENWIDTH*7] = colormap[source[(frac+fracstep3)>>25]]; ! 194: ! 195: frac += fracstep4; ! 196: dest += SCREENWIDTH*8; ! 197: count -= 8; ! 198: } ! 199: ! 200: while (count > 0) ! 201: { ! 202: *dest = colormap[source[frac>>25]]; ! 203: dest += SCREENWIDTH; ! 204: frac += fracstep; ! 205: count--; ! 206: } ! 207: } ! 208: #endif ! 209: ! 210: ! 211: void R_DrawColumnLow (void) ! 212: { ! 213: int count; ! 214: byte* dest; ! 215: byte* dest2; ! 216: fixed_t frac; ! 217: fixed_t fracstep; ! 218: ! 219: count = dc_yh - dc_yl; ! 220: ! 221: // Zero length. ! 222: if (count < 0) ! 223: return; ! 224: ! 225: #ifdef RANGECHECK ! 226: if ((unsigned)dc_x >= SCREENWIDTH ! 227: || dc_yl < 0 ! 228: || dc_yh >= SCREENHEIGHT) ! 229: { ! 230: ! 231: I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); ! 232: } ! 233: // dccount++; ! 234: #endif ! 235: // Blocky mode, need to multiply by 2. ! 236: dc_x <<= 1; ! 237: ! 238: dest = ylookup[dc_yl] + columnofs[dc_x]; ! 239: dest2 = ylookup[dc_yl] + columnofs[dc_x+1]; ! 240: ! 241: fracstep = dc_iscale; ! 242: frac = dc_texturemid + (dc_yl-centery)*fracstep; ! 243: ! 244: do ! 245: { ! 246: // Hack. Does not work corretly. ! 247: *dest2 = *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]]; ! 248: dest += SCREENWIDTH; ! 249: dest2 += SCREENWIDTH; ! 250: frac += fracstep; 1.1 root 251: 1.1.1.3 ! root 252: } while (count--); 1.1 root 253: } 254: 255: 1.1.1.3 ! root 256: // ! 257: // Spectre/Invisibility. ! 258: // ! 259: #define FUZZTABLE 50 ! 260: #define FUZZOFF (SCREENWIDTH) ! 261: 1.1 root 262: 1.1.1.3 ! root 263: int fuzzoffset[FUZZTABLE] = 1.1 root 264: { 1.1.1.3 ! root 265: FUZZOFF,-FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, ! 266: FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, ! 267: FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF, ! 268: FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF, ! 269: FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF, ! 270: FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF, ! 271: FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF ! 272: }; 1.1 root 273: 1.1.1.3 ! root 274: int fuzzpos = 0; 1.1 root 275: 276: 1.1.1.2 root 277: // 1.1.1.3 ! root 278: // Framebuffer postprocessing. ! 279: // Creates a fuzzy image by copying pixels ! 280: // from adjacent ones to left and right. ! 281: // Used with an all black colormap, this ! 282: // could create the SHADOW effect, ! 283: // i.e. spectres and invisible players. 1.1.1.2 root 284: // 1.1.1.3 ! root 285: void R_DrawFuzzColumn (void) ! 286: { ! 287: int count; ! 288: byte* dest; ! 289: fixed_t frac; ! 290: fixed_t fracstep; ! 291: ! 292: // Adjust borders. Low... ! 293: if (!dc_yl) ! 294: dc_yl = 1; ! 295: ! 296: // .. and high. ! 297: if (dc_yh == viewheight-1) ! 298: dc_yh = viewheight - 2; ! 299: ! 300: count = dc_yh - dc_yl; ! 301: ! 302: // Zero length. ! 303: if (count < 0) ! 304: return; ! 305: ! 306: ! 307: #ifdef RANGECHECK ! 308: if ((unsigned)dc_x >= SCREENWIDTH ! 309: || dc_yl < 0 || dc_yh >= SCREENHEIGHT) ! 310: { ! 311: I_Error ("R_DrawFuzzColumn: %i to %i at %i", ! 312: dc_yl, dc_yh, dc_x); ! 313: } 1.1 root 314: #endif 315: 316: 1.1.1.3 ! root 317: // Keep till detailshift bug in blocky mode fixed, ! 318: // or blocky mode removed. ! 319: /* WATCOM code ! 320: if (detailshift) ! 321: { ! 322: if (dc_x & 1) 1.1 root 323: { 1.1.1.3 ! root 324: outpw (GC_INDEX,GC_READMAP+(2<<8) ); ! 325: outp (SC_INDEX+1,12); ! 326: } ! 327: else ! 328: { ! 329: outpw (GC_INDEX,GC_READMAP); ! 330: outp (SC_INDEX+1,3); ! 331: } ! 332: dest = destview + dc_yl*80 + (dc_x>>1); ! 333: } ! 334: else ! 335: { ! 336: outpw (GC_INDEX,GC_READMAP+((dc_x&3)<<8) ); ! 337: outp (SC_INDEX+1,1<<(dc_x&3)); ! 338: dest = destview + dc_yl*80 + (dc_x>>2); ! 339: }*/ ! 340: ! 341: ! 342: // Does not work with blocky mode. ! 343: dest = ylookup[dc_yl] + columnofs[dc_x]; ! 344: ! 345: // Looks familiar. ! 346: fracstep = dc_iscale; ! 347: frac = dc_texturemid + (dc_yl-centery)*fracstep; ! 348: ! 349: // Looks like an attempt at dithering, ! 350: // using the colormap #6 (of 0-31, a bit ! 351: // brighter than average). ! 352: do ! 353: { ! 354: // Lookup framebuffer, and retrieve ! 355: // a pixel that is either one column ! 356: // left or right of the current one. ! 357: // Add index from colormap to index. ! 358: *dest = colormaps[6*256+dest[fuzzoffset[fuzzpos]]]; ! 359: ! 360: // Clamp table lookup index. ! 361: if (++fuzzpos == FUZZTABLE) ! 362: fuzzpos = 0; ! 363: ! 364: dest += SCREENWIDTH; ! 365: ! 366: frac += fracstep; ! 367: } while (count--); ! 368: } ! 369: ! 370: ! 371: 1.1 root 372: 1.1.1.2 root 373: // 1.1.1.3 ! root 374: // R_DrawTranslatedColumn ! 375: // Used to draw player sprites ! 376: // with the green colorramp mapped to others. ! 377: // Could be used with different translation ! 378: // tables, e.g. the lighter colored version ! 379: // of the BaronOfHell, the HellKnight, uses ! 380: // identical sprites, kinda brightened up. 1.1.1.2 root 381: // 1.1.1.3 ! root 382: byte* dc_translation; ! 383: byte* translationtables; 1.1.1.2 root 384: 1.1.1.3 ! root 385: void R_DrawTranslatedColumn (void) ! 386: { ! 387: int count; ! 388: byte* dest; ! 389: fixed_t frac; ! 390: fixed_t fracstep; ! 391: ! 392: count = dc_yh - dc_yl; ! 393: if (count < 0) ! 394: return; ! 395: ! 396: #ifdef RANGECHECK ! 397: if ((unsigned)dc_x >= SCREENWIDTH ! 398: || dc_yl < 0 ! 399: || dc_yh >= SCREENHEIGHT) ! 400: { ! 401: I_Error ( "R_DrawColumn: %i to %i at %i", ! 402: dc_yl, dc_yh, dc_x); ! 403: } ! 404: ! 405: #endif ! 406: ! 407: ! 408: // WATCOM VGA specific. ! 409: /* Keep for fixing. ! 410: if (detailshift) ! 411: { ! 412: if (dc_x & 1) ! 413: outp (SC_INDEX+1,12); ! 414: else ! 415: outp (SC_INDEX+1,3); 1.1.1.2 root 416: 1.1.1.3 ! root 417: dest = destview + dc_yl*80 + (dc_x>>1); ! 418: } ! 419: else ! 420: { ! 421: outp (SC_INDEX+1,1<<(dc_x&3)); ! 422: ! 423: dest = destview + dc_yl*80 + (dc_x>>2); ! 424: }*/ ! 425: ! 426: ! 427: // FIXME. As above. ! 428: dest = ylookup[dc_yl] + columnofs[dc_x]; ! 429: ! 430: // Looks familiar. ! 431: fracstep = dc_iscale; ! 432: frac = dc_texturemid + (dc_yl-centery)*fracstep; ! 433: ! 434: // Here we do an additional index re-mapping. ! 435: do ! 436: { ! 437: // Translation tables are used ! 438: // to map certain colorramps to other ones, ! 439: // used with PLAY sprites. ! 440: // Thus the "green" ramp of the player 0 sprite ! 441: // is mapped to gray, red, black/indigo. ! 442: *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; ! 443: dest += SCREENWIDTH; ! 444: ! 445: frac += fracstep; ! 446: } while (count--); ! 447: } ! 448: ! 449: 1.1.1.2 root 450: 451: 1.1 root 452: // 1.1.1.3 ! root 453: // R_InitTranslationTables ! 454: // Creates the translation tables to map ! 455: // the green color ramp to gray, brown, red. ! 456: // Assumes a given structure of the PLAYPAL. ! 457: // Could be read from a lump instead. 1.1 root 458: // 459: void R_InitTranslationTables (void) 460: { 1.1.1.3 ! root 461: int i; ! 462: ! 463: translationtables = Z_Malloc (256*3+255, PU_STATIC, 0); ! 464: translationtables = (byte *)(( (int)translationtables + 255 )& ~255); ! 465: ! 466: // translate just the 16 green colors ! 467: for (i=0 ; i<256 ; i++) ! 468: { ! 469: if (i >= 0x70 && i<= 0x7f) ! 470: { ! 471: // map green ramp to gray, brown, red ! 472: translationtables[i] = 0x60 + (i&0xf); ! 473: translationtables [i+256] = 0x40 + (i&0xf); ! 474: translationtables [i+512] = 0x20 + (i&0xf); ! 475: } ! 476: else 1.1.1.2 root 477: { 1.1.1.3 ! root 478: // Keep all other colors as is. ! 479: translationtables[i] = translationtables[i+256] ! 480: = translationtables[i+512] = i; 1.1 root 481: } 1.1.1.3 ! root 482: } 1.1 root 483: } 484: 485: 486: 487: 1.1.1.3 ! root 488: // ! 489: // R_DrawSpan ! 490: // With DOOM style restrictions on view orientation, ! 491: // the floors and ceilings consist of horizontal slices ! 492: // or spans with constant z depth. ! 493: // However, rotation around the world z axis is possible, ! 494: // thus this mapping, while simpler and faster than ! 495: // perspective correct texture mapping, has to traverse ! 496: // the texture at an angle in all but a few cases. ! 497: // In consequence, flats are not stored by column (like walls), ! 498: // and the inner loop has to step in texture space u and v. ! 499: // ! 500: int ds_y; ! 501: int ds_x1; ! 502: int ds_x2; ! 503: ! 504: lighttable_t* ds_colormap; ! 505: ! 506: fixed_t ds_xfrac; ! 507: fixed_t ds_yfrac; ! 508: fixed_t ds_xstep; ! 509: fixed_t ds_ystep; 1.1 root 510: 1.1.1.3 ! root 511: // start of a 64*64 tile image ! 512: byte* ds_source; 1.1 root 513: 1.1.1.3 ! root 514: // just for profiling ! 515: int dscount; 1.1 root 516: 517: 1.1.1.3 ! root 518: // ! 519: // Draws the actual span. ! 520: void R_DrawSpan (void) ! 521: { ! 522: fixed_t xfrac; ! 523: fixed_t yfrac; ! 524: byte* dest; ! 525: int count; ! 526: int spot; ! 527: ! 528: #ifdef RANGECHECK ! 529: if (ds_x2 < ds_x1 ! 530: || ds_x1<0 ! 531: || ds_x2>=SCREENWIDTH ! 532: || (unsigned)ds_y>SCREENHEIGHT) ! 533: { ! 534: I_Error( "R_DrawSpan: %i to %i at %i", ! 535: ds_x1,ds_x2,ds_y); ! 536: } ! 537: // dscount++; ! 538: #endif ! 539: ! 540: ! 541: xfrac = ds_xfrac; ! 542: yfrac = ds_yfrac; ! 543: ! 544: dest = ylookup[ds_y] + columnofs[ds_x1]; ! 545: ! 546: // We do not check for zero spans here? ! 547: count = ds_x2 - ds_x1; ! 548: ! 549: do ! 550: { ! 551: // Current texture index in u,v. ! 552: spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); ! 553: ! 554: // Lookup pixel from flat texture tile, ! 555: // re-index using light/colormap. ! 556: *dest++ = ds_colormap[ds_source[spot]]; ! 557: ! 558: // Next step in u,v. ! 559: xfrac += ds_xstep; ! 560: yfrac += ds_ystep; ! 561: ! 562: } while (count--); ! 563: } 1.1 root 564: 565: 566: 1.1.1.3 ! root 567: // UNUSED. ! 568: // Loop unrolled by 4. ! 569: #if 0 ! 570: void R_DrawSpan (void) ! 571: { ! 572: unsigned position, step; ! 573: ! 574: byte* source; ! 575: byte* colormap; ! 576: byte* dest; ! 577: ! 578: unsigned count; ! 579: usingned spot; ! 580: unsigned value; ! 581: unsigned temp; ! 582: unsigned xtemp; ! 583: unsigned ytemp; ! 584: ! 585: position = ((ds_xfrac<<10)&0xffff0000) | ((ds_yfrac>>6)&0xffff); ! 586: step = ((ds_xstep<<10)&0xffff0000) | ((ds_ystep>>6)&0xffff); ! 587: ! 588: source = ds_source; ! 589: colormap = ds_colormap; ! 590: dest = ylookup[ds_y] + columnofs[ds_x1]; ! 591: count = ds_x2 - ds_x1 + 1; ! 592: ! 593: while (count >= 4) ! 594: { ! 595: ytemp = position>>4; ! 596: ytemp = ytemp & 4032; ! 597: xtemp = position>>26; ! 598: spot = xtemp | ytemp; ! 599: position += step; ! 600: dest[0] = colormap[source[spot]]; ! 601: ! 602: ytemp = position>>4; ! 603: ytemp = ytemp & 4032; ! 604: xtemp = position>>26; ! 605: spot = xtemp | ytemp; ! 606: position += step; ! 607: dest[1] = colormap[source[spot]]; ! 608: ! 609: ytemp = position>>4; ! 610: ytemp = ytemp & 4032; ! 611: xtemp = position>>26; ! 612: spot = xtemp | ytemp; ! 613: position += step; ! 614: dest[2] = colormap[source[spot]]; ! 615: ! 616: ytemp = position>>4; ! 617: ytemp = ytemp & 4032; ! 618: xtemp = position>>26; ! 619: spot = xtemp | ytemp; ! 620: position += step; ! 621: dest[3] = colormap[source[spot]]; ! 622: ! 623: count -= 4; ! 624: dest += 4; ! 625: } ! 626: while (count > 0) ! 627: { ! 628: ytemp = position>>4; ! 629: ytemp = ytemp & 4032; ! 630: xtemp = position>>26; ! 631: spot = xtemp | ytemp; ! 632: position += step; ! 633: *dest++ = colormap[source[spot]]; ! 634: count--; ! 635: } ! 636: } ! 637: #endif 1.1 root 638: 639: 1.1.1.3 ! root 640: // ! 641: // Again.. ! 642: // ! 643: void R_DrawSpanLow (void) ! 644: { ! 645: fixed_t xfrac; ! 646: fixed_t yfrac; ! 647: byte* dest; ! 648: int count; ! 649: int spot; ! 650: ! 651: #ifdef RANGECHECK ! 652: if (ds_x2 < ds_x1 ! 653: || ds_x1<0 ! 654: || ds_x2>=SCREENWIDTH ! 655: || (unsigned)ds_y>SCREENHEIGHT) ! 656: { ! 657: I_Error( "R_DrawSpan: %i to %i at %i", ! 658: ds_x1,ds_x2,ds_y); ! 659: } ! 660: // dscount++; ! 661: #endif ! 662: ! 663: xfrac = ds_xfrac; ! 664: yfrac = ds_yfrac; ! 665: ! 666: // Blocky mode, need to multiply by 2. ! 667: ds_x1 <<= 1; ! 668: ds_x2 <<= 1; ! 669: ! 670: dest = ylookup[ds_y] + columnofs[ds_x1]; ! 671: ! 672: ! 673: count = ds_x2 - ds_x1; ! 674: do ! 675: { ! 676: spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63); ! 677: // Lowres/blocky mode does it twice, ! 678: // while scale is adjusted appropriately. ! 679: *dest++ = ds_colormap[ds_source[spot]]; ! 680: *dest++ = ds_colormap[ds_source[spot]]; 1.1 root 681: 1.1.1.3 ! root 682: xfrac += ds_xstep; ! 683: yfrac += ds_ystep; ! 684: ! 685: } while (count--); 1.1 root 686: } 687: 1.1.1.3 ! root 688: // ! 689: // R_InitBuffer ! 690: // Creats lookup tables that avoid ! 691: // multiplies and other hazzles ! 692: // for getting the framebuffer address ! 693: // of a pixel to draw. ! 694: // ! 695: void ! 696: R_InitBuffer ! 697: ( int width, ! 698: int height ) ! 699: { ! 700: int i; ! 701: ! 702: // Handle resize, ! 703: // e.g. smaller view windows ! 704: // with border and/or status bar. ! 705: viewwindowx = (SCREENWIDTH-width) >> 1; ! 706: ! 707: // Column offset. For windows. ! 708: for (i=0 ; i<width ; i++) ! 709: columnofs[i] = viewwindowx + i; ! 710: ! 711: // Samw with base row offset. ! 712: if (width == SCREENWIDTH) ! 713: viewwindowy = 0; ! 714: else ! 715: viewwindowy = (SCREENHEIGHT-SBARHEIGHT-height) >> 1; ! 716: ! 717: // Preclaculate all row offsets. ! 718: for (i=0 ; i<height ; i++) ! 719: ylookup[i] = screens[0] + (i+viewwindowy)*SCREENWIDTH; ! 720: } ! 721: ! 722: 1.1 root 723: 724: 1.1.1.3 ! root 725: // ! 726: // R_FillBackScreen ! 727: // Fills the back screen with a pattern ! 728: // for variable screen sizes ! 729: // Also draws a beveled edge. ! 730: // ! 731: void R_FillBackScreen (void) ! 732: { ! 733: byte* src; ! 734: byte* dest; ! 735: int x; ! 736: int y; ! 737: patch_t* patch; ! 738: ! 739: // DOOM border patch. ! 740: char name1[] = "FLOOR7_2"; ! 741: ! 742: // DOOM II border patch. ! 743: char name2[] = "GRNROCK"; ! 744: ! 745: char* name; ! 746: ! 747: if (scaledviewwidth == 320) ! 748: return; ! 749: ! 750: if ( gamemode == commercial) ! 751: name = name2; ! 752: else ! 753: name = name1; ! 754: ! 755: src = W_CacheLumpName (name, PU_CACHE); ! 756: dest = screens[1]; ! 757: ! 758: for (y=0 ; y<SCREENHEIGHT-SBARHEIGHT ; y++) ! 759: { ! 760: for (x=0 ; x<SCREENWIDTH/64 ; x++) ! 761: { ! 762: memcpy (dest, src+((y&63)<<6), 64); ! 763: dest += 64; ! 764: } ! 765: ! 766: if (SCREENWIDTH&63) ! 767: { ! 768: memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63); ! 769: dest += (SCREENWIDTH&63); ! 770: } ! 771: } ! 772: ! 773: patch = W_CacheLumpName ("brdr_t",PU_CACHE); ! 774: ! 775: for (x=0 ; x<scaledviewwidth ; x+=8) ! 776: V_DrawPatch (viewwindowx+x,viewwindowy-8,1,patch); ! 777: patch = W_CacheLumpName ("brdr_b",PU_CACHE); ! 778: ! 779: for (x=0 ; x<scaledviewwidth ; x+=8) ! 780: V_DrawPatch (viewwindowx+x,viewwindowy+viewheight,1,patch); ! 781: patch = W_CacheLumpName ("brdr_l",PU_CACHE); ! 782: ! 783: for (y=0 ; y<viewheight ; y+=8) ! 784: V_DrawPatch (viewwindowx-8,viewwindowy+y,1,patch); ! 785: patch = W_CacheLumpName ("brdr_r",PU_CACHE); ! 786: ! 787: for (y=0 ; y<viewheight ; y+=8) ! 788: V_DrawPatch (viewwindowx+scaledviewwidth,viewwindowy+y,1,patch); ! 789: ! 790: ! 791: // Draw beveled edge. ! 792: V_DrawPatch (viewwindowx-8, ! 793: viewwindowy-8, ! 794: 1, ! 795: W_CacheLumpName ("brdr_tl",PU_CACHE)); ! 796: ! 797: V_DrawPatch (viewwindowx+scaledviewwidth, ! 798: viewwindowy-8, ! 799: 1, ! 800: W_CacheLumpName ("brdr_tr",PU_CACHE)); ! 801: ! 802: V_DrawPatch (viewwindowx-8, ! 803: viewwindowy+viewheight, ! 804: 1, ! 805: W_CacheLumpName ("brdr_bl",PU_CACHE)); ! 806: ! 807: V_DrawPatch (viewwindowx+scaledviewwidth, ! 808: viewwindowy+viewheight, ! 809: 1, ! 810: W_CacheLumpName ("brdr_br",PU_CACHE)); ! 811: } ! 812: 1.1 root 813: 1.1.1.3 ! root 814: // ! 815: // Copy a screen buffer. ! 816: // ! 817: void ! 818: R_VideoErase ! 819: ( unsigned ofs, ! 820: int count ) ! 821: { ! 822: // LFB copy. ! 823: // This might not be a good idea if memcpy ! 824: // is not optiomal, e.g. byte by byte on ! 825: // a 32bit CPU, as GNU GCC/Linux libc did ! 826: // at one point. ! 827: memcpy (screens[0]+ofs, screens[1]+ofs, count); ! 828: } 1.1 root 829: 830: 1.1.1.3 ! root 831: // ! 832: // R_DrawViewBorder ! 833: // Draws the border around the view ! 834: // for different size windows? ! 835: // ! 836: void ! 837: V_MarkRect ! 838: ( int x, ! 839: int y, ! 840: int width, ! 841: int height ); ! 842: ! 843: void R_DrawViewBorder (void) ! 844: { ! 845: int top; ! 846: int side; ! 847: int ofs; ! 848: int i; ! 849: ! 850: if (scaledviewwidth == SCREENWIDTH) ! 851: return; ! 852: ! 853: top = ((SCREENHEIGHT-SBARHEIGHT)-viewheight)/2; ! 854: side = (SCREENWIDTH-scaledviewwidth)/2; ! 855: ! 856: // copy top and one line of left side ! 857: R_VideoErase (0, top*SCREENWIDTH+side); ! 858: ! 859: // copy one line of right side and bottom ! 860: ofs = (viewheight+top)*SCREENWIDTH-side; ! 861: R_VideoErase (ofs, top*SCREENWIDTH+side); ! 862: ! 863: // copy sides using wraparound ! 864: ofs = top*SCREENWIDTH + SCREENWIDTH-side; ! 865: side <<= 1; ! 866: ! 867: for (i=1 ; i<viewheight ; i++) ! 868: { ! 869: R_VideoErase (ofs, side); ! 870: ofs += SCREENWIDTH; ! 871: } ! 872: ! 873: // ? ! 874: V_MarkRect (0,0,SCREENWIDTH, SCREENHEIGHT-SBARHEIGHT); ! 875: } ! 876: ! 877:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.