diff --git a/src/r_draw.c b/src/r_draw.c index db64805a4..ec53d79fc 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -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 diff --git a/src/r_draw.h b/src/r_draw.h index d033f221d..392eb3827 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -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); diff --git a/src/r_draw8.c b/src/r_draw8.c index 11cdd5dca..609ce6d5c 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -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; diff --git a/src/r_plane.c b/src/r_plane.c index f96e7950e..97a4ca9f8 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -190,6 +190,15 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_xfrac += FixedMul(FINECOSINE(angle), (ds_bgofs<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<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<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); - // 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 + 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; - ds_su.z *= focallengthf; - ds_sv.z *= focallengthf; - ds_sz.z *= focallengthf; + angle = (angle + 2048) & 8191; // 90 degrees + xoffs = rxoffs + FixedMul(FINECOSINE(angle), (ds_bgofs<