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