|
|
1.1 ! root 1: // R_planes.c ! 2: ! 3: #include "DoomDef.h" ! 4: #include "R_local.h" ! 5: ! 6: planefunction_t floorfunc, ceilingfunc; ! 7: ! 8: // ! 9: // sky mapping ! 10: // ! 11: int skyflatnum; ! 12: int skytexture; ! 13: int skytexturemid; ! 14: fixed_t skyiscale; ! 15: ! 16: // ! 17: // opening ! 18: // ! 19: ! 20: visplane_t visplanes[MAXVISPLANES], *lastvisplane; ! 21: visplane_t *floorplane, *ceilingplane; ! 22: ! 23: short openings[MAXOPENINGS], *lastopening; ! 24: ! 25: // ! 26: // clip values are the solid pixel bounding the range ! 27: // floorclip starts out SCREENHEIGHT ! 28: // ceilingclip starts out -1 ! 29: // ! 30: short floorclip[SCREENWIDTH]; ! 31: short ceilingclip[SCREENWIDTH]; ! 32: ! 33: // ! 34: // spanstart holds the start of a plane span ! 35: // initialized to 0 at start ! 36: // ! 37: int spanstart[SCREENHEIGHT]; ! 38: int spanstop[SCREENHEIGHT]; ! 39: ! 40: // ! 41: // texture mapping ! 42: // ! 43: lighttable_t **planezlight; ! 44: fixed_t planeheight; ! 45: ! 46: fixed_t yslope[SCREENHEIGHT]; ! 47: fixed_t distscale[SCREENWIDTH]; ! 48: fixed_t basexscale, baseyscale; ! 49: ! 50: fixed_t cachedheight[SCREENHEIGHT]; ! 51: fixed_t cacheddistance[SCREENHEIGHT]; ! 52: fixed_t cachedxstep[SCREENHEIGHT]; ! 53: fixed_t cachedystep[SCREENHEIGHT]; ! 54: ! 55: ! 56: /* ! 57: ================ ! 58: = ! 59: = R_InitSkyMap ! 60: = ! 61: = Called whenever the view size changes ! 62: = ! 63: ================ ! 64: */ ! 65: ! 66: void R_InitSkyMap (void) ! 67: { ! 68: skyflatnum = R_FlatNumForName ("F_SKY1"); ! 69: skytexturemid = 200*FRACUNIT; ! 70: skyiscale = FRACUNIT; ! 71: } ! 72: ! 73: ! 74: /* ! 75: ==================== ! 76: = ! 77: = R_InitPlanes ! 78: = ! 79: = Only at game startup ! 80: ==================== ! 81: */ ! 82: ! 83: void R_InitPlanes (void) ! 84: { ! 85: } ! 86: ! 87: ! 88: /* ! 89: ================ ! 90: = ! 91: = R_MapPlane ! 92: = ! 93: global vars: ! 94: ! 95: planeheight ! 96: ds_source ! 97: basexscale ! 98: baseyscale ! 99: viewx ! 100: viewy ! 101: ! 102: BASIC PRIMITIVE ! 103: ================ ! 104: */ ! 105: ! 106: void R_MapPlane (int y, int x1, int x2) ! 107: { ! 108: angle_t angle; ! 109: fixed_t distance, length; ! 110: unsigned index; ! 111: ! 112: #ifdef RANGECHECK ! 113: if (x2 < x1 || x1<0 || x2>=viewwidth || (unsigned)y>viewheight) ! 114: I_Error ("R_MapPlane: %i, %i at %i",x1,x2,y); ! 115: #endif ! 116: ! 117: if (planeheight != cachedheight[y]) ! 118: { ! 119: cachedheight[y] = planeheight; ! 120: distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]); ! 121: ! 122: ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale); ! 123: ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale); ! 124: } ! 125: else ! 126: { ! 127: distance = cacheddistance[y]; ! 128: ds_xstep = cachedxstep[y]; ! 129: ds_ystep = cachedystep[y]; ! 130: } ! 131: ! 132: length = FixedMul (distance,distscale[x1]); ! 133: angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT; ! 134: ds_xfrac = viewx + FixedMul(finecosine[angle], length); ! 135: ds_yfrac = -viewy - FixedMul(finesine[angle], length); ! 136: ! 137: if (fixedcolormap) ! 138: ds_colormap = fixedcolormap; ! 139: else ! 140: { ! 141: index = distance >> LIGHTZSHIFT; ! 142: if (index >= MAXLIGHTZ ) ! 143: index = MAXLIGHTZ-1; ! 144: ds_colormap = planezlight[index]; ! 145: } ! 146: ! 147: ds_y = y; ! 148: ds_x1 = x1; ! 149: ds_x2 = x2; ! 150: ! 151: spanfunc (); // high or low detail ! 152: } ! 153: ! 154: //============================================================================= ! 155: ! 156: /* ! 157: ==================== ! 158: = ! 159: = R_ClearPlanes ! 160: = ! 161: = At begining of frame ! 162: ==================== ! 163: */ ! 164: ! 165: void R_ClearPlanes (void) ! 166: { ! 167: int i; ! 168: angle_t angle; ! 169: ! 170: // ! 171: // opening / clipping determination ! 172: // ! 173: for (i=0 ; i<viewwidth ; i++) ! 174: { ! 175: floorclip[i] = viewheight; ! 176: ceilingclip[i] = -1; ! 177: } ! 178: ! 179: lastvisplane = visplanes; ! 180: lastopening = openings; ! 181: ! 182: // ! 183: // texture calculation ! 184: // ! 185: memset (cachedheight, 0, sizeof(cachedheight)); ! 186: angle = (viewangle-ANG90)>>ANGLETOFINESHIFT; // left to right mapping ! 187: ! 188: // scale will be unit scale at SCREENWIDTH/2 distance ! 189: basexscale = FixedDiv (finecosine[angle],centerxfrac); ! 190: baseyscale = -FixedDiv (finesine[angle],centerxfrac); ! 191: } ! 192: ! 193: ! 194: ! 195: /* ! 196: =============== ! 197: = ! 198: = R_FindPlane ! 199: = ! 200: =============== ! 201: */ ! 202: ! 203: visplane_t *R_FindPlane(fixed_t height, int picnum, ! 204: int lightlevel, int special) ! 205: { ! 206: visplane_t *check; ! 207: ! 208: if(picnum == skyflatnum) ! 209: { ! 210: // all skies map together ! 211: height = 0; ! 212: lightlevel = 0; ! 213: } ! 214: ! 215: for(check = visplanes; check < lastvisplane; check++) ! 216: { ! 217: if(height == check->height ! 218: && picnum == check->picnum ! 219: && lightlevel == check->lightlevel ! 220: && special == check->special) ! 221: break; ! 222: } ! 223: ! 224: if(check < lastvisplane) ! 225: { ! 226: return(check); ! 227: } ! 228: ! 229: if(lastvisplane-visplanes == MAXVISPLANES) ! 230: { ! 231: I_Error("R_FindPlane: no more visplanes"); ! 232: } ! 233: ! 234: lastvisplane++; ! 235: check->height = height; ! 236: check->picnum = picnum; ! 237: check->lightlevel = lightlevel; ! 238: check->special = special; ! 239: check->minx = SCREENWIDTH; ! 240: check->maxx = -1; ! 241: memset(check->top,0xff,sizeof(check->top)); ! 242: return(check); ! 243: } ! 244: ! 245: /* ! 246: =============== ! 247: = ! 248: = R_CheckPlane ! 249: = ! 250: =============== ! 251: */ ! 252: ! 253: visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop) ! 254: { ! 255: int intrl, intrh; ! 256: int unionl, unionh; ! 257: int x; ! 258: ! 259: if (start < pl->minx) ! 260: { ! 261: intrl = pl->minx; ! 262: unionl = start; ! 263: } ! 264: else ! 265: { ! 266: unionl = pl->minx; ! 267: intrl = start; ! 268: } ! 269: ! 270: if (stop > pl->maxx) ! 271: { ! 272: intrh = pl->maxx; ! 273: unionh = stop; ! 274: } ! 275: else ! 276: { ! 277: unionh = pl->maxx; ! 278: intrh = stop; ! 279: } ! 280: ! 281: for (x=intrl ; x<= intrh ; x++) ! 282: if (pl->top[x] != 0xff) ! 283: break; ! 284: ! 285: if (x > intrh) ! 286: { ! 287: pl->minx = unionl; ! 288: pl->maxx = unionh; ! 289: return pl; // use the same one ! 290: } ! 291: ! 292: // make a new visplane ! 293: ! 294: lastvisplane->height = pl->height; ! 295: lastvisplane->picnum = pl->picnum; ! 296: lastvisplane->lightlevel = pl->lightlevel; ! 297: lastvisplane->special = pl->special; ! 298: pl = lastvisplane++; ! 299: pl->minx = start; ! 300: pl->maxx = stop; ! 301: memset (pl->top,0xff,sizeof(pl->top)); ! 302: ! 303: return pl; ! 304: } ! 305: ! 306: ! 307: ! 308: //============================================================================= ! 309: ! 310: /* ! 311: ================ ! 312: = ! 313: = R_MakeSpans ! 314: = ! 315: ================ ! 316: */ ! 317: ! 318: void R_MakeSpans (int x, int t1, int b1, int t2, int b2) ! 319: { ! 320: while (t1 < t2 && t1<=b1) ! 321: { ! 322: R_MapPlane (t1,spanstart[t1],x-1); ! 323: t1++; ! 324: } ! 325: while (b1 > b2 && b1>=t1) ! 326: { ! 327: R_MapPlane (b1,spanstart[b1],x-1); ! 328: b1--; ! 329: } ! 330: ! 331: while (t2 < t1 && t2<=b2) ! 332: { ! 333: spanstart[t2] = x; ! 334: t2++; ! 335: } ! 336: while (b2 > b1 && b2>=t2) ! 337: { ! 338: spanstart[b2] = x; ! 339: b2--; ! 340: } ! 341: } ! 342: ! 343: ! 344: ! 345: /* ! 346: ================ ! 347: = ! 348: = R_DrawPlanes ! 349: = ! 350: = At the end of each frame ! 351: ================ ! 352: */ ! 353: ! 354: void R_DrawPlanes (void) ! 355: { ! 356: visplane_t *pl; ! 357: int light; ! 358: int x, stop; ! 359: int angle; ! 360: byte *tempSource; ! 361: ! 362: byte *dest; ! 363: int count; ! 364: fixed_t frac, fracstep; ! 365: ! 366: extern byte *ylookup[MAXHEIGHT]; ! 367: extern int columnofs[MAXWIDTH]; ! 368: ! 369: #ifdef RANGECHECK ! 370: if (ds_p - drawsegs > MAXDRAWSEGS) ! 371: I_Error ("R_DrawPlanes: drawsegs overflow (%i)", ds_p - drawsegs); ! 372: if (lastvisplane - visplanes > MAXVISPLANES) ! 373: I_Error ("R_DrawPlanes: visplane overflow (%i)", lastvisplane - visplanes); ! 374: if (lastopening - openings > MAXOPENINGS) ! 375: I_Error ("R_DrawPlanes: opening overflow (%i)", lastopening - openings); ! 376: #endif ! 377: ! 378: for (pl = visplanes ; pl < lastvisplane ; pl++) ! 379: { ! 380: if (pl->minx > pl->maxx) ! 381: continue; ! 382: // ! 383: // sky flat ! 384: // ! 385: if (pl->picnum == skyflatnum) ! 386: { ! 387: dc_iscale = skyiscale; ! 388: dc_colormap = colormaps;// sky is allways drawn full bright ! 389: dc_texturemid = skytexturemid; ! 390: for (x=pl->minx ; x <= pl->maxx ; x++) ! 391: { ! 392: dc_yl = pl->top[x]; ! 393: dc_yh = pl->bottom[x]; ! 394: if (dc_yl <= dc_yh) ! 395: { ! 396: angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; ! 397: dc_x = x; ! 398: dc_source = R_GetColumn(skytexture, angle); ! 399: ! 400: count = dc_yh - dc_yl; ! 401: if (count < 0) ! 402: return; ! 403: ! 404: #ifdef RANGECHECK ! 405: if ((unsigned)dc_x >= SCREENWIDTH || dc_yl < 0 || dc_yh >= SCREENHEIGHT) ! 406: I_Error ("R_DrawColumn: %i to %i at %i", dc_yl, dc_yh, dc_x); ! 407: #endif ! 408: ! 409: dest = ylookup[dc_yl] + columnofs[dc_x]; ! 410: ! 411: fracstep = 1; ! 412: frac = (dc_texturemid>>FRACBITS) + (dc_yl-centery); ! 413: do ! 414: { ! 415: *dest = dc_source[frac]; ! 416: dest += SCREENWIDTH; ! 417: frac += fracstep; ! 418: } while (count--); ! 419: ! 420: // colfunc (); ! 421: } ! 422: } ! 423: continue; ! 424: } ! 425: ! 426: // ! 427: // regular flat ! 428: // ! 429: tempSource = W_CacheLumpNum(firstflat + ! 430: flattranslation[pl->picnum], PU_STATIC); ! 431: ! 432: switch(pl->special) ! 433: { ! 434: case 25: case 26: case 27: case 28: case 29: // Scroll_North ! 435: ds_source = tempSource; ! 436: break; ! 437: case 20: case 21: case 22: case 23: case 24: // Scroll_East ! 438: ds_source = tempSource+((63-((leveltime>>1)&63))<< ! 439: (pl->special-20)&63); ! 440: //ds_source = tempSource+((leveltime>>1)&63); ! 441: break; ! 442: case 30: case 31: case 32: case 33: case 34: // Scroll_South ! 443: ds_source = tempSource; ! 444: break; ! 445: case 35: case 36: case 37: case 38: case 39: // Scroll_West ! 446: ds_source = tempSource; ! 447: break; ! 448: case 4: // Scroll_EastLavaDamage ! 449: ds_source = tempSource+(((63-((leveltime>>1)&63))<<3)&63); ! 450: break; ! 451: default: ! 452: ds_source = tempSource; ! 453: } ! 454: planeheight = abs(pl->height-viewz); ! 455: light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight; ! 456: if (light >= LIGHTLEVELS) ! 457: light = LIGHTLEVELS-1; ! 458: if (light < 0) ! 459: light = 0; ! 460: planezlight = zlight[light]; ! 461: ! 462: pl->top[pl->maxx+1] = 0xff; ! 463: pl->top[pl->minx-1] = 0xff; ! 464: ! 465: stop = pl->maxx + 1; ! 466: for (x=pl->minx ; x<= stop ; x++) ! 467: R_MakeSpans (x,pl->top[x-1],pl->bottom[x-1] ! 468: ,pl->top[x],pl->bottom[x]); ! 469: ! 470: Z_ChangeTag (tempSource, PU_CACHE); ! 471: } ! 472: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.