Fix slope planes not being able to render fog

This commit is contained in:
Jaime Ita Passos 2021-10-12 14:10:48 -03:00
parent 923e6f31aa
commit 5db4bff19c
7 changed files with 173 additions and 154 deletions

View file

@ -883,6 +883,39 @@ void R_DrawViewBorder(void)
}
#endif
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static INT32 tiltlighting[MAXVIDWIDTH];
static void R_CalcTiltedLighting(fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 left = ds_x1, right = ds_x2;
fixed_t step = (end-start)/(ds_x2-ds_x1+1);
INT32 i;
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++) {
tiltlighting[i] = (start += step) >> FRACBITS;
if (tiltlighting[i] < 0)
tiltlighting[i] = 0;
else if (tiltlighting[i] >= MAXLIGHTSCALE)
tiltlighting[i] = MAXLIGHTSCALE-1;
}
}
// Lighting is simple. It's just linear interpolation from start to end
#define CALC_SLOPE_LIGHT { \
float planelightfloat = PLANELIGHTFLOAT; \
float lightstart, lightend; \
lightend = (iz + ds_szp->x*width) * planelightfloat; \
lightstart = iz * planelightfloat; \
R_CalcTiltedLighting(FloatToFixed(lightstart), FloatToFixed(lightend)); \
}
// ==========================================================================
// INCLUDE 8bpp DRAWING CODE HERE
// ==========================================================================

View file

@ -193,13 +193,11 @@ void R_DrawTranslucentFloorSprite_8(void);
void R_DrawTiltedFloorSprite_8(void);
void R_DrawTiltedTranslucentFloorSprite_8(void);
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
extern INT32 tiltlighting[MAXVIDWIDTH];
void R_DrawTranslucentWaterSpan_8(void);
void R_DrawTiltedTranslucentWaterSpan_8(void);
void R_DrawFogSpan_8(void);
void R_DrawTiltedFogSpan_8(void);
// Lactozilla: Non-powers-of-two
void R_DrawSpan_NPO2_8(void);

View file

@ -623,29 +623,6 @@ void R_DrawSpan_8 (void)
}
}
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
INT32 tiltlighting[MAXVIDWIDTH];
void R_CalcTiltedLighting(fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 left = ds_x1, right = ds_x2;
fixed_t step = (end-start)/(ds_x2-ds_x1+1);
INT32 i;
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++) {
tiltlighting[i] = (start += step) >> FRACBITS;
if (tiltlighting[i] < 0)
tiltlighting[i] = 0;
else if (tiltlighting[i] >= MAXLIGHTSCALE)
tiltlighting[i] = MAXLIGHTSCALE-1;
}
}
/** \brief The R_DrawTiltedSpan_8 function
Draw slopes! Holy sheit!
*/
@ -668,17 +645,7 @@ void R_DrawTiltedSpan_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
@ -801,17 +768,7 @@ void R_DrawTiltedTranslucentSpan_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
@ -934,17 +891,7 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
@ -1066,17 +1013,7 @@ void R_DrawTiltedSplat_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
@ -2034,6 +1971,27 @@ void R_DrawFogSpan_8(void)
}
}
/** \brief The R_DrawTiltedFogSpan_8 function
Draws a tilted span with fogging.
*/
void R_DrawTiltedFogSpan_8(void)
{
int width = ds_x2 - ds_x1;
UINT8 *dest = ylookup[ds_y] + columnofs[ds_x1];
double iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
CALC_SLOPE_LIGHT
do
{
UINT8 *colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*dest];
dest++;
} while (--width >= 0);
}
/** \brief The R_DrawFogColumn_8 function
Fog wall.
*/

View file

@ -111,17 +111,7 @@ void R_DrawTiltedSpan_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
@ -311,17 +301,7 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
@ -509,17 +489,7 @@ void R_DrawTiltedSplat_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
@ -1427,17 +1397,7 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void)
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = PLANELIGHTFLOAT;
float lightstart, lightend;
lightend = (iz + ds_szp->x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
CALC_SLOPE_LIGHT
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);

View file

@ -262,6 +262,61 @@ static void R_MapTiltedPlane(INT32 y, INT32 x1, INT32 x2)
spanfunc();
}
static void R_MapFogPlane(INT32 y, INT32 x1, INT32 x2)
{
fixed_t distance;
size_t pindex;
#ifdef RANGECHECK
if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight)
I_Error("R_MapFogPlane: %d, %d at %d", x1, x2, y);
#endif
if (x1 >= vid.width)
x1 = vid.width - 1;
if (planeheight != cachedheight[y])
distance = FixedMul(planeheight, yslope[y]);
else
distance = cacheddistance[y];
pindex = distance >> LIGHTZSHIFT;
if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1;
ds_colormap = planezlight[pindex];
if (currentplane->extra_colormap)
ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps);
ds_y = y;
ds_x1 = x1;
ds_x2 = x2;
spanfunc();
}
static void R_MapTiltedFogPlane(INT32 y, INT32 x1, INT32 x2)
{
#ifdef RANGECHECK
if (x2 < x1 || x1 < 0 || x2 >= viewwidth || y > viewheight)
I_Error("R_MapTiltedFogPlane: %d, %d at %d", x1, x2, y);
#endif
if (x1 >= vid.width)
x1 = vid.width - 1;
if (currentplane->extra_colormap)
ds_colormap = currentplane->extra_colormap->colormap;
else
ds_colormap = colormaps;
ds_y = y;
ds_x1 = x1;
ds_x2 = x2;
spanfunc();
}
void R_ClearFFloorClips (void)
{
INT32 i, p;
@ -791,11 +846,11 @@ static inline void R_AdjustSlopeCoordinatesNPO2(vector3_t *origin)
void R_DrawSinglePlane(visplane_t *pl)
{
levelflat_t *levelflat;
INT32 light = 0;
INT32 x, stop;
ffloor_t *rover;
INT32 type, spanfunctype = BASEDRAWFUNC;
boolean fog = false;
INT32 spanfunctype = BASEDRAWFUNC;
void (*mapfunc)(INT32, INT32, INT32) = R_MapPlane;
if (!(pl->minx <= pl->maxx))
@ -885,6 +940,7 @@ void R_DrawSinglePlane(visplane_t *pl)
}
else if (pl->ffloor->flags & FF_FOG)
{
fog = true;
spanfunctype = SPANDRAWFUNC_FOG;
light = (pl->lightlevel >> LIGHTSEGSHIFT);
}
@ -892,28 +948,28 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->ffloor->flags & FF_RIPPLE)
{
INT32 top, bottom;
planeripple.active = true;
if (spanfunctype == SPANDRAWFUNC_TRANS)
{
spanfunctype = SPANDRAWFUNC_WATER;
// Copy the current scene, ugh
top = pl->high-8;
bottom = pl->low+8;
INT32 top = pl->high-8;
INT32 bottom = pl->low+8;
if (top < 0)
top = 0;
if (bottom > vid.height)
bottom = vid.height;
spanfunctype = SPANDRAWFUNC_WATER;
// Only copy the part of the screen we need
VID_BlitLinearScreen((splitscreen && viewplayer == &players[secondarydisplayplayer]) ? screens[0] + (top+(vid.height>>1))*vid.width : screens[0]+((top)*vid.width), screens[1]+((top)*vid.width),
vid.width, bottom-top,
vid.width, vid.width);
}
else if (fog)
planeripple.active = false;
}
}
else
@ -921,35 +977,40 @@ void R_DrawSinglePlane(visplane_t *pl)
}
currentplane = pl;
levelflat = &levelflats[pl->picnum];
/* :james: */
type = levelflat->type;
switch (type)
if (!fog)
{
case LEVELFLAT_NONE:
return;
case LEVELFLAT_FLAT:
ds_source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum);
R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum));
// Raw flats always have dimensions that are powers-of-two numbers.
ds_powersoftwo = true;
break;
default:
ds_source = (UINT8 *)R_GetLevelFlat(levelflat);
if (!ds_source)
levelflat_t *levelflat = &levelflats[pl->picnum];
/* :james: */
switch (levelflat->type)
{
case LEVELFLAT_NONE:
return;
// Check if this texture or patch has power-of-two dimensions.
if (R_CheckPowersOfTwo())
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
}
case LEVELFLAT_FLAT:
ds_source = (UINT8 *)R_GetFlat(levelflat->u.flat.lumpnum);
R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum));
// Raw flats always have dimensions that are powers-of-two numbers.
ds_powersoftwo = true;
break;
default:
ds_source = (UINT8 *)R_GetLevelFlat(levelflat);
if (!ds_source)
return;
// Check if this texture or patch has power-of-two dimensions.
if (R_CheckPowersOfTwo())
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
}
if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later
&& viewangle != pl->viewangle+pl->plangle)
{
memset(cachedheight, 0, sizeof (cachedheight));
viewangle = pl->viewangle+pl->plangle;
if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later
&& viewangle != pl->viewangle+pl->plangle)
{
memset(cachedheight, 0, sizeof (cachedheight));
viewangle = pl->viewangle+pl->plangle;
}
}
else
mapfunc = R_MapFogPlane;
xoffs = pl->xoffs;
yoffs = pl->yoffs;
@ -962,14 +1023,19 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->slope)
{
mapfunc = R_MapTiltedPlane;
if (!pl->plangle)
if (fog)
mapfunc = R_MapTiltedFogPlane;
else
{
if (ds_powersoftwo)
R_AdjustSlopeCoordinates(&pl->slope->o);
else
R_AdjustSlopeCoordinatesNPO2(&pl->slope->o);
mapfunc = R_MapTiltedPlane;
if (!pl->plangle)
{
if (ds_powersoftwo)
R_AdjustSlopeCoordinates(&pl->slope->o);
else
R_AdjustSlopeCoordinatesNPO2(&pl->slope->o);
}
}
if (planeripple.active)
@ -999,6 +1065,9 @@ void R_DrawSinglePlane(visplane_t *pl)
case SPANDRAWFUNC_SPLAT:
spanfunctype = SPANDRAWFUNC_TILTEDSPLAT;
break;
case SPANDRAWFUNC_FOG:
spanfunctype = SPANDRAWFUNC_TILTEDFOG;
break;
default:
spanfunctype = SPANDRAWFUNC_TILTED;
break;

View file

@ -139,6 +139,7 @@ void SCR_SetDrawFuncs(void)
spanfuncs[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_8;
spanfuncs[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_8;
spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8;
spanfuncs[SPANDRAWFUNC_TILTEDFOG] = R_DrawTiltedFogSpan_8;
// Lactozilla: Non-powers-of-two
spanfuncs_npo2[BASEDRAWFUNC] = R_DrawSpan_NPO2_8;
@ -154,7 +155,6 @@ void SCR_SetDrawFuncs(void)
spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed
#ifdef RUSEASM
if (R_ASM)

View file

@ -156,6 +156,7 @@ enum
SPANDRAWFUNC_TILTEDWATER,
SPANDRAWFUNC_FOG,
SPANDRAWFUNC_TILTEDFOG,
SPANDRAWFUNC_MAX
};