Merge branch 'floorsprite-fix' into 'next'

Fix #649

Closes #649

See merge request STJr/SRB2!1604
This commit is contained in:
Tatsuru 2021-09-11 15:00:14 +00:00
commit 8aee7fcbce
6 changed files with 68 additions and 166 deletions

View file

@ -89,8 +89,6 @@ static fixed_t planeheight;
fixed_t yslopetab[MAXVIDHEIGHT*16];
fixed_t *yslope;
fixed_t basexscale, baseyscale;
fixed_t cachedheight[MAXVIDHEIGHT];
fixed_t cacheddistance[MAXVIDHEIGHT];
fixed_t cachedxstep[MAXVIDHEIGHT];
@ -114,7 +112,7 @@ void R_InitPlanes(void)
// Sets planeripple.xfrac and planeripple.yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted.
//
struct
static struct
{
INT32 offset;
fixed_t xfrac, yfrac;
@ -143,15 +141,6 @@ static void R_UpdatePlaneRipple(void)
planeripple.offset = (leveltime * 140);
}
//
// R_MapPlane
//
// Uses global vars:
// planeheight
// basexscale
// baseyscale
// centerx
static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
{
angle_t angle, planecos, planesin;
@ -176,16 +165,13 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
cacheddistance[y] = distance = FixedMul(planeheight, yslope[y]);
span = abs(centery - y);
if (span) // don't divide by zero
if (span) // Don't divide by zero
{
ds_xstep = FixedMul(planesin, planeheight) / span;
ds_ystep = FixedMul(planecos, planeheight) / span;
}
else
{
ds_xstep = FixedMul(distance, basexscale);
ds_ystep = FixedMul(distance, baseyscale);
}
ds_xstep = ds_ystep = FRACUNIT;
cachedxstep[y] = ds_xstep;
cachedystep[y] = ds_ystep;
@ -197,6 +183,11 @@ static void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
ds_ystep = cachedystep[y];
}
// [RH] Instead of using the xtoviewangle array, I calculated the fractional values
// at the middle of the screen, then used the calculated ds_xstep and ds_ystep
// to step from those to the proper texture coordinate to start drawing at.
// That way, the texture coordinate is always calculated by its position
// on the screen and not by its position relative to the edge of the visplane.
ds_xfrac = xoffs + FixedMul(planecos, distance) + (x1 - centerx) * ds_xstep;
ds_yfrac = yoffs - FixedMul(planesin, distance) + (x1 - centerx) * ds_ystep;
@ -295,7 +286,6 @@ void R_ClearFFloorClips (void)
void R_ClearPlanes(void)
{
INT32 i, p;
angle_t angle;
// opening / clipping determination
for (i = 0; i < viewwidth; i++)
@ -321,13 +311,6 @@ void R_ClearPlanes(void)
// texture calculation
memset(cachedheight, 0, sizeof (cachedheight));
// left to right mapping
angle = (viewangle-ANGLE_90)>>ANGLETOFINESHIFT;
// scale will be unit scale at SCREENWIDTH/2 distance
basexscale = FixedDiv (FINECOSINE(angle),centerxfrac);
baseyscale = -FixedDiv (FINESINE(angle),centerxfrac);
}
static visplane_t *new_visplane(unsigned hash)
@ -532,53 +515,22 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
//
// R_ExpandPlane
//
// This function basically expands the visplane or I_Errors.
// This function basically expands the visplane.
// The reason for this is that when creating 3D floor planes, there is no
// need to create new ones with R_CheckPlane, because 3D floor planes
// are created by subsector and there is no way a subsector can graphically
// overlap.
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop)
{
// INT32 unionl, unionh;
// INT32 x;
// Don't expand polyobject planes here - we do that on our own.
if (pl->polyobj)
return;
if (pl->minx > start) pl->minx = start;
if (pl->maxx < stop) pl->maxx = stop;
/*
if (start < pl->minx)
{
unionl = start;
}
else
{
unionl = pl->minx;
}
if (stop > pl->maxx)
{
unionh = stop;
}
else
{
unionh = pl->maxx;
}
for (x = start; x <= stop; x++)
if (pl->top[x] != 0xffff || pl->bottom[x] != 0x0000)
break;
if (x <= stop)
I_Error("R_ExpandPlane: planes in same subsector overlap?!\nminx: %d, maxx: %d, start: %d, stop: %d\n", pl->minx, pl->maxx, start, stop);
pl->minx = unionl, pl->maxx = unionh;
*/
}
static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
static void R_MakeSpans(void (*mapfunc)(INT32, INT32, INT32), INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
{
// Alam: from r_splats's R_RasterizeFloorSplat
if (t1 >= vid.height) t1 = vid.height-1;
@ -589,38 +541,12 @@ static void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
while (t1 < t2 && t1 <= b1)
{
R_MapPlane(t1, spanstart[t1], x - 1);
mapfunc(t1, spanstart[t1], x - 1);
t1++;
}
while (b1 > b2 && b1 >= t1)
{
R_MapPlane(b1, spanstart[b1], x - 1);
b1--;
}
while (t2 < t1 && t2 <= b2)
spanstart[t2++] = x;
while (b2 > b1 && b2 >= t2)
spanstart[b2--] = x;
}
static void R_MakeTiltedSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2)
{
// Alam: from r_splats's R_RasterizeFloorSplat
if (t1 >= vid.height) t1 = vid.height-1;
if (b1 >= vid.height) b1 = vid.height-1;
if (t2 >= vid.height) t2 = vid.height-1;
if (b2 >= vid.height) b2 = vid.height-1;
if (x-1 >= vid.width) x = vid.width;
while (t1 < t2 && t1 <= b1)
{
R_MapTiltedPlane(t1, spanstart[t1], x - 1);
t1++;
}
while (b1 > b2 && b1 >= t1)
{
R_MapTiltedPlane(b1, spanstart[b1], x - 1);
mapfunc(b1, spanstart[b1], x - 1);
b1--;
}
@ -867,11 +793,10 @@ void R_DrawSinglePlane(visplane_t *pl)
{
levelflat_t *levelflat;
INT32 light = 0;
INT32 x;
INT32 stop, angle;
INT32 x, stop;
ffloor_t *rover;
INT32 type;
INT32 spanfunctype = BASEDRAWFUNC;
INT32 type, spanfunctype = BASEDRAWFUNC;
void (*mapfunc)(INT32, INT32, INT32) = R_MapPlane;
if (!(pl->minx <= pl->maxx))
return;
@ -1023,9 +948,6 @@ void R_DrawSinglePlane(visplane_t *pl)
&& viewangle != pl->viewangle+pl->plangle)
{
memset(cachedheight, 0, sizeof (cachedheight));
angle = (pl->viewangle+pl->plangle-ANGLE_90)>>ANGLETOFINESHIFT;
basexscale = FixedDiv(FINECOSINE(angle),centerxfrac);
baseyscale = -FixedDiv(FINESINE(angle),centerxfrac);
viewangle = pl->viewangle+pl->plangle;
}
@ -1040,6 +962,8 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->slope)
{
mapfunc = R_MapTiltedPlane;
if (!pl->plangle)
{
if (ds_powersoftwo)
@ -1107,16 +1031,8 @@ void R_DrawSinglePlane(visplane_t *pl)
stop = pl->maxx + 1;
if (pl->slope)
{
for (x = pl->minx; x <= stop; x++)
R_MakeTiltedSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
}
else
{
for (x = pl->minx; x <= stop; x++)
R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
}
for (x = pl->minx; x <= stop; x++)
R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1], pl->top[x], pl->bottom[x]);
/*
QUINCUNX anti-aliasing technique (sort of)
@ -1183,7 +1099,7 @@ using the palette colors.
stop = pl->maxx + 1;
for (x = pl->minx; x <= stop; x++)
R_MakeSpans(x, pl->top[x-1], pl->bottom[x-1],
R_MakeSpans(mapfunc, x, pl->top[x-1], pl->bottom[x-1],
pl->top[x], pl->bottom[x]);
}
}

View file

@ -69,7 +69,6 @@ extern fixed_t cachedheight[MAXVIDHEIGHT];
extern fixed_t cacheddistance[MAXVIDHEIGHT];
extern fixed_t cachedxstep[MAXVIDHEIGHT];
extern fixed_t cachedystep[MAXVIDHEIGHT];
extern fixed_t basexscale, baseyscale;
extern fixed_t *yslope;
extern lighttable_t **planezlight;

View file

@ -155,7 +155,6 @@ void R_DrawFloorSplat(vissprite_t *spr)
fixed_t xscale, yscale;
fixed_t xoffset, yoffset;
fixed_t leftoffset, topoffset;
pslope_t *slope = NULL;
INT32 i;
boolean hflip = (spr->xiscale < 0);
@ -188,7 +187,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
if (spr->rotateflags & SRF_3D || renderflags & RF_NOSPLATBILLBOARD)
splatangle = mobj->angle;
else
splatangle = spr->viewangle;
splatangle = spr->viewpoint.angle;
if (!(spr->cut & SC_ISROTATED))
splatangle += mobj->rollangle;
@ -218,7 +217,7 @@ void R_DrawFloorSplat(vissprite_t *spr)
splat.x = x;
splat.y = y;
splat.z = mobj->z;
splat.tilted = false;
splat.slope = NULL;
// Set positions
@ -238,9 +237,9 @@ void R_DrawFloorSplat(vissprite_t *spr)
splat.verts[3].x = w - xoffset;
splat.verts[3].y = -h + yoffset;
angle = -splat.angle;
ca = FINECOSINE(angle>>ANGLETOFINESHIFT);
sa = FINESINE(angle>>ANGLETOFINESHIFT);
angle = -splat.angle>>ANGLETOFINESHIFT;
ca = FINECOSINE(angle);
sa = FINESINE(angle);
// Rotate
for (i = 0; i < 4; i++)
@ -255,36 +254,10 @@ void R_DrawFloorSplat(vissprite_t *spr)
// The slope that was defined for the sprite.
if (renderflags & RF_SLOPESPLAT)
slope = mobj->floorspriteslope;
splat.slope = mobj->floorspriteslope;
if (standingslope && (renderflags & RF_OBJECTSLOPESPLAT))
slope = standingslope;
// Set splat as tilted
splat.tilted = (slope != NULL);
}
if (splat.tilted)
{
pslope_t *s = &splat.slope;
s->o.x = slope->o.x;
s->o.y = slope->o.y;
s->o.z = slope->o.z;
s->d.x = slope->d.x;
s->d.y = slope->d.y;
s->normal.x = slope->normal.x;
s->normal.y = slope->normal.y;
s->normal.z = slope->normal.z;
s->zdelta = slope->zdelta;
s->zangle = slope->zangle;
s->xydirection = slope->xydirection;
s->next = NULL;
s->flags = 0;
splat.slope = standingslope;
}
// Translate
@ -293,9 +266,9 @@ void R_DrawFloorSplat(vissprite_t *spr)
tr_x = rotated[i].x + x;
tr_y = rotated[i].y + y;
if (slope)
if (splat.slope)
{
rot_z = P_GetSlopeZAt(slope, tr_x, tr_y);
rot_z = P_GetSlopeZAt(splat.slope, tr_x, tr_y);
splat.verts[i].z = rot_z;
}
else
@ -305,18 +278,23 @@ void R_DrawFloorSplat(vissprite_t *spr)
splat.verts[i].y = tr_y;
}
angle = spr->viewpoint.angle >> ANGLETOFINESHIFT;
ca = FINECOSINE(angle);
sa = FINESINE(angle);
// Project
for (i = 0; i < 4; i++)
{
v3d = &splat.verts[i];
// transform the origin point
tr_x = v3d->x - viewx;
tr_y = v3d->y - viewy;
tr_x = v3d->x - spr->viewpoint.x;
tr_y = v3d->y - spr->viewpoint.y;
// rotation around vertical y axis
rot_x = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos);
rot_y = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
rot_z = v3d->z - viewz;
rot_x = FixedMul(tr_x, sa) - FixedMul(tr_y, ca);
rot_y = FixedMul(tr_x, ca) + FixedMul(tr_y, sa);
rot_z = v3d->z - spr->viewpoint.z;
if (rot_y < FRACUNIT)
return;
@ -416,31 +394,32 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (R_CheckPowersOfTwo())
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
if (pSplat->tilted)
if (pSplat->slope)
{
R_SetTiltedSpan(0);
R_SetScaledSlopePlane(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewangle, pSplat->angle);
R_SetScaledSlopePlane(pSplat->slope, vis->viewpoint.x, vis->viewpoint.y, vis->viewpoint.z, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, vis->viewpoint.angle, pSplat->angle);
R_CalculateSlopeVectors();
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
}
else
{
planeheight = abs(pSplat->z - viewz);
planeheight = abs(pSplat->z - vis->viewpoint.z);
if (pSplat->angle)
{
// Add the view offset, rotated by the plane angle.
fixed_t a = -pSplat->verts[0].x + viewx;
fixed_t b = -pSplat->verts[0].y + viewy;
angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT);
offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b,FINESINE(angle));
offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b,FINECOSINE(angle));
memset(cachedheight, 0, sizeof(cachedheight));
// Add the view offset, rotated by the plane angle.
fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x;
fixed_t b = -pSplat->verts[0].y + vis->viewpoint.y;
angle_t angle = (pSplat->angle >> ANGLETOFINESHIFT);
offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b, FINESINE(angle));
offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b, FINECOSINE(angle));
}
else
{
offsetx = viewx - pSplat->verts[0].x;
offsety = pSplat->verts[0].y - viewy;
offsetx = vis->viewpoint.x - pSplat->verts[0].x;
offsety = pSplat->verts[0].y - vis->viewpoint.y;
}
}
@ -461,7 +440,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
{
ds_transmap = vis->transmap;
if (pSplat->tilted)
if (pSplat->slope)
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
else
spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
@ -528,12 +507,12 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (x2 < x1)
continue;
if (!pSplat->tilted)
if (!pSplat->slope)
{
fixed_t xstep, ystep;
fixed_t distance, span;
angle_t angle = (vis->viewangle + pSplat->angle)>>ANGLETOFINESHIFT;
angle_t angle = (vis->viewpoint.angle + pSplat->angle)>>ANGLETOFINESHIFT;
angle_t planecos = FINECOSINE(angle);
angle_t planesin = FINESINE(angle);
@ -577,7 +556,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
rastertab[y].maxx = INT32_MIN;
}
if (pSplat->angle && !pSplat->tilted)
if (pSplat->angle && !pSplat->slope)
memset(cachedheight, 0, sizeof(cachedheight));
}

View file

@ -34,8 +34,7 @@ typedef struct floorsplat_s
INT32 width, height;
fixed_t scale, xscale, yscale;
angle_t angle;
boolean tilted; // Uses the tilted drawer
pslope_t slope;
pslope_t *slope;
vector3_t verts[4]; // (x,y,z) as viewed from above on map
fixed_t x, y, z; // position

View file

@ -1957,9 +1957,12 @@ static void R_ProjectSprite(mobj_t *thing)
vis->paperoffset = paperoffset;
vis->paperdistance = paperdistance;
vis->centerangle = centerangle;
vis->viewangle = viewangle;
vis->shear.tan = sheartan;
vis->shear.offset = 0;
vis->viewpoint.x = viewx;
vis->viewpoint.y = viewy;
vis->viewpoint.z = viewz;
vis->viewpoint.angle = viewangle;
vis->mobj = thing; // Easy access! Tails 06-07-2002

View file

@ -164,7 +164,12 @@ typedef struct vissprite_s
fixed_t xiscale; // negative if flipped
angle_t centerangle; // for paper sprites
angle_t viewangle; // for floor sprites, the viewpoint's current angle
// for floor sprites
struct {
fixed_t x, y, z; // the viewpoint's current position
angle_t angle; // the viewpoint's current angle
} viewpoint;
struct {
fixed_t tan; // The amount to shear the sprite vertically per row
@ -185,9 +190,10 @@ typedef struct vissprite_s
extracolormap_t *extra_colormap; // global colormaps
// Precalculated top and bottom screen coords for the sprite.
fixed_t thingheight; // The actual height of the thing (for 3D floors)
sector_t *sector; // The sector containing the thing.
// Precalculated top and bottom screen coords for the sprite.
INT16 sz, szt;
spritecut_e cut;