Correct texture scaling, part 3

This commit is contained in:
Lactozilla 2023-11-23 20:03:23 -03:00
parent 10537deacf
commit 2f20f21eb6
2 changed files with 55 additions and 52 deletions

View file

@ -757,6 +757,8 @@ typedef struct drawseg_s
fixed_t bsilheight; // do not clip sprites above this fixed_t bsilheight; // do not clip sprites above this
fixed_t tsilheight; // do not clip sprites below this fixed_t tsilheight; // do not clip sprites below this
fixed_t offsetx;
// Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value.
INT16 *sprtopclip; INT16 *sprtopclip;
INT16 *sprbottomclip; INT16 *sprbottomclip;

View file

@ -76,6 +76,7 @@ static fixed_t bottomfrac, bottomstep;
static lighttable_t **walllights; static lighttable_t **walllights;
static fixed_t *maskedtexturecol = NULL; static fixed_t *maskedtexturecol = NULL;
static fixed_t *maskedtextureheight = NULL; static fixed_t *maskedtextureheight = NULL;
static fixed_t *thicksidecol = NULL;
static fixed_t *invscale = NULL; static fixed_t *invscale = NULL;
//SoM: 3/23/2000: Use boom opening limit removal //SoM: 3/23/2000: Use boom opening limit removal
@ -535,7 +536,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
INT32 i, p; INT32 i, p;
fixed_t bottombounds = viewheight << FRACBITS; fixed_t bottombounds = viewheight << FRACBITS;
fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS;
fixed_t offsetvalue = 0; fixed_t offsetvalue;
lightlist_t *light; lightlist_t *light;
r_lightlist_t *rlight; r_lightlist_t *rlight;
INT32 range; INT32 range;
@ -544,11 +545,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// NOTE: INT64 instead of fixed_t because overflow concerns // NOTE: INT64 instead of fixed_t because overflow concerns
INT64 top_frac, top_step, bottom_frac, bottom_step; INT64 top_frac, top_step, bottom_frac, bottom_step;
// skew FOF walls with slopes? // skew FOF walls with slopes?
boolean slopeskew = false;
fixed_t ffloortextureslide = 0; fixed_t ffloortextureslide = 0;
INT32 oldx = -1; INT32 oldx = -1;
fixed_t left_top, left_bottom; // needed here for slope skewing fixed_t left_top, left_bottom; // needed here for slope skewing
pslope_t *skewslope = NULL; pslope_t *skewslope = NULL;
boolean do_texture_skew;
UINT32 lineflags;
fixed_t wall_scalex, wall_scaley;
void (*colfunc_2s) (column_t *); void (*colfunc_2s) (column_t *);
@ -560,7 +563,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
curline = ds->curline; curline = ds->curline;
backsector = pfloor->target; backsector = pfloor->target;
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); sidedef = &sides[pfloor->master->sidenum[0]];
colfunc = colfuncs[BASEDRAWFUNC]; colfunc = colfuncs[BASEDRAWFUNC];
@ -568,8 +571,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{ {
size_t linenum = curline->linedef-backsector->lines[0]; size_t linenum = curline->linedef-backsector->lines[0];
newline = pfloor->master->frontsector->lines[0] + linenum; newline = pfloor->master->frontsector->lines[0] + linenum;
texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); sidedef = &sides[newline->sidenum[0]];
lineflags = newline->flags;
} }
else
lineflags = pfloor->master->flags;
texnum = R_GetTextureNum(sidedef->midtexture);
if (pfloor->fofflags & FOF_TRANSLUCENT) if (pfloor->fofflags & FOF_TRANSLUCENT)
{ {
@ -721,7 +729,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
walllights = scalelight[lightnum]; walllights = scalelight[lightnum];
} }
maskedtexturecol = ds->thicksidecol; wall_scalex = FixedDiv(FRACUNIT, sidedef->scalex_mid);
wall_scaley = sidedef->scaley_mid;
thicksidecol = ds->thicksidecol;
for (INT32 x = x1; x <= x2; x++)
thicksidecol[x] = FixedDiv(thicksidecol[x], wall_scalex) + ds->offsetx;
mfloorclip = ds->sprbottomclip; mfloorclip = ds->sprbottomclip;
mceilingclip = ds->sprtopclip; mceilingclip = ds->sprtopclip;
@ -731,50 +745,28 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; left_top = P_GetFFloorTopZAt (pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz; left_bottom = P_GetFFloorBottomZAt(pfloor, ds->leftpos.x, ds->leftpos.y) - viewz;
do_texture_skew = lineflags & ML_SKEWTD;
skewslope = *pfloor->t_slope; // skew using top slope by default skewslope = *pfloor->t_slope; // skew using top slope by default
if (newline)
{
if (newline->flags & ML_SKEWTD)
slopeskew = true;
}
else if (pfloor->master->flags & ML_SKEWTD)
slopeskew = true;
if (slopeskew) if (do_texture_skew)
dc_texturemid = left_top; dc_texturemid = FixedMul(left_top, wall_scaley);
else else
dc_texturemid = *pfloor->topheight - viewz; dc_texturemid = FixedMul(*pfloor->topheight - viewz, wall_scaley);
if (newline) offsetvalue = sidedef->rowoffset + sidedef->offsety_mid;
{
offsetvalue = sides[newline->sidenum[0]].rowoffset + sides[newline->sidenum[0]].offsety_mid; if (lineflags & ML_DONTPEGBOTTOM)
if (newline->flags & ML_DONTPEGBOTTOM)
{ {
skewslope = *pfloor->b_slope; // skew using bottom slope skewslope = *pfloor->b_slope; // skew using bottom slope
if (slopeskew) if (do_texture_skew)
dc_texturemid = left_bottom; dc_texturemid = FixedMul(left_bottom, wall_scaley);
else else
offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; offsetvalue -= FixedMul(*pfloor->topheight - *pfloor->bottomheight, wall_scaley);
}
}
else
{
offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset + sides[pfloor->master->sidenum[0]].offsety_mid;
if (curline->linedef->flags & ML_DONTPEGBOTTOM)
{
skewslope = *pfloor->b_slope; // skew using bottom slope
if (slopeskew)
dc_texturemid = left_bottom;
else
offsetvalue -= *pfloor->topheight - *pfloor->bottomheight;
}
} }
if (slopeskew) if (do_texture_skew && skewslope)
{ {
angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y);
if (skewslope)
ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT));
} }
@ -829,7 +821,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (ffloortextureslide) if (ffloortextureslide)
{ {
if (oldx != -1) if (oldx != -1)
dc_texturemid += FixedMul(ffloortextureslide, maskedtexturecol[oldx]-maskedtexturecol[dc_x]); dc_texturemid += FixedMul(ffloortextureslide, thicksidecol[oldx]-thicksidecol[dc_x]);
oldx = dc_x; oldx = dc_x;
} }
@ -862,10 +854,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
continue; continue;
} }
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
// Get data for the column // Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (maskedtexturecol[dc_x] >> FRACBITS)) - 3); col = (column_t *)((UINT8 *)R_GetColumn(texnum, (thicksidecol[dc_x] >> FRACBITS)) - 3);
// SoM: New code does not rely on R_DrawColumnShadowed_8 which // SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack. // will (hopefully) put less strain on the stack.
@ -1439,7 +1431,10 @@ static void R_RenderSegLoop (void)
} }
if (maskedtexturecol) if (maskedtexturecol)
maskedtexturecol[rw_x] = texturecolumn; maskedtexturecol[rw_x] = texturecolumn + rw_offsetx;
if (thicksidecol)
thicksidecol[rw_x] = rw_offset - distance;
if (maskedtextureheight) if (maskedtextureheight)
{ {
@ -1551,10 +1546,9 @@ static void R_AllocClippingTables(size_t range)
static void R_AllocTextureColumnTables(size_t range) static void R_AllocTextureColumnTables(size_t range)
{ {
size_t pos = curtexturecolumntable - texturecolumntable; size_t pos = curtexturecolumntable - texturecolumntable;
size_t need = range * 3;
// For both tables, we reserve exactly an amount of memory that's equivalent to if (pos + need < texturecolumntablesize)
// how many columns the seg will take on the entire screen (think about it)
if (pos + range < texturecolumntablesize)
return; return;
fixed_t *oldtable = texturecolumntable; fixed_t *oldtable = texturecolumntable;
@ -1563,7 +1557,7 @@ static void R_AllocTextureColumnTables(size_t range)
if (texturecolumntablesize == 0) if (texturecolumntablesize == 0)
texturecolumntablesize = 16384; texturecolumntablesize = 16384;
texturecolumntablesize += range; texturecolumntablesize += need;
texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL); texturecolumntable = Z_Realloc(texturecolumntable, texturecolumntablesize * sizeof (*texturecolumntable), PU_STATIC, NULL);
curtexturecolumntable = texturecolumntable + pos; curtexturecolumntable = texturecolumntable + pos;
@ -1604,6 +1598,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
maskedtexturecol = NULL; maskedtexturecol = NULL;
maskedtextureheight = NULL; maskedtextureheight = NULL;
thicksidecol = NULL;
invscale = NULL; invscale = NULL;
//initialize segleft and segright //initialize segleft and segright
@ -2135,9 +2130,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_toptexturemid += toprowoffset; rw_toptexturemid += toprowoffset;
rw_bottomtexturemid += botrowoffset; rw_bottomtexturemid += botrowoffset;
// allocate space for masked texture tables
R_AllocTextureColumnTables(rw_stopx - start); R_AllocTextureColumnTables(rw_stopx - start);
// allocate space for masked texture tables
if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors)) if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors))
{ {
ffloor_t *rover; ffloor_t *rover;
@ -2150,7 +2145,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
maskedtexture = true; maskedtexture = true;
ds_p->thicksidecol = curtexturecolumntable - rw_x; ds_p->thicksidecol = thicksidecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x; curtexturecolumntable += rw_stopx - rw_x;
lowcut = max(worldbottom, worldlow) + viewz; lowcut = max(worldbottom, worldlow) + viewz;
@ -2329,14 +2324,17 @@ void R_StoreWallRange(INT32 start, INT32 stop)
ds_p->numthicksides = numthicksides = i; ds_p->numthicksides = numthicksides = i;
} }
// masked midtexture
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures)
{ {
// masked midtexture
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x; curtexturecolumntable += rw_stopx - rw_x;
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
maskedtexture = true;
if (curline->polyseg) if (curline->polyseg)
{ {
// use REAL front and back floors please, so midtexture rendering isn't mucked up // use REAL front and back floors please, so midtexture rendering isn't mucked up
@ -2427,6 +2425,9 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (rw_midtexturescalex < 0) if (rw_midtexturescalex < 0)
rw_offsetx = -rw_offsetx; rw_offsetx = -rw_offsetx;
if (numthicksides)
ds_p->offsetx = rw_offsetx;
// calculate light table // calculate light table
// use different light tables // use different light tables
// for horizontal / vertical / diagonal // for horizontal / vertical / diagonal