r_plane.c (6029B)
1 #include <stdlib.h> 2 3 #include "i_system.h" 4 #include "z_zone.h" 5 #include "w_wad.h" 6 #include "doomdef.h" 7 #include "doomstat.h" 8 #include "r_local.h" 9 10 planefunction_t floorfunc; 11 planefunction_t ceilingfunc; 12 #define MAXVISPLANES 128 13 visplane_t visplanes[MAXVISPLANES]; 14 visplane_t* lastvisplane; 15 visplane_t* floorplane; 16 visplane_t* ceilingplane; 17 #define MAXOPENINGS SCREENWIDTH*64 18 short openings[MAXOPENINGS]; 19 short* lastopening; 20 short floorclip[SCREENWIDTH]; 21 short ceilingclip[SCREENWIDTH]; 22 int spanstart[SCREENHEIGHT]; 23 int spanstop[SCREENHEIGHT]; 24 lighttable_t** planezlight; 25 fixed_t planeheight; 26 fixed_t yslope[SCREENHEIGHT]; 27 fixed_t distscale[SCREENWIDTH]; 28 fixed_t basexscale; 29 fixed_t baseyscale; 30 fixed_t cachedheight[SCREENHEIGHT]; 31 fixed_t cacheddistance[SCREENHEIGHT]; 32 fixed_t cachedxstep[SCREENHEIGHT]; 33 fixed_t cachedystep[SCREENHEIGHT]; 34 35 void 36 R_InitPlanes() 37 { 38 } 39 40 void 41 R_MapPlane(int y, int x1, int x2) 42 { 43 angle_t angle; 44 fixed_t distance, length; 45 uint index; 46 47 if (planeheight != cachedheight[y]) { 48 cachedheight[y] = planeheight; 49 distance = cacheddistance[y] = FixedMul (planeheight, yslope[y]); 50 ds_xstep = cachedxstep[y] = FixedMul (distance,basexscale); 51 ds_ystep = cachedystep[y] = FixedMul (distance,baseyscale); 52 } else { 53 distance = cacheddistance[y]; 54 ds_xstep = cachedxstep[y]; 55 ds_ystep = cachedystep[y]; 56 } 57 length = FixedMul (distance,distscale[x1]); 58 angle = (viewangle + xtoviewangle[x1])>>ANGLETOFINESHIFT; 59 ds_xfrac = viewx + FixedMul(finecosine[angle], length); 60 ds_yfrac = -viewy - FixedMul(finesine[angle], length); 61 if (fixedcolormap) { 62 ds_colormap = fixedcolormap; 63 } else { 64 index = distance >> LIGHTZSHIFT; 65 if (index >= MAXLIGHTZ ) 66 index = MAXLIGHTZ-1; 67 ds_colormap = planezlight[index]; 68 } 69 ds_y = y; 70 ds_x1 = x1; 71 ds_x2 = x2; 72 spanfunc(); 73 } 74 75 void 76 R_ClearPlanes (void) 77 { 78 int i; 79 angle_t angle; 80 81 82 for (i=0 ; i<viewwidth ; i++) 83 { 84 floorclip[i] = viewheight; 85 ceilingclip[i] = -1; 86 } 87 88 lastvisplane = visplanes; 89 lastopening = openings; 90 91 92 memset (cachedheight, 0, sizeof(cachedheight)); 93 94 95 angle = (viewangle-ANG90)>>ANGLETOFINESHIFT; 96 97 98 basexscale = FixedDiv (finecosine[angle],centerxfrac); 99 baseyscale = -FixedDiv (finesine[angle],centerxfrac); 100 } 101 102 103 104 105 106 107 108 visplane_t* 109 R_FindPlane 110 ( fixed_t height, 111 int picnum, 112 int lightlevel ) 113 { 114 visplane_t* check; 115 116 if (picnum == skyflatnum) 117 { 118 height = 0; 119 lightlevel = 0; 120 } 121 122 for (check=visplanes; check<lastvisplane; check++) 123 { 124 if (height == check->height 125 && picnum == check->picnum 126 && lightlevel == check->lightlevel) 127 { 128 break; 129 } 130 } 131 132 133 if (check < lastvisplane) 134 return check; 135 136 if (lastvisplane - visplanes == MAXVISPLANES) 137 I_Error ("R_FindPlane: no more visplanes"); 138 139 lastvisplane++; 140 141 check->height = height; 142 check->picnum = picnum; 143 check->lightlevel = lightlevel; 144 check->minx = SCREENWIDTH; 145 check->maxx = -1; 146 147 memset (check->top,0xff,sizeof(check->top)); 148 149 return check; 150 } 151 152 153 154 155 156 visplane_t* 157 R_CheckPlane 158 ( visplane_t* pl, 159 int start, 160 int stop ) 161 { 162 int intrl; 163 int intrh; 164 int unionl; 165 int unionh; 166 int x; 167 168 if (start < pl->minx) 169 { 170 intrl = pl->minx; 171 unionl = start; 172 } 173 else 174 { 175 unionl = pl->minx; 176 intrl = start; 177 } 178 179 if (stop > pl->maxx) 180 { 181 intrh = pl->maxx; 182 unionh = stop; 183 } 184 else 185 { 186 unionh = pl->maxx; 187 intrh = stop; 188 } 189 190 for (x=intrl ; x<= intrh ; x++) 191 if (pl->top[x] != 0xff) 192 break; 193 194 if (x > intrh) 195 { 196 pl->minx = unionl; 197 pl->maxx = unionh; 198 199 200 return pl; 201 } 202 203 204 lastvisplane->height = pl->height; 205 lastvisplane->picnum = pl->picnum; 206 lastvisplane->lightlevel = pl->lightlevel; 207 208 pl = lastvisplane++; 209 pl->minx = start; 210 pl->maxx = stop; 211 212 memset (pl->top,0xff,sizeof(pl->top)); 213 214 return pl; 215 } 216 217 218 219 220 221 void 222 R_MakeSpans 223 ( int x, 224 int t1, 225 int b1, 226 int t2, 227 int b2 ) 228 { 229 while (t1 < t2 && t1<=b1) 230 { 231 R_MapPlane (t1,spanstart[t1],x-1); 232 t1++; 233 } 234 while (b1 > b2 && b1>=t1) 235 { 236 R_MapPlane (b1,spanstart[b1],x-1); 237 b1--; 238 } 239 240 while (t2 < t1 && t2<=b2) 241 { 242 spanstart[t2] = x; 243 t2++; 244 } 245 while (b2 > b1 && b2>=t2) 246 { 247 spanstart[b2] = x; 248 b2--; 249 } 250 } 251 252 253 254 255 256 257 258 void R_DrawPlanes (void) 259 { 260 visplane_t* pl; 261 int light; 262 int x; 263 int stop; 264 int angle; 265 266 #ifdef RANGECHECK 267 if (ds_p - drawsegs > MAXDRAWSEGS) 268 I_Error ("R_DrawPlanes: drawsegs overflow (%i)", 269 ds_p - drawsegs); 270 271 if (lastvisplane - visplanes > MAXVISPLANES) 272 I_Error ("R_DrawPlanes: visplane overflow (%i)", 273 lastvisplane - visplanes); 274 275 if (lastopening - openings > MAXOPENINGS) 276 I_Error ("R_DrawPlanes: opening overflow (%i)", 277 lastopening - openings); 278 #endif 279 280 for (pl = visplanes ; pl < lastvisplane ; pl++) 281 { 282 if (pl->minx > pl->maxx) 283 continue; 284 285 286 287 if (pl->picnum == skyflatnum) 288 { 289 dc_iscale = pspriteiscale>>detailshift; 290 291 292 293 294 295 dc_colormap = colormaps; 296 dc_texturemid = skytexturemid; 297 for (x=pl->minx ; x <= pl->maxx ; x++) 298 { 299 dc_yl = pl->top[x]; 300 dc_yh = pl->bottom[x]; 301 302 if (dc_yl <= dc_yh) 303 { 304 angle = (viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; 305 dc_x = x; 306 dc_source = R_GetColumn(skytexture, angle); 307 colfunc (); 308 } 309 } 310 continue; 311 } 312 313 314 ds_source = W_CacheLumpNum(firstflat + 315 flattranslation[pl->picnum], 316 PU_STATIC); 317 318 planeheight = abs(pl->height-viewz); 319 light = (pl->lightlevel >> LIGHTSEGSHIFT)+extralight; 320 321 if (light >= LIGHTLEVELS) 322 light = LIGHTLEVELS-1; 323 324 if (light < 0) 325 light = 0; 326 327 planezlight = zlight[light]; 328 329 pl->top[pl->maxx+1] = 0xff; 330 pl->top[pl->minx-1] = 0xff; 331 332 stop = pl->maxx + 1; 333 334 for (x=pl->minx ; x<= stop ; x++) 335 { 336 R_MakeSpans(x,pl->top[x-1], 337 pl->bottom[x-1], 338 pl->top[x], 339 pl->bottom[x]); 340 } 341 342 Z_ChangeTag (ds_source, PU_CACHE); 343 } 344 }