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