in doom_py/src/vizdoom/src/r_segs.cpp [224:588]
void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
{
FTexture *tex;
int i;
sector_t tempsec; // killough 4/13/98
fixed_t texheight, textop, texheightscale;
bool notrelevant = false;
fixed_t rowoffset;
const sector_t *sec;
sprflipvert = false;
curline = ds->curline;
// killough 4/11/98: draw translucent 2s normal textures
// [RH] modified because we don't use user-definable translucency maps
ESPSResult drawmode;
drawmode = R_SetPatchStyle (LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent],
MIN(curline->linedef->Alpha, FRACUNIT), 0, 0);
if ((drawmode == DontDraw && !ds->bFogBoundary && !ds->bFakeBoundary))
{
return;
}
NetUpdate ();
frontsector = curline->frontsector;
backsector = curline->backsector;
tex = TexMan(curline->sidedef->GetTexture(side_t::mid), true);
if (i_compatflags & COMPATF_MASKEDMIDTEX)
{
tex = tex->GetRawTexture();
}
// killough 4/13/98: get correct lightlevel for 2s normal textures
sec = R_FakeFlat (frontsector, &tempsec, NULL, NULL, false);
basecolormap = sec->ColorMap; // [RH] Set basecolormap
wallshade = ds->shade;
rw_lightstep = ds->lightstep;
rw_light = ds->light + (x1 - ds->x1) * rw_lightstep;
if (fixedlightlev < 0)
{
for (i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
{
if (!(fake3D & FAKE3D_CLIPTOP))
{
sclipTop = sec->ceilingplane.ZatPoint(viewx, viewy);
}
if (sclipTop <= frontsector->e->XFloor.lightlist[i].plane.ZatPoint(viewx, viewy))
{
lightlist_t *lit = &frontsector->e->XFloor.lightlist[i];
basecolormap = lit->extra_colormap;
wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource == NULL) + r_actualextralight);
break;
}
}
}
mfloorclip = openings + ds->sprbottomclip - ds->x1;
mceilingclip = openings + ds->sprtopclip - ds->x1;
// [RH] Draw fog partition
if (ds->bFogBoundary)
{
R_DrawFogBoundary (x1, x2, mceilingclip, mfloorclip);
if (ds->maskedtexturecol == -1)
{
goto clearfog;
}
}
if ((ds->bFakeBoundary && !(ds->bFakeBoundary & 4)) || drawmode == DontDraw)
{
goto clearfog;
}
MaskedSWall = (fixed_t *)(openings + ds->swall) - ds->x1;
MaskedScaleY = ds->yrepeat;
maskedtexturecol = (fixed_t *)(openings + ds->maskedtexturecol) - ds->x1;
spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
rw_scalestep = ds->iscalestep;
if (fixedlightlev >= 0)
dc_colormap = basecolormap->Maps + fixedlightlev;
else if (fixedcolormap != NULL)
dc_colormap = fixedcolormap;
// find positioning
texheight = tex->GetScaledHeight() << FRACBITS;
texheightscale = abs(curline->sidedef->GetTextureYScale(side_t::mid));
if (texheightscale != FRACUNIT)
{
texheight = FixedDiv(texheight, texheightscale);
}
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{
dc_texturemid = MAX (frontsector->GetPlaneTexZ(sector_t::floor), backsector->GetPlaneTexZ(sector_t::floor)) + texheight;
}
else
{
dc_texturemid = MIN (frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling));
}
rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid);
if (!(curline->linedef->flags & ML_WRAP_MIDTEX) &&
!(curline->sidedef->Flags & WALLF_WRAP_MIDTEX))
{ // Texture does not wrap vertically.
fixed_t textop;
if (MaskedScaleY < 0)
{
MaskedScaleY = -MaskedScaleY;
sprflipvert = true;
}
if (tex->bWorldPanning)
{
// rowoffset is added before the MulScale3 so that the masked texture will
// still be positioned in world units rather than texels.
dc_texturemid += rowoffset - viewz;
textop = dc_texturemid;
dc_texturemid = MulScale16 (dc_texturemid, MaskedScaleY);
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
textop = dc_texturemid - viewz + SafeDivScale16 (rowoffset, MaskedScaleY);
dc_texturemid = MulScale16 (dc_texturemid - viewz, MaskedScaleY) + rowoffset;
}
if (sprflipvert)
{
MaskedScaleY = -MaskedScaleY;
dc_texturemid -= tex->GetHeight() << FRACBITS;
}
// [RH] Don't bother drawing segs that are completely offscreen
if (MulScale12 (globaldclip, ds->sz1) < -textop &&
MulScale12 (globaldclip, ds->sz2) < -textop)
{ // Texture top is below the bottom of the screen
goto clearfog;
}
if (MulScale12 (globaluclip, ds->sz1) > texheight - textop &&
MulScale12 (globaluclip, ds->sz2) > texheight - textop)
{ // Texture bottom is above the top of the screen
goto clearfog;
}
if ((fake3D & FAKE3D_CLIPBOTTOM) && textop < sclipBottom - viewz)
{
notrelevant = true;
goto clearfog;
}
if ((fake3D & FAKE3D_CLIPTOP) && textop - texheight > sclipTop - viewz)
{
notrelevant = true;
goto clearfog;
}
WallC.sz1 = ds->sz1;
WallC.sz2 = ds->sz2;
WallC.sx1 = ds->sx1;
WallC.sx2 = ds->sx2;
if (fake3D & FAKE3D_CLIPTOP)
{
OWallMost(wallupper, textop < sclipTop - viewz ? textop : sclipTop - viewz, &WallC);
}
else
{
OWallMost(wallupper, textop, &WallC);
}
if (fake3D & FAKE3D_CLIPBOTTOM)
{
OWallMost(walllower, textop - texheight > sclipBottom - viewz ? textop - texheight : sclipBottom - viewz, &WallC);
}
else
{
OWallMost(walllower, textop - texheight, &WallC);
}
for (i = x1; i < x2; i++)
{
if (wallupper[i] < mceilingclip[i])
wallupper[i] = mceilingclip[i];
}
for (i = x1; i < x2; i++)
{
if (walllower[i] > mfloorclip[i])
walllower[i] = mfloorclip[i];
}
if (CurrentSkybox)
{ // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor
// or above the ceiling, so the appropriate end won't be clipped automatically when adding
// this drawseg.
if ((curline->linedef->flags & ML_CLIP_MIDTEX) ||
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX))
{
ClipMidtex(x1, x2);
}
}
mfloorclip = walllower;
mceilingclip = wallupper;
// draw the columns one at a time
if (drawmode == DoDraw0)
{
for (dc_x = x1; dc_x < x2; ++dc_x)
{
BlastMaskedColumn (R_DrawMaskedColumn, tex);
}
}
else
{
// [RH] Draw up to four columns at once
int stop = x2 & ~3;
if (x1 >= x2)
goto clearfog;
dc_x = x1;
while ((dc_x < stop) && (dc_x & 3))
{
if(depthMap!=NULL) {
depthMap->setActualDepth((unsigned int) ((MaskedSWall[dc_x] - 7500) * 255) / (1250000 - 7500));
if (MaskedSWall[dc_x] > 1250000)
depthMap->setActualDepth(255);
if (MaskedSWall[dc_x] < 7500)
depthMap->setActualDepth(0);
}
BlastMaskedColumn (R_DrawMaskedColumn, tex);
dc_x++;
}
while (dc_x < stop)
{
for(int pcf=0;pcf<4;pcf++) {
if(depthMap!=NULL) {
depthMap->helperBuffer[pcf]=(unsigned int) ((MaskedSWall[dc_x+pcf] - 7500) * 255) / (1250000 - 7500);
if (MaskedSWall[dc_x+pcf] > 1250000)
depthMap->helperBuffer[pcf]=(255);
if (MaskedSWall[dc_x+pcf] < 7500)
depthMap->helperBuffer[pcf]=(0);
}
/*static long max, min;
if (min == 0) min = max;
if (MaskedSWall[dc_x] > max || MaskedSWall[dc_x] < min) {
if (MaskedSWall[dc_x] > max)
max = MaskedSWall[dc_x];
else
min = MaskedSWall[dc_x];
printf("MAX: %ld MIN: %ld\n", max, min);
}*/
}
rt_initcols();
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex); dc_x++;
BlastMaskedColumn (R_DrawMaskedColumnHoriz, tex);
rt_draw4cols (dc_x - 3);
dc_x++;
}
while (dc_x < x2)
{
if(depthMap!=NULL) {
depthMap->setActualDepth((unsigned int) ((MaskedSWall[dc_x] - 7500) * 255) / (1250000 - 7500));
if (MaskedSWall[dc_x] > 1250000)
depthMap->setActualDepth(255);
if (MaskedSWall[dc_x] < 7500)
depthMap->setActualDepth(0);
}
BlastMaskedColumn (R_DrawMaskedColumn, tex);
dc_x++;
}
}
}
else
{ // Texture does wrap vertically.
if (tex->bWorldPanning)
{
// rowoffset is added before the MulScale3 so that the masked texture will
// still be positioned in world units rather than texels.
dc_texturemid += rowoffset - viewz;
dc_texturemid = MulScale16 (dc_texturemid, MaskedScaleY);
}
else
{
// rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units.
dc_texturemid = MulScale16 (dc_texturemid - viewz, MaskedScaleY) + rowoffset;
}
WallC.sz1 = ds->sz1;
WallC.sz2 = ds->sz2;
WallC.sx1 = ds->sx1;
WallC.sx2 = ds->sx2;
if (CurrentSkybox)
{ // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor
// or above the ceiling, so the appropriate end won't be clipped automatically when adding
// this drawseg.
if ((curline->linedef->flags & ML_CLIP_MIDTEX) ||
(curline->sidedef->Flags & WALLF_CLIP_MIDTEX))
{
ClipMidtex(x1, x2);
}
}
if (fake3D & FAKE3D_CLIPTOP)
{
OWallMost(wallupper, sclipTop - viewz, &WallC);
for (i = x1; i < x2; i++)
{
if (wallupper[i] < mceilingclip[i])
wallupper[i] = mceilingclip[i];
}
mceilingclip = wallupper;
}
if (fake3D & FAKE3D_CLIPBOTTOM)
{
OWallMost(walllower, sclipBottom - viewz, &WallC);
for (i = x1; i < x2; i++)
{
if (walllower[i] > mfloorclip[i])
walllower[i] = mfloorclip[i];
}
mfloorclip = walllower;
}
rw_offset = 0;
rw_pic = tex;
wallscan_np2_ds(ds, x1, x2, mceilingclip, mfloorclip, MaskedSWall, maskedtexturecol, ds->yrepeat);
}
clearfog:
R_FinishSetPatchStyle ();
if (ds->bFakeBoundary & 3)
{
R_RenderFakeWallRange(ds, x1, x2);
}
if (!notrelevant)
{
if (fake3D & FAKE3D_REFRESHCLIP)
{
assert(ds->bkup >= 0);
memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2 - ds->x1) * 2);
}
else
{
clearbufshort(openings + ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight);
}
}
return;
}