r_segs.c (12546B)
1 #include <stdlib.h> 2 3 #include "i_system.h" 4 #include "doomdef.h" 5 #include "doomstat.h" 6 #include "r_local.h" 7 #include "r_things.h" 8 9 boolean segtextured; 10 boolean markfloor; 11 boolean markceiling; 12 boolean maskedtexture; 13 int toptexture; 14 int bottomtexture; 15 int midtexture; 16 angle_t rw_normalangle; 17 int rw_angle1; 18 int rw_x; 19 int rw_stopx; 20 angle_t rw_centerangle; 21 fixed_t rw_offset; 22 fixed_t rw_distance; 23 fixed_t rw_scale; 24 fixed_t rw_scalestep; 25 fixed_t rw_midtexturemid; 26 fixed_t rw_toptexturemid; 27 fixed_t rw_bottomtexturemid; 28 int worldtop; 29 int worldbottom; 30 int worldhigh; 31 int worldlow; 32 fixed_t pixhigh; 33 fixed_t pixlow; 34 fixed_t pixhighstep; 35 fixed_t pixlowstep; 36 fixed_t topfrac; 37 fixed_t topstep; 38 fixed_t bottomfrac; 39 fixed_t bottomstep; 40 lighttable_t** walllights; 41 short* maskedtexturecol; 42 43 void 44 R_RenderMaskedSegRange(drawseg_t* ds, int x1, int x2) 45 { 46 column_t* col; 47 uint index; 48 int lightnum, texnum; 49 50 curline = ds->curline; 51 frontsector = curline->frontsector; 52 backsector = curline->backsector; 53 texnum = texturetranslation[curline->sidedef->midtexture]; 54 lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight; 55 if (curline->v1->y == curline->v2->y) 56 --lightnum; 57 if (curline->v1->x == curline->v2->x) 58 ++lightnum; 59 if (lightnum < 0) 60 walllights = scalelight[0]; 61 else if (lightnum >= LIGHTLEVELS) 62 walllights = scalelight[LIGHTLEVELS-1]; 63 else 64 walllights = scalelight[lightnum]; 65 maskedtexturecol = ds->maskedtexturecol; 66 rw_scalestep = ds->scalestep; 67 spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; 68 mfloorclip = ds->sprbottomclip; 69 mceilingclip = ds->sprtopclip; 70 if (curline->linedef->flags & ML_DONTPEGBOTTOM) { 71 dc_texturemid = 72 frontsector->floorheight > backsector->floorheight 73 ? frontsector->floorheight 74 : backsector->floorheight; 75 dc_texturemid = dc_texturemid + textureheight_g[texnum] - viewz; 76 } else { 77 dc_texturemid = 78 frontsector->ceilingheight<backsector->ceilingheight 79 ? frontsector->ceilingheight 80 : backsector->ceilingheight; 81 dc_texturemid = dc_texturemid - viewz; 82 } 83 dc_texturemid += curline->sidedef->rowoffset; 84 if (fixedcolormap) 85 dc_colormap = fixedcolormap; 86 for (dc_x = x1; dc_x <= x2; ++dc_x) { 87 if (maskedtexturecol[dc_x] != SHRT_MAX) { 88 if (!fixedcolormap) { 89 index = spryscale >> LIGHTSCALESHIFT; 90 if (index >= MAXLIGHTSCALE ) 91 index = MAXLIGHTSCALE-1; 92 dc_colormap = walllights[index]; 93 } 94 sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); 95 dc_iscale = 0xffffffffu / (unsigned)spryscale; 96 col = (column_t*)((byte*)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3); 97 R_DrawMaskedColumn(col); 98 maskedtexturecol[dc_x] = SHRT_MAX; 99 } 100 spryscale += rw_scalestep; 101 } 102 } 103 104 #define HEIGHTBITS 12 105 #define HEIGHTUNIT (1<<HEIGHTBITS) 106 107 void 108 R_RenderSegLoop() 109 { 110 angle_t angle; 111 fixed_t texturecolumn; 112 uint index; 113 int yl, yh, mid, top, bottom; 114 115 texturecolumn = 0; 116 for (; rw_x < rw_stopx; ++rw_x) { 117 yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; 118 if (yl < ceilingclip[rw_x]+1) 119 yl = ceilingclip[rw_x]+1; 120 if (markceiling) { 121 top = ceilingclip[rw_x] + 1; 122 bottom = yl - 1; 123 if (bottom >= floorclip[rw_x]) 124 bottom = floorclip[rw_x]-1; 125 if (top <= bottom) { 126 ceilingplane->top[rw_x] = top; 127 ceilingplane->bottom[rw_x] = bottom; 128 } 129 } 130 yh = bottomfrac>>HEIGHTBITS; 131 if (yh >= floorclip[rw_x]) 132 yh = floorclip[rw_x]-1; 133 if (markfloor) { 134 top = yh + 1; 135 bottom = floorclip[rw_x] - 1; 136 if (top <= ceilingclip[rw_x]) 137 top = ceilingclip[rw_x] + 1; 138 if (top <= bottom) { 139 floorplane->top[rw_x] = top; 140 floorplane->bottom[rw_x] = bottom; 141 } 142 } 143 if (segtextured) { 144 angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; 145 texturecolumn = rw_offset - FixedMul(finetangent[angle], rw_distance); 146 texturecolumn >>= FRACBITS; 147 index = rw_scale>>LIGHTSCALESHIFT; 148 if (index >= MAXLIGHTSCALE) 149 index = MAXLIGHTSCALE-1; 150 dc_colormap = walllights[index]; 151 dc_x = rw_x; 152 dc_iscale = 0xffffffffu / (unsigned)rw_scale; 153 } 154 if (midtexture) { 155 dc_yl = yl; 156 dc_yh = yh; 157 dc_texturemid = rw_midtexturemid; 158 dc_source = R_GetColumn(midtexture,texturecolumn); 159 colfunc (); 160 ceilingclip[rw_x] = viewheight; 161 floorclip[rw_x] = -1; 162 } else { 163 if (toptexture) { 164 mid = pixhigh>>HEIGHTBITS; 165 pixhigh += pixhighstep; 166 if (mid >= floorclip[rw_x]) 167 mid = floorclip[rw_x]-1; 168 if (mid >= yl) { 169 dc_yl = yl; 170 dc_yh = mid; 171 dc_texturemid = rw_toptexturemid; 172 dc_source = R_GetColumn(toptexture, texturecolumn); 173 colfunc(); 174 ceilingclip[rw_x] = mid; 175 } else 176 ceilingclip[rw_x] = yl-1; 177 } else { 178 if (markceiling) 179 ceilingclip[rw_x] = yl-1; 180 } 181 if (bottomtexture) { 182 mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS; 183 pixlow += pixlowstep; 184 if (mid <= ceilingclip[rw_x]) 185 mid = ceilingclip[rw_x]+1; 186 if (mid <= yh) { 187 dc_yl = mid; 188 dc_yh = yh; 189 dc_texturemid = rw_bottomtexturemid; 190 dc_source = R_GetColumn(bottomtexture, 191 texturecolumn); 192 colfunc(); 193 floorclip[rw_x] = mid; 194 } else 195 floorclip[rw_x] = yh+1; 196 } else { 197 if (markfloor) 198 floorclip[rw_x] = yh+1; 199 } 200 if (maskedtexture) 201 maskedtexturecol[rw_x] = texturecolumn; 202 } 203 rw_scale += rw_scalestep; 204 topfrac += topstep; 205 bottomfrac += bottomstep; 206 } 207 } 208 209 void 210 R_StoreWallRange(int start, int stop) 211 { 212 fixed_t hyp, sineval, vtop; 213 angle_t distangle, offsetangle; 214 int lightnum; 215 216 if (ds_p == &drawsegs[MAXDRAWSEGS]) 217 return; 218 #ifdef RANGECHECK 219 if (start >=viewwidth || start > stop) 220 I_Error("Bad R_RenderWallRange: %i to %i", start , stop); 221 #endif 222 sidedef = curline->sidedef; 223 linedef = curline->linedef; 224 linedef->flags |= ML_MAPPED; 225 rw_normalangle = curline->angle + ANG90; 226 offsetangle = abs(rw_normalangle-rw_angle1); 227 if (offsetangle > ANG90) 228 offsetangle = ANG90; 229 distangle = ANG90 - offsetangle; 230 hyp = R_PointToDist (curline->v1->x, curline->v1->y); 231 sineval = finesine[distangle>>ANGLETOFINESHIFT]; 232 rw_distance = FixedMul (hyp, sineval); 233 ds_p->x1 = rw_x = start; 234 ds_p->x2 = stop; 235 ds_p->curline = curline; 236 rw_stopx = stop+1; 237 ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); 238 if (stop > start) { 239 ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]); 240 ds_p->scalestep = rw_scalestep = 241 (ds_p->scale2 - rw_scale) / (stop-start); 242 } 243 else 244 { 245 246 #if 0 247 if (rw_distance < FRACUNIT/2) 248 { 249 fixed_t trx,try; 250 fixed_t gxt,gyt; 251 252 trx = curline->v1->x - viewx; 253 try = curline->v1->y - viewy; 254 255 gxt = FixedMul(trx,viewcos); 256 gyt = -FixedMul(try,viewsin); 257 ds_p->scale1 = FixedDiv(projection, gxt-gyt)<<detailshift; 258 } 259 #endif 260 ds_p->scale2 = ds_p->scale1; 261 } 262 263 264 265 worldtop = frontsector->ceilingheight - viewz; 266 worldbottom = frontsector->floorheight - viewz; 267 268 midtexture = toptexture = bottomtexture = maskedtexture = 0; 269 ds_p->maskedtexturecol = NULL; 270 271 if (!backsector) 272 { 273 274 midtexture = texturetranslation[sidedef->midtexture]; 275 276 markfloor = markceiling = true; 277 if (linedef->flags & ML_DONTPEGBOTTOM) 278 { 279 vtop = frontsector->floorheight + 280 textureheight_g[sidedef->midtexture]; 281 282 rw_midtexturemid = vtop - viewz; 283 } 284 else 285 { 286 287 rw_midtexturemid = worldtop; 288 } 289 rw_midtexturemid += sidedef->rowoffset; 290 291 ds_p->silhouette = SIL_BOTH; 292 ds_p->sprtopclip = screenheightarray; 293 ds_p->sprbottomclip = negonearray; 294 ds_p->bsilheight = INT_MAX; 295 ds_p->tsilheight = INT_MIN; 296 } 297 else 298 { 299 300 ds_p->sprtopclip = ds_p->sprbottomclip = NULL; 301 ds_p->silhouette = 0; 302 303 if (frontsector->floorheight > backsector->floorheight) 304 { 305 ds_p->silhouette = SIL_BOTTOM; 306 ds_p->bsilheight = frontsector->floorheight; 307 } 308 else if (backsector->floorheight > viewz) 309 { 310 ds_p->silhouette = SIL_BOTTOM; 311 ds_p->bsilheight = INT_MAX; 312 313 } 314 315 if (frontsector->ceilingheight < backsector->ceilingheight) 316 { 317 ds_p->silhouette |= SIL_TOP; 318 ds_p->tsilheight = frontsector->ceilingheight; 319 } 320 else if (backsector->ceilingheight < viewz) 321 { 322 ds_p->silhouette |= SIL_TOP; 323 ds_p->tsilheight = INT_MIN; 324 325 } 326 327 if (backsector->ceilingheight <= frontsector->floorheight) 328 { 329 ds_p->sprbottomclip = negonearray; 330 ds_p->bsilheight = INT_MAX; 331 ds_p->silhouette |= SIL_BOTTOM; 332 } 333 334 if (backsector->floorheight >= frontsector->ceilingheight) 335 { 336 ds_p->sprtopclip = screenheightarray; 337 ds_p->tsilheight = INT_MIN; 338 ds_p->silhouette |= SIL_TOP; 339 } 340 341 worldhigh = backsector->ceilingheight - viewz; 342 worldlow = backsector->floorheight - viewz; 343 344 345 if (frontsector->ceilingpic == skyflatnum 346 && backsector->ceilingpic == skyflatnum) 347 { 348 worldtop = worldhigh; 349 } 350 351 352 if (worldlow != worldbottom 353 || backsector->floorpic != frontsector->floorpic 354 || backsector->lightlevel != frontsector->lightlevel) 355 { 356 markfloor = true; 357 } 358 else 359 { 360 361 markfloor = false; 362 } 363 364 365 if (worldhigh != worldtop 366 || backsector->ceilingpic != frontsector->ceilingpic 367 || backsector->lightlevel != frontsector->lightlevel) 368 { 369 markceiling = true; 370 } 371 else 372 { 373 374 markceiling = false; 375 } 376 377 if (backsector->ceilingheight <= frontsector->floorheight 378 || backsector->floorheight >= frontsector->ceilingheight) 379 { 380 381 markceiling = markfloor = true; 382 } 383 384 385 if (worldhigh < worldtop) 386 { 387 388 toptexture = texturetranslation[sidedef->toptexture]; 389 if (linedef->flags & ML_DONTPEGTOP) 390 { 391 392 rw_toptexturemid = worldtop; 393 } 394 else 395 { 396 vtop = 397 backsector->ceilingheight 398 + textureheight_g[sidedef->toptexture]; 399 400 401 rw_toptexturemid = vtop - viewz; 402 } 403 } 404 if (worldlow > worldbottom) 405 { 406 407 bottomtexture = texturetranslation[sidedef->bottomtexture]; 408 409 if (linedef->flags & ML_DONTPEGBOTTOM ) 410 { 411 412 413 rw_bottomtexturemid = worldtop; 414 } 415 else 416 rw_bottomtexturemid = worldlow; 417 } 418 rw_toptexturemid += sidedef->rowoffset; 419 rw_bottomtexturemid += sidedef->rowoffset; 420 421 422 if (sidedef->midtexture) 423 { 424 425 maskedtexture = true; 426 ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; 427 lastopening += rw_stopx - rw_x; 428 } 429 } 430 431 432 segtextured = midtexture | toptexture | bottomtexture | maskedtexture; 433 434 if (segtextured) 435 { 436 offsetangle = rw_normalangle-rw_angle1; 437 438 if (offsetangle > ANG180) 439 offsetangle = -offsetangle; 440 441 if (offsetangle > ANG90) 442 offsetangle = ANG90; 443 444 sineval = finesine[offsetangle >>ANGLETOFINESHIFT]; 445 rw_offset = FixedMul (hyp, sineval); 446 447 if (rw_normalangle-rw_angle1 < ANG180) 448 rw_offset = -rw_offset; 449 450 rw_offset += sidedef->textureoffset + curline->offset; 451 rw_centerangle = ANG90 + viewangle - rw_normalangle; 452 453 454 455 456 457 if (!fixedcolormap) 458 { 459 lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight; 460 461 if (curline->v1->y == curline->v2->y) 462 lightnum--; 463 else if (curline->v1->x == curline->v2->x) 464 lightnum++; 465 466 if (lightnum < 0) 467 walllights = scalelight[0]; 468 else if (lightnum >= LIGHTLEVELS) 469 walllights = scalelight[LIGHTLEVELS-1]; 470 else 471 walllights = scalelight[lightnum]; 472 } 473 } 474 475 476 477 478 479 480 if (frontsector->floorheight >= viewz) 481 { 482 483 markfloor = false; 484 } 485 486 if (frontsector->ceilingheight <= viewz 487 && frontsector->ceilingpic != skyflatnum) 488 { 489 490 markceiling = false; 491 } 492 493 494 495 worldtop >>= 4; 496 worldbottom >>= 4; 497 498 topstep = -FixedMul (rw_scalestep, worldtop); 499 topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); 500 501 bottomstep = -FixedMul (rw_scalestep,worldbottom); 502 bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); 503 504 if (backsector) 505 { 506 worldhigh >>= 4; 507 worldlow >>= 4; 508 509 if (worldhigh < worldtop) 510 { 511 pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); 512 pixhighstep = -FixedMul (rw_scalestep,worldhigh); 513 } 514 515 if (worldlow > worldbottom) 516 { 517 pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); 518 pixlowstep = -FixedMul (rw_scalestep,worldlow); 519 } 520 } 521 522 523 if (markceiling) 524 ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1); 525 526 if (markfloor) 527 floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1); 528 529 R_RenderSegLoop (); 530 531 532 533 if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture) 534 && !ds_p->sprtopclip) 535 { 536 memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start)); 537 ds_p->sprtopclip = lastopening - start; 538 lastopening += rw_stopx - start; 539 } 540 541 if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) 542 && !ds_p->sprbottomclip) 543 { 544 memcpy (lastopening, floorclip+start, 2*(rw_stopx-start)); 545 ds_p->sprbottomclip = lastopening - start; 546 lastopening += rw_stopx - start; 547 } 548 549 if (maskedtexture && !(ds_p->silhouette&SIL_TOP)) 550 { 551 ds_p->silhouette |= SIL_TOP; 552 ds_p->tsilheight = INT_MIN; 553 } 554 if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM)) 555 { 556 ds_p->silhouette |= SIL_BOTTOM; 557 ds_p->bsilheight = INT_MAX; 558 } 559 ds_p++; 560 } 561