1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
6 // Copyright (C) 1993-1996 by id Software, Inc.
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.
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
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.
24 //-----------------------------------------------------------------------------
28 rcsid[] = "$Id: r_plane.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
42 planefunction_t floorfunc;
43 planefunction_t ceilingfunc;
49 // Here comes the obnoxious "visplane".
50 #define MAXVISPLANES 128
51 visplane_t visplanes[MAXVISPLANES];
52 visplane_t* lastvisplane;
53 visplane_t* floorplane;
54 visplane_t* ceilingplane;
57 #define MAXOPENINGS SCREENWIDTH*64
58 short openings[MAXOPENINGS];
63 // Clip values are the solid pixel bounding the range.
64 // floorclip starts out SCREENHEIGHT
65 // ceilingclip starts out -1
67 short floorclip[SCREENWIDTH];
68 short ceilingclip[SCREENWIDTH];
71 // spanstart holds the start of a plane span
72 // initialized to 0 at start
74 int spanstart[SCREENHEIGHT];
75 int spanstop[SCREENHEIGHT];
80 lighttable_t** planezlight;
83 fixed_t yslope[SCREENHEIGHT];
84 fixed_t distscale[SCREENWIDTH];
88 fixed_t cachedheight[SCREENHEIGHT];
89 fixed_t cacheddistance[SCREENHEIGHT];
90 fixed_t cachedxstep[SCREENHEIGHT];
91 fixed_t cachedystep[SCREENHEIGHT];
97 // Only at game startup.
99 void R_InitPlanes (void)
133 || (unsigned)y>viewheight)
135 I_Error ("R_MapPlane: %i, %i at %i",x1,x2,y);
139 if (planeheight != cachedheight[y])
141 cachedheight[y] = planeheight;
142 distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]);
143 ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale);
144 ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale);
148 distance = cacheddistance[y];
149 ds_xstep = cachedxstep[y];
150 ds_ystep = cachedystep[y];
153 length = FixedMul (distance,distscale[x1]);
154 angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT;
155 ds_xfrac = viewx + FixedMul(finecosine[angle], length);
156 ds_yfrac = -viewy - FixedMul(finesine[angle], length);
159 ds_colormap = fixedcolormap;
162 index = distance >> LIGHTZSHIFT;
164 if (index >= MAXLIGHTZ )
167 ds_colormap = planezlight[index];
174 // high or low detail
181 // At begining of frame.
183 void R_ClearPlanes (void)
188 // opening / clipping determination
189 for (i=0 ; i<viewwidth ; i++)
191 floorclip[i] = viewheight;
195 lastvisplane = visplanes;
196 lastopening = openings;
198 // texture calculation
199 memset (cachedheight, 0, sizeof(cachedheight));
201 // left to right mapping
202 angle = (viewangle-ANG90)>>ANGLETOFINESHIFT;
204 // scale will be unit scale at SCREENWIDTH/2 distance
205 basexscale = FixedDiv (finecosine[angle],centerxfrac);
206 baseyscale = -FixedDiv (finesine[angle],centerxfrac);
223 if (picnum == skyflatnum)
225 height = 0; // all skys map together
229 for (check=visplanes; check<lastvisplane; check++)
231 if (height == check->height
232 && picnum == check->picnum
233 && lightlevel == check->lightlevel)
240 if (check < lastvisplane)
243 if (lastvisplane - visplanes == MAXVISPLANES)
244 I_Error ("R_FindPlane: no more visplanes");
248 check->height = height;
249 check->picnum = picnum;
250 check->lightlevel = lightlevel;
251 check->minx = SCREENWIDTH;
254 memset (check->top,0xff,sizeof(check->top));
275 if (start < pl->minx)
297 for (x=intrl ; x<= intrh ; x++)
298 if (pl->top[x] != 0xff)
310 // make a new visplane
311 lastvisplane->height = pl->height;
312 lastvisplane->picnum = pl->picnum;
313 lastvisplane->lightlevel = pl->lightlevel;
319 memset (pl->top,0xff,sizeof(pl->top));
336 while (t1 < t2 && t1<=b1)
338 R_MapPlane (t1,spanstart[t1],x-1);
341 while (b1 > b2 && b1>=t1)
343 R_MapPlane (b1,spanstart[b1],x-1);
347 while (t2 < t1 && t2<=b2)
352 while (b2 > b1 && b2>=t2)
363 // At the end of each frame.
365 void R_DrawPlanes (void)
374 if (ds_p - drawsegs > MAXDRAWSEGS)
375 I_Error ("R_DrawPlanes: drawsegs overflow (%i)",
378 if (lastvisplane - visplanes > MAXVISPLANES)
379 I_Error ("R_DrawPlanes: visplane overflow (%i)",
380 lastvisplane - visplanes);
382 if (lastopening - openings > MAXOPENINGS)
383 I_Error ("R_DrawPlanes: opening overflow (%i)",
384 lastopening - openings);
387 for (pl = visplanes ; pl < lastvisplane ; pl++)
389 if (pl->minx > pl->maxx)
394 if (pl->picnum == skyflatnum)
396 dc_iscale = pspriteiscale>>detailshift;
398 // Sky is allways drawn full bright,
399 // i.e. colormaps[0] is used.
400 // Because of this hack, sky is not affected
401 // by INVUL inverse mapping.
402 dc_colormap = colormaps;
403 dc_texturemid = skytexturemid;
404 for (x=pl->minx ; x <= pl->maxx ; x++)
407 dc_yh = pl->bottom[x];
411 angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
413 dc_source = R_GetColumn(skytexture, angle);
421 ds_source = W_CacheLumpNum(firstflat +
422 flattranslation[pl->picnum],
425 planeheight = abs(pl->height-viewz);
426 light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight;
428 if (light >= LIGHTLEVELS)
429 light = LIGHTLEVELS-1;
434 planezlight = zlight[light];
436 pl->top[pl->maxx+1] = 0xff;
437 pl->top[pl->minx-1] = 0xff;
441 for (x=pl->minx ; x<= stop ; x++)
443 R_MakeSpans(x,pl->top[x-1],
449 Z_ChangeTag (ds_source, PU_CACHE);