diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 794cf6add..8e10a4fdd 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,12 @@ +May 21, 2008 +- Fixed: When R_DrawTiltedPlane() calculates the p vector, it can overflow + if the view is near the bounds of the fixed point coordinate system. This + happens because it rotates the view position around (0,0) according to + the current viewangle, so the resultant coordinate may be outside the + bounds of fixed point. All important math in this function is now done + entirely in floating point. +- Fixed: Slopes didn't draw right on 64-bit platforms. + May 20, 2008 - Fixed: With hardware 2D, the console and menu need not reimplement palette flashes to ensure their visibility. diff --git a/src/mscinlines.h b/src/mscinlines.h index 9e14668ab..e432e4259 100644 --- a/src/mscinlines.h +++ b/src/mscinlines.h @@ -343,7 +343,7 @@ __forceinline SDWORD ksgn (SDWORD a) __forceinline int toint (float v) { - QWORD res; + SQWORD res; __asm fld v; __asm fistp res; return (int)res; @@ -351,7 +351,7 @@ __forceinline int toint (float v) __forceinline int quickertoint (float v) { - DWORD res; + SDWORD res; __asm fld v; __asm fistp res; return (int)res; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d4b172d91..ad17ec949 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2552,7 +2552,6 @@ void AActor::Tick () } else { - AInventory * item = Inventory; // Handle powerup effects here so that the order is controlled diff --git a/src/r_defs.h b/src/r_defs.h index bd86106a9..7e61c1c33 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -140,6 +140,12 @@ struct secplane_t return FixedMul (ic, -d - DMulScale16 (a, x, b, y)); } + // Returns the value of z at (x,y) as a double + double ZatPoint (double x, double y) const + { + return (d + a*x + b*y) * ic / (-65536.0 * 65536.0); + } + // Returns the value of z at vertex v fixed_t ZatPoint (const vertex_t *v) const { diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 419107e38..d34783f75 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -315,7 +315,7 @@ void R_MapTiltedPlane (int y, int x1) { int x2 = spanend[y]; int width = x2 - x1; - float iz, uz, vz; + double iz, uz, vz; BYTE *fb; DWORD u, v; int i; @@ -344,10 +344,10 @@ void R_MapTiltedPlane (int y, int x1) i = 0; do { - float z = 1.f/iz; + double z = 1.f/iz; - u = toint (uz*z) + pviewx; - v = toint (vz*z) + pviewy; + u = SQWORD(uz*z) + pviewx; + v = SQWORD(vz*z) + pviewy; ds_colormap = tiltlighting[i]; fb[i++] = ds_colormap[ds_source[(v >> vshift) | ((u >> ushift) & umask)]]; iz += plane_sz[0]; @@ -362,10 +362,10 @@ void R_MapTiltedPlane (int y, int x1) #define SPANSIZE 16 #define INVSPAN 0.0625f - float startz = 1.f/iz; - float startu = uz*startz; - float startv = vz*startz; - float izstep, uzstep, vzstep; + double startz = 1.f/iz; + double startu = uz*startz; + double startv = vz*startz; + double izstep, uzstep, vzstep; izstep = plane_sz[0] * SPANSIZE; uzstep = plane_su[0] * SPANSIZE; @@ -379,13 +379,13 @@ void R_MapTiltedPlane (int y, int x1) uz += uzstep; vz += vzstep; - float endz = 1.f/iz; - float endu = uz*endz; - float endv = vz*endz; - DWORD stepu = toint ((endu - startu) * INVSPAN); - DWORD stepv = toint ((endv - startv) * INVSPAN); - u = toint (startu) + pviewx; - v = toint (startv) + pviewy; + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + DWORD stepu = SQWORD((endu - startu) * INVSPAN); + DWORD stepv = SQWORD((endv - startv) * INVSPAN); + u = SQWORD(startu) + pviewx; + v = SQWORD(startv) + pviewy; for (i = SPANSIZE-1; i >= 0; i--) { @@ -403,25 +403,25 @@ void R_MapTiltedPlane (int y, int x1) { if (width == 1) { - u = toint (startu); - v = toint (startv); + u = SQWORD(startu); + v = SQWORD(startv); fb[x1] = *(tiltlighting[x1] + ds_source[(v >> vshift) | ((u >> ushift) & umask)]); } else { - float left = (float)width; + double left = width; iz += plane_sz[0] * left; uz += plane_su[0] * left; vz += plane_sv[0] * left; - float endz = 1.f/iz; - float endu = uz*endz; - float endv = vz*endz; + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; left = 1.f/left; - DWORD stepu = toint ((endu - startu) * left); - DWORD stepv = toint ((endv - startv) * left); - u = toint (startu) + pviewx; - v = toint (startv) + pviewy; + DWORD stepu = SQWORD((endu - startu) * left); + DWORD stepv = SQWORD((endv - startv) * left); + u = SQWORD(startu) + pviewx; + v = SQWORD(startv) + pviewy; for (; width != 0; width--) { @@ -1447,66 +1447,59 @@ void R_DrawTiltedPlane (visplane_t *pl, fixed_t alpha, bool masked) /*, 0.0009765625f, 0.00048828125f, 0.000244140625f, 1.220703125e-4f, 6.103515625e-5, 3.0517578125e-5*/ }; - float lxscale, lyscale; - float xscale, yscale; - fixed_t ixscale, iyscale; - angle_t ang; + double lxscale, lyscale; + double xscale, yscale; FVector3 p, m, n; - fixed_t zeroheight; + double ang; + double zeroheight; if (alpha <= 0) { return; } - // 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. + double vx = FIXED2FLOAT(viewx); + double vy = FIXED2FLOAT(viewy); + double vz = FIXED2FLOAT(viewz); lxscale = FIXED2FLOAT(pl->xscale) * ifloatpow2[ds_xbits]; lyscale = FIXED2FLOAT(pl->yscale) * ifloatpow2[ds_ybits]; xscale = 64.f / lxscale; yscale = 64.f / lyscale; - ixscale = quickertoint(xscale*65536.f); - iyscale = quickertoint(yscale*65536.f); - zeroheight = pl->height.ZatPoint (viewx, viewy); + zeroheight = pl->height.ZatPoint(vx, vy); pviewx = MulScale (pl->xoffs, pl->xscale, ds_xbits); pviewy = MulScale (pl->yoffs, pl->yscale, ds_ybits); - ang = (ANG270 - viewangle) >> ANGLETOFINESHIFT; -// Printf ("%u %d %d\n", ang, finecosine[ang], finesine[ang]); - p[0] = FIXED2FLOAT(DMulScale16 (viewx, finecosine[ang], -viewy, finesine[ang])); - p[2] = FIXED2FLOAT(DMulScale16 (viewx, finesine[ang], viewy, finecosine[ang])); -// double dang = 1.5*M_PI - double(viewangle)*M_PI/2147483648.0; -// double vx = viewx/65536.0, vy = viewy/65536.0; -// double dcos = cos(dang), dsin = sin(dang); -// p[0] = vx * dcos - vy * dsin; -// p[2] = vx * dsin + vy * dcos; - p[1] = FIXED2FLOAT(pl->height.ZatPoint (0, 0) - viewz); + // 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 = bam2rad(ANG270 - viewangle); + p[0] = vx * cos(ang) - vy * sin(ang); + p[2] = vx * sin(ang) + vy * cos(ang); + p[1] = pl->height.ZatPoint(0.0, 0.0) - vz; // m is the v direction vector in view space - ang = (ANG180 - viewangle - pl->angle) >> ANGLETOFINESHIFT; - m[0] = yscale * FIXED2FLOAT(finecosine[ang]); - m[2] = yscale * FIXED2FLOAT(finesine[ang]); + ang = bam2rad(ANG180 - viewangle - pl->angle); + m[0] = yscale * cos(ang); + m[2] = yscale * sin(ang); // m[1] = FIXED2FLOAT(pl->height.ZatPoint (0, iyscale) - pl->height.ZatPoint (0,0)); // VectorScale2 (m, 64.f/VectorLength(m)); // n is the u direction vector in view space - ang = (ang + (ANG90>>ANGLETOFINESHIFT)) & FINEMASK; - n[0] = -xscale * FIXED2FLOAT(finecosine[ang]); - n[2] = -xscale * FIXED2FLOAT(finesine[ang]); + ang += PI/2; + n[0] = -xscale * cos(ang); + n[2] = -xscale * sin(ang); // n[1] = FIXED2FLOAT(pl->height.ZatPoint (ixscale, 0) - pl->height.ZatPoint (0,0)); // VectorScale2 (n, 64.f/VectorLength(n)); - ang = pl->angle >> ANGLETOFINESHIFT; - m[1] = FIXED2FLOAT(pl->height.ZatPoint ( - viewx + MulScale16 (iyscale, finesine[ang]), - viewy + MulScale16 (iyscale, finecosine[ang])) - zeroheight); - ang = (pl->angle + ANGLE_90) >> ANGLETOFINESHIFT; - n[1] = FIXED2FLOAT(pl->height.ZatPoint ( - viewx + MulScale16 (ixscale, finesine[ang]), - viewy + MulScale16 (ixscale, finecosine[ang])) - zeroheight); + // This code keeps the texture coordinates constant across the x,y plane no matter + // how much you slope the surface. Use the commented-out code above instead to keep + // the textures a constant size across the surface's plane instead. + ang = bam2rad(pl->angle); + m[1] = pl->height.ZatPoint(vx + yscale * sin(ang), vy + yscale * cos(ang)) - zeroheight; + ang += PI/2; + n[1] = pl->height.ZatPoint(vx + xscale * sin(ang), vy + xscale * cos(ang)) - zeroheight; plane_su = p ^ m; plane_sv = p ^ n; diff --git a/src/tables.h b/src/tables.h index 6e916729e..2f5008b4d 100644 --- a/src/tables.h +++ b/src/tables.h @@ -120,4 +120,9 @@ inline int SlopeDiv (unsigned int num, unsigned den) return ans <= SLOPERANGE ? ans : SLOPERANGE; } +inline double bam2rad(angle_t ang) +{ + return double(ang >> 1) * (PI / ANGLE_90); +} + #endif // __TABLES_H__ diff --git a/zdoom.sln b/zdoom.sln index dc02af2dc..49310e6d6 100644 --- a/zdoom.sln +++ b/zdoom.sln @@ -57,16 +57,16 @@ Global {8049475B-5C87-46F9-9358-635218A4EF18}.Debug|x64.Build.0 = Debug|x64 {8049475B-5C87-46F9-9358-635218A4EF18}.Release|Win32.ActiveCfg = Release|Win32 {8049475B-5C87-46F9-9358-635218A4EF18}.Release|Win32.Build.0 = Release|Win32 - {8049475B-5C87-46F9-9358-635218A4EF18}.Release|x64.ActiveCfg = Release|x64 - {8049475B-5C87-46F9-9358-635218A4EF18}.Release|x64.Build.0 = Release|x64 + {8049475B-5C87-46F9-9358-635218A4EF18}.Release|x64.ActiveCfg = Debug|x64 + {8049475B-5C87-46F9-9358-635218A4EF18}.Release|x64.Build.0 = Debug|x64 {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Debug|Win32.ActiveCfg = Debug|Win32 {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Debug|Win32.Build.0 = Debug|Win32 {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Debug|x64.ActiveCfg = Debug|x64 {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Debug|x64.Build.0 = Debug|x64 {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Release|Win32.ActiveCfg = Release|Win32 {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Release|Win32.Build.0 = Release|Win32 - {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Release|x64.ActiveCfg = Release|x64 - {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Release|x64.Build.0 = Release|x64 + {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Release|x64.ActiveCfg = Debug|x64 + {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}.Release|x64.Build.0 = Debug|x64 {0F80ACBF-460E-44F0-B28E-B3272D1774A7}.Debug|Win32.ActiveCfg = Debug|Win32 {0F80ACBF-460E-44F0-B28E-B3272D1774A7}.Debug|Win32.Build.0 = Debug|Win32 {0F80ACBF-460E-44F0-B28E-B3272D1774A7}.Debug|x64.ActiveCfg = Release|Win32 @@ -113,32 +113,27 @@ Global {6077B7D6-349F-4077-B552-3BC302EF5859}.Debug|x64.Build.0 = Debug|x64 {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|Win32.ActiveCfg = Release|Win32 {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|Win32.Build.0 = Release|Win32 - {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.ActiveCfg = Release|x64 - {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.Build.0 = Release|x64 + {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.ActiveCfg = Debug|x64 + {6077B7D6-349F-4077-B552-3BC302EF5859}.Release|x64.Build.0 = Debug|x64 {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Debug|Win32.ActiveCfg = Debug|Win32 {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Debug|Win32.Build.0 = Debug|Win32 {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Debug|x64.ActiveCfg = Debug|x64 - {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Debug|x64.Build.0 = Debug|x64 {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|Win32.ActiveCfg = Release|Win32 {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|Win32.Build.0 = Release|Win32 - {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|x64.ActiveCfg = Release|x64 - {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|x64.Build.0 = Release|x64 + {AC3F5340-40CB-4C3A-8AA7-CB7158DB4466}.Release|x64.ActiveCfg = Debug|x64 {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Debug|Win32.ActiveCfg = Debug|Win32 {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Debug|Win32.Build.0 = Debug|Win32 {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Debug|x64.ActiveCfg = Debug|Win32 - {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Debug|x64.Build.0 = Debug|Win32 {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Release|Win32.ActiveCfg = Release|Win32 {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Release|Win32.Build.0 = Release|Win32 {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Release|x64.ActiveCfg = Release|Win32 - {DA47396F-60C1-4BDE-A977-7F7DE461CF77}.Release|x64.Build.0 = Release|Win32 {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Debug|Win32.ActiveCfg = Release|Win32 {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Debug|Win32.Build.0 = Release|Win32 - {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Debug|x64.ActiveCfg = Release|x64 - {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Debug|x64.Build.0 = Release|x64 + {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Debug|x64.ActiveCfg = Debug|x64 + {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Debug|x64.Build.0 = Debug|x64 {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Release|Win32.ActiveCfg = Release|Win32 {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Release|Win32.Build.0 = Release|Win32 - {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Release|x64.ActiveCfg = Release|x64 - {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Release|x64.Build.0 = Release|x64 + {E83FD370-2E72-4D4C-9427-FF9D9DED1E88}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE