This commit is contained in:
Lactozilla 2024-05-04 03:39:41 -03:00
parent b6544efceb
commit da3355a153
5 changed files with 235 additions and 23 deletions

View file

@ -74,7 +74,7 @@ UINT8 *dc_transmap; // one of the translucency tables
UINT8 *dc_translation;
struct r_lightlist_s *dc_lightlist = NULL;
INT32 dc_numlights = 0, dc_maxlights, dc_texheight;
INT32 dc_numlights = 0, dc_maxlights, dc_texheight, dc_postlength;
// =========================================================================
// SPAN DRAWING CODE STUFF

View file

@ -41,8 +41,7 @@ extern UINT8 *dc_translation;
extern struct r_lightlist_s *dc_lightlist;
extern INT32 dc_numlights, dc_maxlights;
//Fix TUTIFRUTI
extern INT32 dc_texheight;
extern INT32 dc_texheight, dc_postlength;
// -----------------------
// SPAN DRAWING CODE STUFF
@ -154,8 +153,10 @@ void R_VideoErase(size_t ofs, INT32 count);
// -----------------
void R_DrawColumn_8(void);
void R_DrawColumnClamped_8(void);
void R_DrawShadeColumn_8(void);
void R_DrawTranslucentColumn_8(void);
void R_DrawTranslucentColumnClamped_8(void);
void R_DrawDropShadowColumn_8(void);
void R_DrawTranslatedColumn_8(void);
void R_DrawTranslatedTranslucentColumn_8(void);

View file

@ -100,6 +100,98 @@ void R_DrawColumn_8(void)
}
}
/** \brief The R_DrawColumnClamped_8 function
Same as R_DrawColumn_8, but prevents artifacts from showing up (caused by fixed-point imprecisions)
*/
void R_DrawColumnClamped_8(void)
{
INT32 count;
UINT8 *dest;
fixed_t frac;
fixed_t fracstep;
count = dc_yh - dc_yl;
if (count < 0) // Zero length, column does not exceed a pixel.
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
return;
#endif
// Framebuffer destination address.
dest = &topleft[dc_yl*vid.width + dc_x];
count++;
// Determine scaling, which is the only mapping to be done.
fracstep = dc_iscale;
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
{
const UINT8 *source = dc_source;
const lighttable_t *colormap = dc_colormap;
INT32 heightmask = dc_texheight-1;
INT32 idx;
if (dc_texheight & heightmask) // not a power of 2 -- killough
{
heightmask++;
heightmask <<= FRACBITS;
if (frac < 0)
while ((frac += heightmask) < 0);
else
while (frac >= heightmask)
frac -= heightmask;
do
{
// Re-map color indices from wall texture column
// using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix
idx = frac>>FRACBITS;
if (idx >= 0 && idx < dc_postlength)
*dest = colormap[source[idx]];
dest += vid.width;
// Avoid overflow.
if (fracstep > 0x7FFFFFFF - frac)
frac += fracstep - heightmask;
else
frac += fracstep;
while (frac >= heightmask)
frac -= heightmask;
} while (--count);
}
else
{
while ((count -= 2) >= 0) // texture height is a power of 2
{
idx = (frac>>FRACBITS) & heightmask;
if (idx >= 0 && idx < dc_postlength)
*dest = colormap[source[idx]];
dest += vid.width;
frac += fracstep;
idx = (frac>>FRACBITS) & heightmask;
if (idx >= 0 && idx < dc_postlength)
*dest = colormap[source[idx]];
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
idx = (frac>>FRACBITS) & heightmask;
if (idx >= 0 && idx < dc_postlength)
*dest = colormap[source[idx]];
}
}
}
}
/** \brief The R_DrawShadeColumn_8 function
Experiment to make software go faster. Taken from the Boom source
*/
@ -212,6 +304,90 @@ void R_DrawTranslucentColumn_8(void)
}
}
/** \brief The R_DrawTranslucentColumnClamped_8 function
Same as R_DrawTranslucentColumn_8, but prevents artifacts from showing up (caused by fixed-point imprecisions)
*/
void R_DrawTranslucentColumnClamped_8(void)
{
INT32 count;
UINT8 *dest;
fixed_t frac, fracstep;
count = dc_yh - dc_yl + 1;
if (count <= 0) // Zero length, column does not exceed a pixel.
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
I_Error("R_DrawTranslucentColumnClamped_8: %d to %d at %d", dc_yl, dc_yh, dc_x);
#endif
dest = &topleft[dc_yl*vid.width + dc_x];
// Looks familiar.
fracstep = dc_iscale;
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
{
const UINT8 *source = dc_source;
const UINT8 *transmap = dc_transmap;
const lighttable_t *colormap = dc_colormap;
INT32 heightmask = dc_texheight - 1;
INT32 idx;
if (dc_texheight & heightmask)
{
heightmask++;
heightmask <<= FRACBITS;
if (frac < 0)
while ((frac += heightmask) < 0)
;
else
while (frac >= heightmask)
frac -= heightmask;
do
{
// Re-map color indices from wall texture column
// using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix
idx = frac>>FRACBITS;
if (idx >= 0 && idx < dc_postlength)
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
dest += vid.width;
if ((frac += fracstep) >= heightmask)
frac -= heightmask;
}
while (--count);
}
else
{
while ((count -= 2) >= 0) // texture height is a power of 2
{
idx = (frac>>FRACBITS)&heightmask;
if (idx >= 0 && idx < dc_postlength)
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
idx = (frac>>FRACBITS)&heightmask;
if (idx >= 0 && idx < dc_postlength)
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
idx = (frac>>FRACBITS)&heightmask;
if (idx >= 0 && idx < dc_postlength)
*dest = *(transmap + (colormap[source[idx]]<<8) + (*dest));
}
}
}
}
// Hack: A cut-down copy of R_DrawTranslucentColumn_8 that does not read texture
// data since something about calculating the texture reading address for drop shadows is broken.
// dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly

View file

@ -515,6 +515,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
fixed_t wall_scalex, wall_scaley;
UINT8 vertflip;
unsigned lengthcol;
boolean fog = false;
boolean fuzzy = false;
void (*colfunc_2s) (column_t *, unsigned);
@ -528,8 +530,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector;
sidedef = R_GetFFloorSide(curline, pfloor);
colfunc = colfuncs[BASEDRAWFUNC];
if (pfloor->master->flags & ML_TFERLINE)
{
line_t *newline = R_GetFFloorLine(curline, pfloor);
@ -547,7 +547,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (pfloor->fofflags & FOF_TRANSLUCENT)
{
boolean fuzzy = true;
fuzzy = true;
// Hacked up support for alpha value in software mode Tails 09-24-2002
// ...unhacked by toaster 04-01-2021, re-hacked a little by sphere 19-11-2021
@ -560,17 +560,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else if (!(dc_transmap = R_GetTranslucencyTable(trans)) || trans == 0)
fuzzy = false; // Opaque
}
if (fuzzy)
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
}
else if (pfloor->fofflags & FOF_FOG)
{
colfunc = colfuncs[COLDRAWFUNC_FOG];
fog = true;
}
range = max(ds->x2-ds->x1, 1);
//SoM: Moved these up here so they are available for my lightlist calculations
rw_scalestep = ds->scalestep;
spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
dc_numlights = 0;
if (frontsector->numlights)
@ -673,9 +670,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// Get correct light level!
if ((frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
else if (pfloor->fofflags & FOF_FOG)
else if (fog)
lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT);
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
else if (fuzzy)
lightnum = LIGHTLEVELS-1;
else
lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false)
@ -703,6 +700,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
vertflip = !vertflip;
}
//SoM: Moved these up here so they are available for my lightlist calculations
// Lactozilla: Moved them back down
// This uses floating point math now, because the fixed-point imprecisions
// become more severe the bigger the texture is scaled.
double dwall_scaley = FixedToDouble(wall_scaley);
double scalestep = FixedToDouble(ds->scalestep) / dwall_scaley;
double yscale = (FixedToDouble(ds->scale1) + (x1 - ds->x1)*scalestep) / dwall_scaley;
thicksidecol = ffloortexturecolumn;
wall_offsetx = ds->offsetx + sidedef->offsetx_mid;
@ -824,15 +829,41 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
rlight->botheight += rlight->botheightstep;
}
}
spryscale += rw_scalestep;
yscale += scalestep;
continue;
}
dc_iscale = FixedMul(0xffffffffu / (unsigned)spryscale, wall_scaley);
// Get data for the column
col = R_GetColumn(texnum, ((thicksidecol[dc_x] + wall_offsetx) >> FRACBITS));
spryscale = DoubleToFixed(yscale);
// Eh. I tried fixing the scaling artifacts but it still wasn't perfect.
// So this checks if the column has gaps in it or not, and if it does, uses a version of the column drawers
// that prevents the artifacts from being visible.
// Note that if rendering fog then none of this matters because there's no texture mapping to be done
if (!fog)
{
dc_iscale = 0xffffffffu / (unsigned)spryscale;
// Column has a single post and it matches the texture height, use regular column drawers
if (col->num_posts == 1 && col->posts[0].topdelta == 0 && col->posts[0].length == (unsigned)dc_texheight)
{
if (fuzzy)
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
else
colfunc = colfuncs[BASEDRAWFUNC];
}
else
{
// Otherwise use column drawers with extra checks
if (fuzzy)
colfunc = R_DrawTranslucentColumnClamped_8;
else
colfunc = R_DrawColumnClamped_8;
}
}
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack.
if (dc_numlights)
@ -947,7 +978,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (windowtop < windowbottom)
colfunc_2s (col, lengthcol);
spryscale += rw_scalestep;
yscale += scalestep;
continue;
}
@ -966,7 +997,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// draw the texture
colfunc_2s (col, lengthcol);
spryscale += rw_scalestep;
yscale += scalestep;
}
colfunc = colfuncs[BASEDRAWFUNC];

View file

@ -839,8 +839,10 @@ void R_DrawMaskedColumn(column_t *column, unsigned lengthcol)
{
post_t *post = &column->posts[i];
dc_postlength = post->length;
INT32 topscreen = sprtopscreen + spryscale*post->topdelta;
INT32 bottomscreen = topscreen + spryscale*post->length;
INT32 bottomscreen = topscreen + spryscale*dc_postlength;
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
@ -909,10 +911,12 @@ void R_DrawFlippedMaskedColumn(column_t *column, unsigned lengthcol)
if (!post->length)
continue;
topdelta = lengthcol-post->length-post->topdelta;
dc_postlength = post->length;
topdelta = lengthcol-dc_postlength-post->topdelta;
topscreen = sprtopscreen + spryscale*topdelta;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length
: sprbotscreen + spryscale*post->length;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*dc_postlength
: sprbotscreen + spryscale*dc_postlength;
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;