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