|
|
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.