Tilted water

This commit is contained in:
Jaime Passos 2019-12-10 17:01:19 -03:00
parent 2d68eac528
commit f51253a0a8
4 changed files with 397 additions and 130 deletions

View file

@ -107,7 +107,8 @@ UINT8 *ds_transmap; // one of the translucency tables
#ifdef ESLOPE
pslope_t *ds_slope; // Current slope being used
floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
floatv3_t ds_su[MAXVIDHEIGHT], ds_sv[MAXVIDHEIGHT], ds_sz[MAXVIDHEIGHT]; // Vectors for... stuff?
floatv3_t *ds_sup, *ds_svp, *ds_szp;
float focallengthf, zeroheight;
#endif

View file

@ -68,7 +68,8 @@ typedef struct {
} floatv3_t;
extern pslope_t *ds_slope; // Current slope being used
extern floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
extern floatv3_t ds_su[MAXVIDHEIGHT], ds_sv[MAXVIDHEIGHT], ds_sz[MAXVIDHEIGHT]; // Vectors for... stuff?
extern floatv3_t *ds_sup, *ds_svp, *ds_szp;
extern float focallengthf, zeroheight;
#endif
@ -163,6 +164,9 @@ void R_DrawSpan_8(void);
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
void R_DrawTiltedSpan_8(void);
void R_DrawTiltedTranslucentSpan_8(void);
#ifndef NOWATER
void R_DrawTiltedTranslucentWaterSpan_8(void);
#endif
void R_DrawTiltedSplat_8(void);
#endif
void R_DrawSplat_8(void);

View file

@ -692,22 +692,22 @@ void R_DrawTiltedSpan_8(void)
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
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 = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
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);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
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);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
@ -743,9 +743,9 @@ void R_DrawTiltedSpan_8(void)
else
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
@ -755,9 +755,9 @@ void R_DrawTiltedSpan_8(void)
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
@ -833,9 +833,9 @@ void R_DrawTiltedSpan_8(void)
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;
@ -896,22 +896,22 @@ void R_DrawTiltedTranslucentSpan_8(void)
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
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 = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
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);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
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);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
@ -946,9 +946,9 @@ void R_DrawTiltedTranslucentSpan_8(void)
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest);
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
@ -958,9 +958,9 @@ void R_DrawTiltedTranslucentSpan_8(void)
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
@ -1036,9 +1036,9 @@ void R_DrawTiltedTranslucentSpan_8(void)
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;
@ -1079,6 +1079,213 @@ void R_DrawTiltedTranslucentSpan_8(void)
#endif
}
#ifndef NOWATER
/** \brief The R_DrawTiltedTranslucentWaterSpan_8 function
Like DrawTiltedTranslucentSpan, but for water
*/
void R_DrawTiltedTranslucentWaterSpan_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
UINT8 *dsrc;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
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 = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
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);
}
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);
dest = ylookup[ds_y] + columnofs[ds_x1];
dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1;
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
dest++;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
}
else
{
double left = width;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
if (!ds_powersoftwo)
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
*dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++);
}
else
*dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++);
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
#endif // NOWATER
void R_DrawTiltedSplat_8(void)
{
// x1, x2 = ds_x1, ds_x2
@ -1098,22 +1305,22 @@ void R_DrawTiltedSplat_8(void)
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
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 = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
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);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
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);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
@ -1153,9 +1360,9 @@ void R_DrawTiltedSplat_8(void)
*dest = colormap[val];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
iz += ds_szp->x;
uz += ds_sup->x;
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
@ -1165,9 +1372,9 @@ void R_DrawTiltedSplat_8(void)
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
@ -1247,9 +1454,9 @@ void R_DrawTiltedSplat_8(void)
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;

View file

@ -190,6 +190,15 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
ds_xfrac += FixedMul(FINECOSINE(angle), (ds_bgofs<<FRACBITS));
ds_yfrac += FixedMul(FINESINE(angle), (ds_bgofs<<FRACBITS));
#ifdef ESLOPE
if (currentplane->slope)
{
ds_sup = &ds_su[y];
ds_svp = &ds_sv[y];
ds_szp = &ds_sz[y];
}
#endif
if (y+ds_bgofs>=viewheight)
ds_bgofs = viewheight-y-1;
if (y+ds_bgofs<0)
@ -833,6 +842,100 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo
return flat;
}
// Lactokaiju
#ifdef ESLOPE
static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge)
{
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
// I copied ZDoom's code and adapted it to SRB2... -Red
floatv3_t p, m, n;
float ang;
float vx, vy, vz;
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time
fixed_t temp;
vx = FIXED_TO_FLOAT(pl->viewx+xoffs);
vy = FIXED_TO_FLOAT(pl->viewy-yoffs);
vz = FIXED_TO_FLOAT(pl->viewz);
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
zeroheight = FIXED_TO_FLOAT(temp);
// p is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in
// errors if the flat is rotated.
ang = ANG2RAD(ANGLE_270 - pl->viewangle);
p.x = vx * cos(ang) - vy * sin(ang);
p.z = vx * sin(ang) + vy * cos(ang);
temp = P_GetZAt(pl->slope, -xoffs, yoffs);
p.y = FIXED_TO_FLOAT(temp) - vz;
// m is the v direction vector in view space
ang = ANG2RAD(ANGLE_180 - (pl->viewangle + pl->plangle));
m.x = cos(ang);
m.z = sin(ang);
// n is the u direction vector in view space
n.x = sin(ang);
n.z = -cos(ang);
ang = ANG2RAD(pl->plangle);
temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang)));
m.y = FIXED_TO_FLOAT(temp) - zeroheight;
temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight;
if (ds_powersoftwo)
{
m.x /= fudge;
m.y /= fudge;
m.z /= fudge;
n.x *= fudge;
n.y *= fudge;
n.z *= fudge;
}
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
#define CROSS(d, v1, v2) \
d.x = (v1.y * v2.z) - (v1.z * v2.y);\
d.y = (v1.z * v2.x) - (v1.x * v2.z);\
d.z = (v1.x * v2.y) - (v1.y * v2.x)
CROSS(ds_su[i], p, m);
CROSS(ds_sv[i], p, n);
CROSS(ds_sz[i], m, n);
#undef CROSS
ds_su[i].z *= focallengthf;
ds_sv[i].z *= focallengthf;
ds_sz[i].z *= focallengthf;
// Premultiply the texture vectors with the scale factors
#define SFMULT 65536.f
if (ds_powersoftwo)
{
ds_su[i].x *= (SFMULT * (1<<nflatshiftup));
ds_su[i].y *= (SFMULT * (1<<nflatshiftup));
ds_su[i].z *= (SFMULT * (1<<nflatshiftup));
ds_sv[i].x *= (SFMULT * (1<<nflatshiftup));
ds_sv[i].y *= (SFMULT * (1<<nflatshiftup));
ds_sv[i].z *= (SFMULT * (1<<nflatshiftup));
}
else
{
// I'm essentially multiplying the vectors by FRACUNIT...
ds_su[i].x *= SFMULT;
ds_su[i].y *= SFMULT;
ds_su[i].z *= SFMULT;
ds_sv[i].x *= SFMULT;
ds_sv[i].y *= SFMULT;
ds_sv[i].z *= SFMULT;
}
#undef SFMULT
}
#endif // ESLOPE
void R_DrawSinglePlane(visplane_t *pl)
{
UINT8 *flat;
@ -945,11 +1048,7 @@ void R_DrawSinglePlane(visplane_t *pl)
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE
#ifdef ESLOPE
&& !pl->slope
#endif
)
if (pl->ffloor->flags & FF_RIPPLE)
{
INT32 top, bottom;
@ -1045,25 +1144,18 @@ void R_DrawSinglePlane(visplane_t *pl)
light = 0;
#ifdef ESLOPE
if (pl->slope) {
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
// I copied ZDoom's code and adapted it to SRB2... -Red
floatv3_t p, m, n;
float ang;
float vx, vy, vz;
float fudge = 0;
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time
fixed_t temp;
if (pl->slope)
{
float fudgecanyon = 0;
angle_t hack = (pl->plangle & (ANGLE_90-1));
yoffs *= 1;
if (ds_powersoftwo)
{
fixed_t temp;
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
fudge = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
fudgecanyon = ((1<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
if (hack)
{
/*
@ -1105,89 +1197,52 @@ void R_DrawSinglePlane(visplane_t *pl)
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
}
xoffs = (fixed_t)(xoffs*fudge);
yoffs = (fixed_t)(yoffs/fudge);
xoffs = (fixed_t)(xoffs*fudgecanyon);
yoffs = (fixed_t)(yoffs/fudgecanyon);
}
vx = FIXED_TO_FLOAT(pl->viewx+xoffs);
vy = FIXED_TO_FLOAT(pl->viewy-yoffs);
vz = FIXED_TO_FLOAT(pl->viewz);
ds_sup = &ds_su[0];
ds_svp = &ds_sv[0];
ds_szp = &ds_sz[0];
temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy);
zeroheight = FIXED_TO_FLOAT(temp);
// p is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in
// errors if the flat is rotated.
ang = ANG2RAD(ANGLE_270 - pl->viewangle);
p.x = vx * cos(ang) - vy * sin(ang);
p.z = vx * sin(ang) + vy * cos(ang);
temp = P_GetZAt(pl->slope, -xoffs, yoffs);
p.y = FIXED_TO_FLOAT(temp) - vz;
// m is the v direction vector in view space
ang = ANG2RAD(ANGLE_180 - (pl->viewangle + pl->plangle));
m.x = cos(ang);
m.z = sin(ang);
// n is the u direction vector in view space
n.x = sin(ang);
n.z = -cos(ang);
ang = ANG2RAD(pl->plangle);
temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang)));
m.y = FIXED_TO_FLOAT(temp) - zeroheight;
temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight;
if (ds_powersoftwo)
#ifndef NOWATER
if (itswater)
{
m.x /= fudge;
m.y /= fudge;
m.z /= fudge;
INT32 i;
fixed_t rxoffs = xoffs;
fixed_t ryoffs = yoffs;
n.x *= fudge;
n.y *= fudge;
n.z *= fudge;
R_PlaneBounds(pl);
for (i = pl->high; i < pl->low; i++)
{
// Fuck it
fixed_t plheight = abs(P_GetZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz);
fixed_t distance = FixedMul(plheight, yslope[i]);
const INT32 yay = (wtofs + (distance>>9) ) & 8191;
// ripples da water texture
ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS;
angle = (pl->viewangle + pl->plangle)>>ANGLETOFINESHIFT;
angle = (angle + 2048) & 8191; // 90 degrees
xoffs = rxoffs + FixedMul(FINECOSINE(angle), (ds_bgofs<<FRACBITS));
yoffs = ryoffs + FixedMul(FINESINE(angle), (ds_bgofs<<FRACBITS));
R_SlopeVectors(pl, i, fudgecanyon);
}
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
#define CROSS(d, v1, v2) \
d.x = (v1.y * v2.z) - (v1.z * v2.y);\
d.y = (v1.z * v2.x) - (v1.x * v2.z);\
d.z = (v1.x * v2.y) - (v1.y * v2.x)
CROSS(ds_su, p, m);
CROSS(ds_sv, p, n);
CROSS(ds_sz, m, n);
#undef CROSS
ds_su.z *= focallengthf;
ds_sv.z *= focallengthf;
ds_sz.z *= focallengthf;
// Premultiply the texture vectors with the scale factors
#define SFMULT 65536.f
if (ds_powersoftwo)
{
ds_su.x *= (SFMULT * (1<<nflatshiftup));
ds_su.y *= (SFMULT * (1<<nflatshiftup));
ds_su.z *= (SFMULT * (1<<nflatshiftup));
ds_sv.x *= (SFMULT * (1<<nflatshiftup));
ds_sv.y *= (SFMULT * (1<<nflatshiftup));
ds_sv.z *= (SFMULT * (1<<nflatshiftup));
xoffs = rxoffs;
yoffs = ryoffs;
}
else
{
// I'm essentially multiplying the vectors by FRACUNIT...
ds_su.x *= SFMULT;
ds_su.y *= SFMULT;
ds_su.z *= SFMULT;
ds_sv.x *= SFMULT;
ds_sv.y *= SFMULT;
ds_sv.z *= SFMULT;
}
#undef SFMULT
#endif
R_SlopeVectors(pl, 0, fudgecanyon);
#ifndef NOWATER
if ((spanfunc == R_DrawTranslucentWaterSpan_8) || (spanfunc == R_DrawTranslucentSpan_8))
spanfunc = R_DrawTiltedTranslucentWaterSpan_8;
else
#endif
if (spanfunc == R_DrawTranslucentSpan_8)
spanfunc = R_DrawTiltedTranslucentSpan_8;
else if (spanfunc == splatfunc)