|
|
1.1 ! root 1: // R_things.c ! 2: #include <stdio.h> ! 3: #include <stdlib.h> ! 4: #include "DoomDef.h" ! 5: #include "R_local.h" ! 6: ! 7: void R_DrawColumn (void); ! 8: void R_DrawFuzzColumn (void); ! 9: ! 10: typedef struct ! 11: { ! 12: int x1, x2; ! 13: ! 14: int column; ! 15: int topclip; ! 16: int bottomclip; ! 17: } maskdraw_t; ! 18: ! 19: /* ! 20: ! 21: Sprite rotation 0 is facing the viewer, rotation 1 is one angle turn CLOCKWISE around the axis. ! 22: This is not the same as the angle, which increases counter clockwise ! 23: (protractor). There was a lot of stuff grabbed wrong, so I changed it... ! 24: ! 25: */ ! 26: ! 27: ! 28: fixed_t pspritescale, pspriteiscale; ! 29: ! 30: lighttable_t **spritelights; ! 31: ! 32: // constant arrays used for psprite clipping and initializing clipping ! 33: short negonearray[SCREENWIDTH]; ! 34: short screenheightarray[SCREENWIDTH]; ! 35: ! 36: /* ! 37: =============================================================================== ! 38: ! 39: INITIALIZATION FUNCTIONS ! 40: ! 41: =============================================================================== ! 42: */ ! 43: ! 44: // variables used to look up and range check thing_t sprites patches ! 45: spritedef_t *sprites; ! 46: int numsprites; ! 47: ! 48: spriteframe_t sprtemp[26]; ! 49: int maxframe; ! 50: char *spritename; ! 51: ! 52: ! 53: ! 54: /* ! 55: ================= ! 56: = ! 57: = R_InstallSpriteLump ! 58: = ! 59: = Local function for R_InitSprites ! 60: ================= ! 61: */ ! 62: ! 63: void R_InstallSpriteLump (int lump, unsigned frame, unsigned rotation, boolean flipped) ! 64: { ! 65: int r; ! 66: ! 67: if (frame >= 26 || rotation > 8) ! 68: I_Error ("R_InstallSpriteLump: Bad frame characters in lump %i", lump); ! 69: ! 70: if ((int)frame > maxframe) ! 71: maxframe = frame; ! 72: ! 73: if (rotation == 0) ! 74: { ! 75: // the lump should be used for all rotations ! 76: if (sprtemp[frame].rotate == false) ! 77: I_Error ("R_InitSprites: Sprite %s frame %c has multip rot=0 lump" ! 78: , spritename, 'A'+frame); ! 79: if (sprtemp[frame].rotate == true) ! 80: I_Error ("R_InitSprites: Sprite %s frame %c has rotations and a rot=0 lump" ! 81: , spritename, 'A'+frame); ! 82: ! 83: sprtemp[frame].rotate = false; ! 84: for (r=0 ; r<8 ; r++) ! 85: { ! 86: sprtemp[frame].lump[r] = lump - firstspritelump; ! 87: sprtemp[frame].flip[r] = (byte)flipped; ! 88: } ! 89: return; ! 90: } ! 91: ! 92: // the lump is only used for one rotation ! 93: if (sprtemp[frame].rotate == false) ! 94: I_Error ("R_InitSprites: Sprite %s frame %c has rotations and a rot=0 lump" ! 95: , spritename, 'A'+frame); ! 96: ! 97: sprtemp[frame].rotate = true; ! 98: ! 99: rotation--; // make 0 based ! 100: if (sprtemp[frame].lump[rotation] != -1) ! 101: I_Error ("R_InitSprites: Sprite %s : %c : %c has two lumps mapped to it" ! 102: ,spritename, 'A'+frame, '1'+rotation); ! 103: ! 104: sprtemp[frame].lump[rotation] = lump - firstspritelump; ! 105: sprtemp[frame].flip[rotation] = (byte)flipped; ! 106: } ! 107: ! 108: /* ! 109: ================= ! 110: = ! 111: = R_InitSpriteDefs ! 112: = ! 113: = Pass a null terminated list of sprite names (4 chars exactly) to be used ! 114: = Builds the sprite rotation matrixes to account for horizontally flipped ! 115: = sprites. Will report an error if the lumps are inconsistant ! 116: = ! 117: Only called at startup ! 118: = ! 119: = Sprite lump names are 4 characters for the actor, a letter for the frame, ! 120: = and a number for the rotation, A sprite that is flippable will have an ! 121: = additional letter/number appended. The rotation character can be 0 to ! 122: = signify no rotations ! 123: ================= ! 124: */ ! 125: ! 126: void R_InitSpriteDefs (char **namelist) ! 127: { ! 128: char **check; ! 129: int i, l, intname, frame, rotation; ! 130: int start, end; ! 131: ! 132: // count the number of sprite names ! 133: check = namelist; ! 134: while (*check != NULL) ! 135: check++; ! 136: numsprites = check-namelist; ! 137: ! 138: if (!numsprites) ! 139: return; ! 140: ! 141: sprites = Z_Malloc(numsprites *sizeof(*sprites), PU_STATIC, NULL); ! 142: ! 143: start = firstspritelump-1; ! 144: end = lastspritelump+1; ! 145: ! 146: // scan all the lump names for each of the names, noting the highest ! 147: // frame letter ! 148: // Just compare 4 characters as ints ! 149: for (i=0 ; i<numsprites ; i++) ! 150: { ! 151: spritename = namelist[i]; ! 152: memset (sprtemp,-1, sizeof(sprtemp)); ! 153: ! 154: maxframe = -1; ! 155: intname = *(int *)namelist[i]; ! 156: ! 157: // ! 158: // scan the lumps, filling in the frames for whatever is found ! 159: // ! 160: for (l=start+1 ; l<end ; l++) ! 161: if (*(int *)lumpinfo[l].name == intname) ! 162: { ! 163: frame = lumpinfo[l].name[4] - 'A'; ! 164: rotation = lumpinfo[l].name[5] - '0'; ! 165: R_InstallSpriteLump (l, frame, rotation, false); ! 166: if (lumpinfo[l].name[6]) ! 167: { ! 168: frame = lumpinfo[l].name[6] - 'A'; ! 169: rotation = lumpinfo[l].name[7] - '0'; ! 170: R_InstallSpriteLump (l, frame, rotation, true); ! 171: } ! 172: } ! 173: ! 174: // ! 175: // check the frames that were found for completeness ! 176: // ! 177: if (maxframe == -1) ! 178: { ! 179: //continue; ! 180: sprites[i].numframes = 0; ! 181: if (shareware) ! 182: continue; ! 183: I_Error ("R_InitSprites: No lumps found for sprite %s" ! 184: ,namelist[i]); ! 185: } ! 186: ! 187: maxframe++; ! 188: for (frame = 0 ; frame < maxframe ; frame++) ! 189: { ! 190: switch ((int)sprtemp[frame].rotate) ! 191: { ! 192: case -1: // no rotations were found for that frame at all ! 193: I_Error ("R_InitSprites: No patches found for %s frame %c" ! 194: , namelist[i], frame+'A'); ! 195: case 0: // only the first rotation is needed ! 196: break; ! 197: ! 198: case 1: // must have all 8 frames ! 199: for (rotation=0 ; rotation<8 ; rotation++) ! 200: if (sprtemp[frame].lump[rotation] == -1) ! 201: I_Error ("R_InitSprites: Sprite %s frame %c is missing rotations" ! 202: , namelist[i], frame+'A'); ! 203: } ! 204: } ! 205: ! 206: // ! 207: // allocate space for the frames present and copy sprtemp to it ! 208: // ! 209: sprites[i].numframes = maxframe; ! 210: sprites[i].spriteframes = ! 211: Z_Malloc (maxframe * sizeof(spriteframe_t), PU_STATIC, NULL); ! 212: memcpy (sprites[i].spriteframes, sprtemp, maxframe*sizeof(spriteframe_t)); ! 213: } ! 214: ! 215: } ! 216: ! 217: ! 218: /* ! 219: =============================================================================== ! 220: ! 221: GAME FUNCTIONS ! 222: ! 223: =============================================================================== ! 224: */ ! 225: ! 226: vissprite_t vissprites[MAXVISSPRITES], *vissprite_p; ! 227: int newvissprite; ! 228: ! 229: ! 230: /* ! 231: =================== ! 232: = ! 233: = R_InitSprites ! 234: = ! 235: = Called at program start ! 236: =================== ! 237: */ ! 238: ! 239: void R_InitSprites (char **namelist) ! 240: { ! 241: int i; ! 242: ! 243: for (i=0 ; i<SCREENWIDTH ; i++) ! 244: { ! 245: negonearray[i] = -1; ! 246: } ! 247: ! 248: R_InitSpriteDefs (namelist); ! 249: } ! 250: ! 251: ! 252: /* ! 253: =================== ! 254: = ! 255: = R_ClearSprites ! 256: = ! 257: = Called at frame start ! 258: =================== ! 259: */ ! 260: ! 261: void R_ClearSprites (void) ! 262: { ! 263: vissprite_p = vissprites; ! 264: } ! 265: ! 266: ! 267: /* ! 268: =================== ! 269: = ! 270: = R_NewVisSprite ! 271: = ! 272: =================== ! 273: */ ! 274: ! 275: vissprite_t overflowsprite; ! 276: ! 277: vissprite_t *R_NewVisSprite (void) ! 278: { ! 279: if (vissprite_p == &vissprites[MAXVISSPRITES]) ! 280: return &overflowsprite; ! 281: vissprite_p++; ! 282: return vissprite_p-1; ! 283: } ! 284: ! 285: ! 286: /* ! 287: ================ ! 288: = ! 289: = R_DrawMaskedColumn ! 290: = ! 291: = Used for sprites and masked mid textures ! 292: ================ ! 293: */ ! 294: ! 295: short *mfloorclip; ! 296: short *mceilingclip; ! 297: fixed_t spryscale; ! 298: fixed_t sprtopscreen; ! 299: fixed_t sprbotscreen; ! 300: ! 301: void R_DrawMaskedColumn (column_t *column, signed int baseclip) ! 302: { ! 303: int topscreen, bottomscreen; ! 304: fixed_t basetexturemid; ! 305: ! 306: basetexturemid = dc_texturemid; ! 307: ! 308: for ( ; column->topdelta != 0xff ; ) ! 309: { ! 310: // calculate unclipped screen coordinates for post ! 311: topscreen = sprtopscreen + spryscale*column->topdelta; ! 312: bottomscreen = topscreen + spryscale*column->length; ! 313: dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; ! 314: dc_yh = (bottomscreen-1)>>FRACBITS; ! 315: ! 316: if (dc_yh >= mfloorclip[dc_x]) ! 317: dc_yh = mfloorclip[dc_x]-1; ! 318: if (dc_yl <= mceilingclip[dc_x]) ! 319: dc_yl = mceilingclip[dc_x]+1; ! 320: ! 321: if(dc_yh >= baseclip && baseclip != -1) ! 322: dc_yh = baseclip; ! 323: ! 324: if (dc_yl <= dc_yh) ! 325: { ! 326: dc_source = (byte *)column + 3; ! 327: dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS); ! 328: // dc_source = (byte *)column + 3 - column->topdelta; ! 329: colfunc (); // either R_DrawColumn or R_DrawFuzzColumn ! 330: } ! 331: column = (column_t *)( (byte *)column + column->length + 4); ! 332: } ! 333: ! 334: dc_texturemid = basetexturemid; ! 335: } ! 336: ! 337: ! 338: /* ! 339: ================ ! 340: = ! 341: = R_DrawVisSprite ! 342: = ! 343: = mfloorclip and mceilingclip should also be set ! 344: ================ ! 345: */ ! 346: ! 347: void R_DrawVisSprite (vissprite_t *vis, int x1, int x2) ! 348: { ! 349: column_t *column; ! 350: int texturecolumn; ! 351: fixed_t frac; ! 352: patch_t *patch; ! 353: fixed_t baseclip; ! 354: ! 355: ! 356: patch = W_CacheLumpNum(vis->patch+firstspritelump, PU_CACHE); ! 357: ! 358: dc_colormap = vis->colormap; ! 359: ! 360: // if(!dc_colormap) ! 361: // colfunc = fuzzcolfunc; // NULL colormap = shadow draw ! 362: ! 363: if(vis->mobjflags&MF_SHADOW) ! 364: { ! 365: if(vis->mobjflags&MF_TRANSLATION) ! 366: { ! 367: colfunc = R_DrawTranslatedFuzzColumn; ! 368: dc_translation = translationtables - 256 + ! 369: ((vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8)); ! 370: } ! 371: else ! 372: { // Draw using shadow column function ! 373: colfunc = fuzzcolfunc; ! 374: } ! 375: } ! 376: else if(vis->mobjflags&MF_TRANSLATION) ! 377: { ! 378: // Draw using translated column function ! 379: colfunc = R_DrawTranslatedColumn; ! 380: dc_translation = translationtables - 256 + ! 381: ( (vis->mobjflags & MF_TRANSLATION) >> (MF_TRANSSHIFT-8) ); ! 382: } ! 383: ! 384: dc_iscale = abs(vis->xiscale)>>detailshift; ! 385: dc_texturemid = vis->texturemid; ! 386: frac = vis->startfrac; ! 387: spryscale = vis->scale; ! 388: ! 389: sprtopscreen = centeryfrac - FixedMul(dc_texturemid,spryscale); ! 390: ! 391: // check to see if weapon is a vissprite ! 392: if(vis->psprite) ! 393: { ! 394: dc_texturemid += FixedMul(((centery-viewheight/2)<<FRACBITS), ! 395: vis->xiscale); ! 396: sprtopscreen += (viewheight/2-centery)<<FRACBITS; ! 397: } ! 398: ! 399: if(vis->footclip && !vis->psprite) ! 400: { ! 401: sprbotscreen = sprtopscreen+FixedMul(patch->height<<FRACBITS, ! 402: spryscale); ! 403: baseclip = (sprbotscreen-FixedMul(vis->footclip<<FRACBITS, ! 404: spryscale))>>FRACBITS; ! 405: } ! 406: else ! 407: { ! 408: baseclip = -1; ! 409: } ! 410: ! 411: for (dc_x=vis->x1 ; dc_x<=vis->x2 ; dc_x++, frac += vis->xiscale) ! 412: { ! 413: texturecolumn = frac>>FRACBITS; ! 414: #ifdef RANGECHECK ! 415: if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) ! 416: I_Error ("R_DrawSpriteRange: bad texturecolumn"); ! 417: #endif ! 418: column = (column_t *) ((byte *)patch + ! 419: LONG(patch->columnofs[texturecolumn])); ! 420: R_DrawMaskedColumn (column, baseclip); ! 421: } ! 422: ! 423: colfunc = basecolfunc; ! 424: } ! 425: ! 426: ! 427: ! 428: /* ! 429: =================== ! 430: = ! 431: = R_ProjectSprite ! 432: = ! 433: = Generates a vissprite for a thing if it might be visible ! 434: = ! 435: =================== ! 436: */ ! 437: ! 438: void R_ProjectSprite (mobj_t *thing) ! 439: { ! 440: fixed_t trx,try; ! 441: fixed_t gxt,gyt; ! 442: fixed_t tx,tz; ! 443: fixed_t xscale; ! 444: int x1, x2; ! 445: spritedef_t *sprdef; ! 446: spriteframe_t *sprframe; ! 447: int lump; ! 448: unsigned rot; ! 449: boolean flip; ! 450: int index; ! 451: vissprite_t *vis; ! 452: angle_t ang; ! 453: fixed_t iscale; ! 454: ! 455: if(thing->flags2&MF2_DONTDRAW) ! 456: { // Never make a vissprite when MF2_DONTDRAW is flagged. ! 457: return; ! 458: } ! 459: ! 460: // ! 461: // transform the origin point ! 462: // ! 463: trx = thing->x - viewx; ! 464: try = thing->y - viewy; ! 465: ! 466: gxt = FixedMul(trx,viewcos); ! 467: gyt = -FixedMul(try,viewsin); ! 468: tz = gxt-gyt; ! 469: ! 470: if (tz < MINZ) ! 471: return; // thing is behind view plane ! 472: xscale = FixedDiv(projection, tz); ! 473: ! 474: gxt = -FixedMul(trx,viewsin); ! 475: gyt = FixedMul(try,viewcos); ! 476: tx = -(gyt+gxt); ! 477: ! 478: if (abs(tx)>(tz<<2)) ! 479: return; // too far off the side ! 480: ! 481: // ! 482: // decide which patch to use for sprite reletive to player ! 483: // ! 484: #ifdef RANGECHECK ! 485: if ((unsigned)thing->sprite >= numsprites) ! 486: I_Error ("R_ProjectSprite: invalid sprite number %i ",thing->sprite); ! 487: #endif ! 488: sprdef = &sprites[thing->sprite]; ! 489: #ifdef RANGECHECK ! 490: if ( (thing->frame&FF_FRAMEMASK) >= sprdef->numframes ) ! 491: I_Error ("R_ProjectSprite: invalid sprite frame %i : %i " ! 492: ,thing->sprite, thing->frame); ! 493: #endif ! 494: sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK]; ! 495: ! 496: if (sprframe->rotate) ! 497: { // choose a different rotation based on player view ! 498: ang = R_PointToAngle (thing->x, thing->y); ! 499: rot = (ang-thing->angle+(unsigned)(ANG45/2)*9)>>29; ! 500: lump = sprframe->lump[rot]; ! 501: flip = (boolean)sprframe->flip[rot]; ! 502: } ! 503: else ! 504: { // use single rotation for all views ! 505: lump = sprframe->lump[0]; ! 506: flip = (boolean)sprframe->flip[0]; ! 507: } ! 508: ! 509: // ! 510: // calculate edges of the shape ! 511: // ! 512: tx -= spriteoffset[lump]; ! 513: x1 = (centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS; ! 514: if (x1 > viewwidth) ! 515: return; // off the right side ! 516: tx += spritewidth[lump]; ! 517: x2 = ((centerxfrac + FixedMul (tx,xscale) ) >>FRACBITS) - 1; ! 518: if (x2 < 0) ! 519: return; // off the left side ! 520: ! 521: ! 522: // ! 523: // store information in a vissprite ! 524: // ! 525: vis = R_NewVisSprite (); ! 526: vis->mobjflags = thing->flags; ! 527: vis->psprite = false; ! 528: vis->scale = xscale<<detailshift; ! 529: vis->gx = thing->x; ! 530: vis->gy = thing->y; ! 531: vis->gz = thing->z; ! 532: vis->gzt = thing->z + spritetopoffset[lump]; ! 533: ! 534: // foot clipping ! 535: if(thing->flags2&MF2_FEETARECLIPPED ! 536: && thing->z <= thing->subsector->sector->floorheight) ! 537: { ! 538: vis->footclip = 10; ! 539: } ! 540: else vis->footclip = 0; ! 541: vis->texturemid = vis->gzt - viewz - (vis->footclip<<FRACBITS); ! 542: ! 543: vis->x1 = x1 < 0 ? 0 : x1; ! 544: vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; ! 545: iscale = FixedDiv (FRACUNIT, xscale); ! 546: if (flip) ! 547: { ! 548: vis->startfrac = spritewidth[lump]-1; ! 549: vis->xiscale = -iscale; ! 550: } ! 551: else ! 552: { ! 553: vis->startfrac = 0; ! 554: vis->xiscale = iscale; ! 555: } ! 556: if (vis->x1 > x1) ! 557: vis->startfrac += vis->xiscale*(vis->x1-x1); ! 558: vis->patch = lump; ! 559: // ! 560: // get light level ! 561: // ! 562: ! 563: // if (thing->flags & MF_SHADOW) ! 564: // vis->colormap = NULL; // shadow draw ! 565: // else ... ! 566: ! 567: if (fixedcolormap) ! 568: vis->colormap = fixedcolormap; // fixed map ! 569: else if (thing->frame & FF_FULLBRIGHT) ! 570: vis->colormap = colormaps; // full bright ! 571: else ! 572: { // diminished light ! 573: index = xscale>>(LIGHTSCALESHIFT-detailshift); ! 574: if (index >= MAXLIGHTSCALE) ! 575: index = MAXLIGHTSCALE-1; ! 576: vis->colormap = spritelights[index]; ! 577: } ! 578: } ! 579: ! 580: ! 581: ! 582: ! 583: /* ! 584: ======================== ! 585: = ! 586: = R_AddSprites ! 587: = ! 588: ======================== ! 589: */ ! 590: ! 591: void R_AddSprites (sector_t *sec) ! 592: { ! 593: mobj_t *thing; ! 594: int lightnum; ! 595: ! 596: if (sec->validcount == validcount) ! 597: return; // already added ! 598: ! 599: sec->validcount = validcount; ! 600: ! 601: lightnum = (sec->lightlevel >> LIGHTSEGSHIFT)+extralight; ! 602: if (lightnum < 0) ! 603: spritelights = scalelight[0]; ! 604: else if (lightnum >= LIGHTLEVELS) ! 605: spritelights = scalelight[LIGHTLEVELS-1]; ! 606: else ! 607: spritelights = scalelight[lightnum]; ! 608: ! 609: ! 610: for (thing = sec->thinglist ; thing ; thing = thing->snext) ! 611: R_ProjectSprite (thing); ! 612: } ! 613: ! 614: ! 615: /* ! 616: ======================== ! 617: = ! 618: = R_DrawPSprite ! 619: = ! 620: ======================== ! 621: */ ! 622: ! 623: int PSpriteSY[NUMWEAPONS] = ! 624: { ! 625: 0, // staff ! 626: 5*FRACUNIT, // goldwand ! 627: 15*FRACUNIT, // crossbow ! 628: 15*FRACUNIT, // blaster ! 629: 15*FRACUNIT, // skullrod ! 630: 15*FRACUNIT, // phoenix rod ! 631: 15*FRACUNIT, // mace ! 632: 15*FRACUNIT, // gauntlets ! 633: 15*FRACUNIT // beak ! 634: }; ! 635: ! 636: void R_DrawPSprite (pspdef_t *psp) ! 637: { ! 638: fixed_t tx; ! 639: int x1, x2; ! 640: spritedef_t *sprdef; ! 641: spriteframe_t *sprframe; ! 642: int lump; ! 643: boolean flip; ! 644: vissprite_t *vis, avis; ! 645: ! 646: int tempangle; ! 647: ! 648: // ! 649: // decide which patch to use ! 650: // ! 651: #ifdef RANGECHECK ! 652: if ( (unsigned)psp->state->sprite >= numsprites) ! 653: I_Error ("R_ProjectSprite: invalid sprite number %i " ! 654: , psp->state->sprite); ! 655: #endif ! 656: sprdef = &sprites[psp->state->sprite]; ! 657: #ifdef RANGECHECK ! 658: if ( (psp->state->frame & FF_FRAMEMASK) >= sprdef->numframes) ! 659: I_Error ("R_ProjectSprite: invalid sprite frame %i : %i " ! 660: , psp->state->sprite, psp->state->frame); ! 661: #endif ! 662: sprframe = &sprdef->spriteframes[ psp->state->frame & FF_FRAMEMASK ]; ! 663: ! 664: lump = sprframe->lump[0]; ! 665: flip = (boolean)sprframe->flip[0]; ! 666: ! 667: // ! 668: // calculate edges of the shape ! 669: // ! 670: tx = psp->sx-160*FRACUNIT; ! 671: ! 672: tx -= spriteoffset[lump]; ! 673: if(viewangleoffset) ! 674: { ! 675: tempangle = ((centerxfrac/1024)*(viewangleoffset>>ANGLETOFINESHIFT)); ! 676: } ! 677: else ! 678: { ! 679: tempangle = 0; ! 680: } ! 681: x1 = (centerxfrac + FixedMul (tx,pspritescale)+tempangle ) >>FRACBITS; ! 682: if (x1 > viewwidth) ! 683: return; // off the right side ! 684: tx += spritewidth[lump]; ! 685: x2 = ((centerxfrac + FixedMul (tx, pspritescale)+tempangle ) >>FRACBITS) - 1; ! 686: if (x2 < 0) ! 687: return; // off the left side ! 688: ! 689: // ! 690: // store information in a vissprite ! 691: // ! 692: vis = &avis; ! 693: vis->mobjflags = 0; ! 694: vis->psprite = true; ! 695: vis->texturemid = (BASEYCENTER<<FRACBITS)+FRACUNIT/2-(psp->sy-spritetopoffset[lump]); ! 696: if(viewheight == SCREENHEIGHT) ! 697: { ! 698: vis->texturemid -= PSpriteSY[players[consoleplayer].readyweapon]; ! 699: } ! 700: vis->x1 = x1 < 0 ? 0 : x1; ! 701: vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; ! 702: vis->scale = pspritescale<<detailshift; ! 703: if (flip) ! 704: { ! 705: vis->xiscale = -pspriteiscale; ! 706: vis->startfrac = spritewidth[lump]-1; ! 707: } ! 708: else ! 709: { ! 710: vis->xiscale = pspriteiscale; ! 711: vis->startfrac = 0; ! 712: } ! 713: if (vis->x1 > x1) ! 714: vis->startfrac += vis->xiscale*(vis->x1-x1); ! 715: vis->patch = lump; ! 716: ! 717: if(viewplayer->powers[pw_invisibility] > 4*32 || ! 718: viewplayer->powers[pw_invisibility] & 8) ! 719: { ! 720: // Invisibility ! 721: vis->colormap = spritelights[MAXLIGHTSCALE-1]; ! 722: vis->mobjflags |= MF_SHADOW; ! 723: } ! 724: else if(fixedcolormap) ! 725: { ! 726: // Fixed color ! 727: vis->colormap = fixedcolormap; ! 728: } ! 729: else if(psp->state->frame & FF_FULLBRIGHT) ! 730: { ! 731: // Full bright ! 732: vis->colormap = colormaps; ! 733: } ! 734: else ! 735: { ! 736: // local light ! 737: vis->colormap = spritelights[MAXLIGHTSCALE-1]; ! 738: } ! 739: R_DrawVisSprite(vis, vis->x1, vis->x2); ! 740: } ! 741: ! 742: /* ! 743: ======================== ! 744: = ! 745: = R_DrawPlayerSprites ! 746: = ! 747: ======================== ! 748: */ ! 749: ! 750: void R_DrawPlayerSprites (void) ! 751: { ! 752: int i, lightnum; ! 753: pspdef_t *psp; ! 754: ! 755: // ! 756: // get light level ! 757: // ! 758: lightnum = (viewplayer->mo->subsector->sector->lightlevel >> LIGHTSEGSHIFT) ! 759: +extralight; ! 760: if (lightnum < 0) ! 761: spritelights = scalelight[0]; ! 762: else if (lightnum >= LIGHTLEVELS) ! 763: spritelights = scalelight[LIGHTLEVELS-1]; ! 764: else ! 765: spritelights = scalelight[lightnum]; ! 766: // ! 767: // clip to screen bounds ! 768: // ! 769: mfloorclip = screenheightarray; ! 770: mceilingclip = negonearray; ! 771: ! 772: // ! 773: // add all active psprites ! 774: // ! 775: for (i=0, psp=viewplayer->psprites ; i<NUMPSPRITES ; i++,psp++) ! 776: if (psp->state) ! 777: R_DrawPSprite (psp); ! 778: ! 779: } ! 780: ! 781: ! 782: /* ! 783: ======================== ! 784: = ! 785: = R_SortVisSprites ! 786: = ! 787: ======================== ! 788: */ ! 789: ! 790: vissprite_t vsprsortedhead; ! 791: ! 792: void R_SortVisSprites (void) ! 793: { ! 794: int i, count; ! 795: vissprite_t *ds, *best; ! 796: vissprite_t unsorted; ! 797: fixed_t bestscale; ! 798: ! 799: count = vissprite_p - vissprites; ! 800: ! 801: unsorted.next = unsorted.prev = &unsorted; ! 802: if (!count) ! 803: return; ! 804: ! 805: for (ds=vissprites ; ds<vissprite_p ; ds++) ! 806: { ! 807: ds->next = ds+1; ! 808: ds->prev = ds-1; ! 809: } ! 810: vissprites[0].prev = &unsorted; ! 811: unsorted.next = &vissprites[0]; ! 812: (vissprite_p-1)->next = &unsorted; ! 813: unsorted.prev = vissprite_p-1; ! 814: ! 815: // ! 816: // pull the vissprites out by scale ! 817: // ! 818: best = 0; // shut up the compiler warning ! 819: vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; ! 820: for (i=0 ; i<count ; i++) ! 821: { ! 822: bestscale = MAXINT; ! 823: for (ds=unsorted.next ; ds!= &unsorted ; ds=ds->next) ! 824: { ! 825: if (ds->scale < bestscale) ! 826: { ! 827: bestscale = ds->scale; ! 828: best = ds; ! 829: } ! 830: } ! 831: best->next->prev = best->prev; ! 832: best->prev->next = best->next; ! 833: best->next = &vsprsortedhead; ! 834: best->prev = vsprsortedhead.prev; ! 835: vsprsortedhead.prev->next = best; ! 836: vsprsortedhead.prev = best; ! 837: } ! 838: } ! 839: ! 840: ! 841: ! 842: /* ! 843: ======================== ! 844: = ! 845: = R_DrawSprite ! 846: = ! 847: ======================== ! 848: */ ! 849: ! 850: void R_DrawSprite (vissprite_t *spr) ! 851: { ! 852: drawseg_t *ds; ! 853: short clipbot[SCREENWIDTH], cliptop[SCREENWIDTH]; ! 854: int x, r1, r2; ! 855: fixed_t scale, lowscale; ! 856: int silhouette; ! 857: ! 858: for (x = spr->x1 ; x<=spr->x2 ; x++) ! 859: clipbot[x] = cliptop[x] = -2; ! 860: ! 861: // ! 862: // scan drawsegs from end to start for obscuring segs ! 863: // the first drawseg that has a greater scale is the clip seg ! 864: // ! 865: for (ds=ds_p-1 ; ds >= drawsegs ; ds--) ! 866: { ! 867: // ! 868: // determine if the drawseg obscures the sprite ! 869: // ! 870: if (ds->x1 > spr->x2 || ds->x2 < spr->x1 || ! 871: (!ds->silhouette && !ds->maskedtexturecol) ) ! 872: continue; // doesn't cover sprite ! 873: ! 874: r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; ! 875: r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; ! 876: if (ds->scale1 > ds->scale2) ! 877: { ! 878: lowscale = ds->scale2; ! 879: scale = ds->scale1; ! 880: } ! 881: else ! 882: { ! 883: lowscale = ds->scale1; ! 884: scale = ds->scale2; ! 885: } ! 886: ! 887: if (scale < spr->scale || ( lowscale < spr->scale ! 888: && !R_PointOnSegSide (spr->gx, spr->gy, ds->curline) ) ) ! 889: { ! 890: if (ds->maskedtexturecol) // masked mid texture ! 891: R_RenderMaskedSegRange (ds, r1, r2); ! 892: continue; // seg is behind sprite ! 893: } ! 894: ! 895: // ! 896: // clip this piece of the sprite ! 897: // ! 898: silhouette = ds->silhouette; ! 899: if (spr->gz >= ds->bsilheight) ! 900: silhouette &= ~SIL_BOTTOM; ! 901: if (spr->gzt <= ds->tsilheight) ! 902: silhouette &= ~SIL_TOP; ! 903: ! 904: if (silhouette == 1) ! 905: { // bottom sil ! 906: for (x=r1 ; x<=r2 ; x++) ! 907: if (clipbot[x] == -2) ! 908: clipbot[x] = ds->sprbottomclip[x]; ! 909: } ! 910: else if (silhouette == 2) ! 911: { // top sil ! 912: for (x=r1 ; x<=r2 ; x++) ! 913: if (cliptop[x] == -2) ! 914: cliptop[x] = ds->sprtopclip[x]; ! 915: } ! 916: else if (silhouette == 3) ! 917: { // both ! 918: for (x=r1 ; x<=r2 ; x++) ! 919: { ! 920: if (clipbot[x] == -2) ! 921: clipbot[x] = ds->sprbottomclip[x]; ! 922: if (cliptop[x] == -2) ! 923: cliptop[x] = ds->sprtopclip[x]; ! 924: } ! 925: } ! 926: ! 927: } ! 928: ! 929: // ! 930: // all clipping has been performed, so draw the sprite ! 931: // ! 932: ! 933: // check for unclipped columns ! 934: for (x = spr->x1 ; x<=spr->x2 ; x++) ! 935: { ! 936: if (clipbot[x] == -2) ! 937: clipbot[x] = viewheight; ! 938: if (cliptop[x] == -2) ! 939: cliptop[x] = -1; ! 940: } ! 941: ! 942: mfloorclip = clipbot; ! 943: mceilingclip = cliptop; ! 944: R_DrawVisSprite (spr, spr->x1, spr->x2); ! 945: } ! 946: ! 947: ! 948: /* ! 949: ======================== ! 950: = ! 951: = R_DrawMasked ! 952: = ! 953: ======================== ! 954: */ ! 955: ! 956: void R_DrawMasked (void) ! 957: { ! 958: vissprite_t *spr; ! 959: drawseg_t *ds; ! 960: ! 961: R_SortVisSprites (); ! 962: ! 963: if (vissprite_p > vissprites) ! 964: { ! 965: // draw all vissprites back to front ! 966: ! 967: for (spr = vsprsortedhead.next ; spr != &vsprsortedhead ! 968: ; spr=spr->next) ! 969: R_DrawSprite (spr); ! 970: } ! 971: ! 972: // ! 973: // render any remaining masked mid textures ! 974: // ! 975: for (ds=ds_p-1 ; ds >= drawsegs ; ds--) ! 976: if (ds->maskedtexturecol) ! 977: R_RenderMaskedSegRange (ds, ds->x1, ds->x2); ! 978: ! 979: // ! 980: // draw the psprites on top of everything ! 981: // ! 982: // Added for the sideviewing with an external device ! 983: if (viewangleoffset <= 1024<<ANGLETOFINESHIFT || viewangleoffset >= ! 984: -1024<<ANGLETOFINESHIFT) ! 985: { // don't draw on side views ! 986: R_DrawPlayerSprites (); ! 987: } ! 988: ! 989: // if (!viewangleoffset) // don't draw on side views ! 990: // R_DrawPlayerSprites (); ! 991: } ! 992: ! 993:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.