diff --git a/src/r_bsp.h b/src/r_bsp.h index 4c5f5f6119..ba302c6866 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -66,13 +66,13 @@ struct drawseg_t { seg_t* curline; float light, lightstep; - fixed_t iscale, iscalestep; + float iscale, iscalestep; short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg short sx1, sx2; // left, right of parent seg on screen float sz1, sz2; // z for left, right of parent seg on screen float siz1, siz2; // 1/z for left, right of parent seg on screen float cx, cy, cdx, cdy; - fixed_t yrepeat; + float yscale; BYTE silhouette; // 0=none, 1=bottom, 2=top, 3=both BYTE bFogBoundary; BYTE bFakeBoundary; // for fake walls diff --git a/src/r_draw.cpp b/src/r_draw.cpp index a25770ebdb..c581759123 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -86,6 +86,7 @@ void (*rt_map4cols)(int,int,int); // R_DrawColumn // Source is the top of the column to scale. // +double dc_texturemid; extern "C" { int dc_pitch=0xABadCafe; // [RH] Distance between rows @@ -94,7 +95,6 @@ int dc_x; int dc_yl; int dc_yh; fixed_t dc_iscale; -fixed_t dc_texturemid; fixed_t dc_texturefrac; int dc_color; // [RH] Color for column filler DWORD dc_srccolor; diff --git a/src/r_draw.h b/src/r_draw.h index 80dc77768b..72b51dfa4d 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -34,7 +34,7 @@ extern "C" int dc_x; extern "C" int dc_yl; extern "C" int dc_yh; extern "C" fixed_t dc_iscale; -extern "C" fixed_t dc_texturemid; +extern double dc_texturemid; extern "C" fixed_t dc_texturefrac; extern "C" int dc_color; // [RH] For flat colors (no texturing) extern "C" DWORD dc_srccolor; diff --git a/src/r_drawt.cpp b/src/r_drawt.cpp index d4b9d5f1e6..e8faff0ceb 100644 --- a/src/r_drawt.cpp +++ b/src/r_drawt.cpp @@ -1108,14 +1108,15 @@ void R_FillColumnHorizP (void) void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span) { + const fixed_t texturemid = FLOAT2FIXED(dc_texturemid); while (span->Length != 0) { const int length = span->Length; const int top = span->TopOffset; // calculate unclipped screen coordinates for post - dc_yl = (sprtopscreen + spryscale * top) >> FRACBITS; - dc_yh = (sprtopscreen + spryscale * (top + length) - FRACUNIT) >> FRACBITS; + dc_yl = xs_RoundToInt(sprtopscreen + spryscale * top); + dc_yh = xs_RoundToInt(sprtopscreen + spryscale * (top + length) - 1); if (sprflipvert) { @@ -1136,7 +1137,7 @@ void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span) if (sprflipvert) { dc_texturefrac = (dc_yl*dc_iscale) - (top << FRACBITS) - - fixed_t(CenterY * dc_iscale) - dc_texturemid; + - fixed_t(CenterY * dc_iscale) - texturemid; const fixed_t maxfrac = length << FRACBITS; while (dc_texturefrac >= maxfrac) { @@ -1154,7 +1155,7 @@ void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span) } else { - dc_texturefrac = dc_texturemid - (top << FRACBITS) + dc_texturefrac = texturemid - (top << FRACBITS) + (dc_yl*dc_iscale) - fixed_t((CenterY-1) * dc_iscale); while (dc_texturefrac < 0) { diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 9390249cbb..40fbba1f50 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -842,11 +842,11 @@ inline void R_MakeSpans (int x, int t1, int b1, int t2, int b2, void (*mapfunc)( static FTexture *frontskytex, *backskytex; static angle_t skyflip; static int frontpos, backpos; -static fixed_t frontyScale; +static double frontyScale; static fixed_t frontcyl, backcyl; -static fixed_t skymid; +static double skymid; static angle_t skyangle; -int frontiScale; +static double frontiScale; extern fixed_t swall[MAXWIDTH]; extern fixed_t lwall[MAXWIDTH]; @@ -947,8 +947,8 @@ static void R_DrawSky (visplane_t *pl) rw_pic = frontskytex; rw_offset = 0; - frontyScale = FLOAT2FIXED(rw_pic->Scale.Y); - dc_texturemid = MulScale16 (skymid, frontyScale); + frontyScale = rw_pic->Scale.Y; + dc_texturemid = skymid * frontyScale; if (1 << frontskytex->HeightBits == frontskytex->GetHeight()) { // The texture tiles nicely @@ -957,19 +957,19 @@ static void R_DrawSky (visplane_t *pl) lastskycol[x] = 0xffffffff; } wallscan (pl->left, pl->right, (short *)pl->top, (short *)pl->bottom, swall, lwall, - frontyScale, backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); + FLOAT2FIXED(frontyScale), backskytex == NULL ? R_GetOneSkyColumn : R_GetTwoSkyColumns); } else { // The texture does not tile nicely - frontyScale = DivScale16 (skyscale, frontyScale); - frontiScale = DivScale32 (1, frontyScale); + frontyScale *= skyscale; + frontiScale = 1 / frontyScale; // Sodding crap. Fixed point sucks when you want precision. // TODO (if I'm feeling adventurous): Rewrite the renderer to use floating point // coordinates to keep as much precision as possible until the final // rasterization stage so fudges like this aren't needed. if (viewheight <= 600) { - skymid -= FRACUNIT; + skymid -= 1; } R_DrawSkyStriped (pl); } @@ -977,22 +977,18 @@ static void R_DrawSky (visplane_t *pl) static void R_DrawSkyStriped (visplane_t *pl) { - double centerysave = CenterY; - short drawheight = (short)MulScale16 (frontskytex->GetHeight(), frontyScale); - fixed_t topfrac; - fixed_t iscale = frontiScale; + short drawheight = short(frontskytex->GetHeight() * frontyScale); + double topfrac; + double iscale = frontiScale; short top[MAXWIDTH], bot[MAXWIDTH]; short yl, yh; int x; - // So that I don't have to worry about fractional precision, chop off the - // fractional part of centeryfrac. - CenterY = centery; - topfrac = (skymid + iscale * (1-centery)) % (frontskytex->GetHeight() << FRACBITS); - if (topfrac < 0) topfrac += frontskytex->GetHeight() << FRACBITS; + topfrac = fmod(skymid + iscale * (1 - CenterY), frontskytex->GetHeight()); + if (topfrac < 0) topfrac += frontskytex->GetHeight(); yl = 0; - yh = (short)MulScale32 ((frontskytex->GetHeight() << FRACBITS) - topfrac, frontyScale); - dc_texturemid = topfrac - iscale * (1-centery); + yh = short((frontskytex->GetHeight() - topfrac) * frontyScale); + dc_texturemid = topfrac - iscale * (1 - CenterY); fixed_t yScale = FLOAT2FIXED(rw_pic->Scale.Y); while (yl < viewheight) @@ -1012,7 +1008,6 @@ static void R_DrawSkyStriped (visplane_t *pl) yh += drawheight; dc_texturemid = iscale * (centery-yl-1); } - CenterY = centerysave; } //========================================================================== @@ -1461,7 +1456,7 @@ void R_DrawSkyPlane (visplane_t *pl) skyangle += s->GetTextureXOffset(pos); // Vertical offset allows careful sky positioning. - skymid = s->GetTextureYOffset(pos) - 28*FRACUNIT; + skymid = s->GetTextureYOffsetF(pos) - 28; // We sometimes flip the picture horizontally. // @@ -1474,7 +1469,7 @@ void R_DrawSkyPlane (visplane_t *pl) frontcyl = MAX(frontskytex->GetWidth(), frontxscale); if (skystretch) { - skymid = Scale(skymid, frontskytex->GetScaledHeight(), SKYSTRETCH_HEIGHT); + skymid = skymid * frontskytex->GetScaledHeightDouble() / SKYSTRETCH_HEIGHT; } } } diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 9ffd82b8b1..c979a6b87d 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -119,10 +119,10 @@ static double rw_frontlowertop; static int rw_x; static int rw_stopx; fixed_t rw_offset; -static fixed_t rw_scalestep; -static fixed_t rw_midtexturemid; -static fixed_t rw_toptexturemid; -static fixed_t rw_bottomtexturemid; +static double rw_scalestep; +static double rw_midtexturemid; +static double rw_toptexturemid; +static double rw_bottomtexturemid; static double rw_midtexturescalex; static double rw_midtexturescaley; static double rw_toptexturescalex; @@ -170,7 +170,7 @@ CVAR(Bool, r_drawmirrors, true, 0) // R_RenderMaskedSegRange // fixed_t *MaskedSWall; -fixed_t MaskedScaleY; +double MaskedScaleY; static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FTexture::Span *spans), FTexture *tex) { @@ -180,11 +180,11 @@ static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FText dc_colormap = basecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } - dc_iscale = MulScale18 (MaskedSWall[dc_x], MaskedScaleY); + dc_iscale = xs_RoundToInt(MaskedSWall[dc_x] * MaskedScaleY); if (sprflipvert) - sprtopscreen = FLOAT2FIXED(CenterY) + FixedMul(dc_texturemid, spryscale); + sprtopscreen = CenterY + dc_texturemid * spryscale; else - sprtopscreen = FLOAT2FIXED(CenterY) - FixedMul(dc_texturemid, spryscale); + sprtopscreen = CenterY - dc_texturemid * spryscale; // killough 1/25/98: here's where Medusa came in, because // it implicitly assumed that the column was all one patch. @@ -230,7 +230,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) sector_t tempsec; // killough 4/13/98 double texheight, texheightscale; bool notrelevant = false; - fixed_t rowoffset; + double rowoffset; const sector_t *sec; @@ -306,7 +306,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } MaskedSWall = (fixed_t *)(openings + ds->swall) - ds->x1; - MaskedScaleY = ds->yrepeat; + MaskedScaleY = ds->yscale; maskedtexturecol = (fixed_t *)(openings + ds->maskedtexturecol) - ds->x1; spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1); rw_scalestep = ds->iscalestep; @@ -325,14 +325,14 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } if (curline->linedef->flags & ML_DONTPEGBOTTOM) { - dc_texturemid = FLOAT2FIXED(MAX(frontsector->GetPlaneTexZF(sector_t::floor), backsector->GetPlaneTexZF(sector_t::floor)) + texheight); + dc_texturemid = MAX(frontsector->GetPlaneTexZF(sector_t::floor), backsector->GetPlaneTexZF(sector_t::floor)) + texheight; } else { - dc_texturemid = FLOAT2FIXED(MIN(frontsector->GetPlaneTexZF(sector_t::ceiling), backsector->GetPlaneTexZF(sector_t::ceiling))); + dc_texturemid = MIN(frontsector->GetPlaneTexZF(sector_t::ceiling), backsector->GetPlaneTexZF(sector_t::ceiling)); } - rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid); + rowoffset = curline->sidedef->GetTextureYOffsetF(side_t::mid); if (!(curline->linedef->flags & ML_WRAP_MIDTEX) && !(curline->sidedef->Flags & WALLF_WRAP_MIDTEX)) @@ -346,18 +346,18 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } if (tex->bWorldPanning) { - // rowoffset is added before the MulScale3 so that the masked texture will + // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. - dc_texturemid += rowoffset - FLOAT2FIXED(ViewPos.Z); - textop = FIXED2FLOAT(dc_texturemid); - dc_texturemid = MulScale16 (dc_texturemid, MaskedScaleY); + dc_texturemid += rowoffset - ViewPos.Z; + textop = dc_texturemid; + dc_texturemid *= MaskedScaleY; } else { // rowoffset is added outside the multiply so that it positions the texture // by texels instead of world units. - textop = FIXED2FLOAT(dc_texturemid + SafeDivScale16 (rowoffset, MaskedScaleY)) - ViewPos.Z; - dc_texturemid = MulScale16 (dc_texturemid - FLOAT2FIXED(ViewPos.Z), MaskedScaleY) + rowoffset; + textop = dc_texturemid + rowoffset / MaskedScaleY - ViewPos.Z; + dc_texturemid = (dc_texturemid - ViewPos.Z) * MaskedScaleY + rowoffset; } if (sprflipvert) { @@ -433,6 +433,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) mfloorclip = walllower; mceilingclip = wallupper; + MaskedScaleY /= 4; // [RH] Wish I could remember why this needs to be done // draw the columns one at a time if (drawmode == DoDraw0) @@ -480,16 +481,15 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) { // Texture does wrap vertically. if (tex->bWorldPanning) { - // rowoffset is added before the MulScale3 so that the masked texture will + // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. - dc_texturemid += rowoffset - FLOAT2FIXED(ViewPos.Z); - dc_texturemid = MulScale16 (dc_texturemid, MaskedScaleY); + dc_texturemid = (dc_texturemid + rowoffset - ViewPos.Z) * MaskedScaleY; } else { // rowoffset is added outside the multiply so that it positions the texture // by texels instead of world units. - dc_texturemid = MulScale16 (dc_texturemid - FLOAT2FIXED(ViewPos.Z), MaskedScaleY) + rowoffset; + dc_texturemid = (dc_texturemid - ViewPos.Z) * MaskedScaleY + rowoffset; } WallC.sz1 = ds->sz1; @@ -531,7 +531,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) rw_offset = 0; rw_pic = tex; - wallscan_np2_ds(ds, x1, x2, mceilingclip, mfloorclip, MaskedSWall, maskedtexturecol, ds->yrepeat); + wallscan_np2_ds(ds, x1, x2, mceilingclip, mfloorclip, MaskedSWall, maskedtexturecol, FLOAT2FIXED(ds->yscale)); } clearfog: @@ -601,23 +601,23 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) scaledpart = side_t::mid; } xscale = fixed_t(rw_pic->Scale.X * scaledside->GetTextureXScale(scaledpart)); - yscale = rw_pic->Scale.Y * scaledside->GetTextureYScale(scaledpart); + yscale = rw_pic->Scale.Y * scaledside->GetTextureYScaleF(scaledpart); - fixed_t rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid); + double rowoffset = curline->sidedef->GetTextureYOffsetF(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffsetF(side_t::mid); double planez = rover->model->GetPlaneTexZF(sector_t::ceiling); rw_offset = curline->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid); if (rowoffset < 0) { - rowoffset += rw_pic->GetHeight() << FRACBITS; + rowoffset += rw_pic->GetHeight(); } - dc_texturemid = FLOAT2FIXED((planez - ViewPos.Z) * yscale); + dc_texturemid = (planez - ViewPos.Z) * yscale; if (rw_pic->bWorldPanning) { - // rowoffset is added before the MulScale3 so that the masked texture will + // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. - dc_texturemid += xs_FloorToInt(rowoffset * yscale); - rw_offset = MulScale16 (rw_offset, xscale); ///Is this really supposed to be xscale and not yscale? + dc_texturemid = dc_texturemid + rowoffset * yscale; + rw_offset = MulScale16 (rw_offset, xscale); } else { @@ -1101,7 +1101,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t shiftval = rw_pic->HeightBits; setupvline (32-shiftval); yrepeat >>= 2 + shiftval; - texturemid = dc_texturemid << (16 - shiftval); + texturemid = xs_ToFixed(32 - shiftval, dc_texturemid); xoffset = rw_offset; basecolormapdata = basecolormap->Maps; fixed_t centeryfrac = FLOAT2FIXED(CenterY); @@ -1317,32 +1317,33 @@ static void call_wallscan(int x1, int x2, short *uwal, short *dwal, fixed_t *swa // //============================================================================= -void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t *lwal, fixed_t yrepeat, fixed_t itop, fixed_t ibot, bool mask) +void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t *lwal, fixed_t yrep, fixed_t itop, fixed_t ibot, bool mask) { if (!r_np2) { - call_wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, mask); + call_wallscan(x1, x2, uwal, dwal, swal, lwal, yrep, mask); } else { short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH]; short *up, *down; - fixed_t texheight = rw_pic->GetHeight() << FRACBITS; - double scaledtexheight = FIXED2FLOAT(FixedDiv(texheight, yrepeat)); + double texheight = rw_pic->GetHeight(); double partition; double top = FIXED2FLOAT(itop); double bot = FIXED2FLOAT(ibot); + double yrepeat = FIXED2FLOAT(yrep); + double scaledtexheight = texheight / yrepeat; if (yrepeat >= 0) { // normal orientation: draw strips from top to bottom - partition = top - fmod(top - FIXED2FLOAT(FixedDiv(dc_texturemid, yrepeat)) - ViewPos.Z, scaledtexheight); + partition = top - fmod(top - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight); if (partition == top) { partition -= scaledtexheight; } up = uwal; down = most1; - dc_texturemid = xs_RoundToInt((partition - ViewPos.Z) * yrepeat + texheight); + dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight; while (partition > bot) { int j = OWallMost(most3, partition - ViewPos.Z, &WallC); @@ -1352,21 +1353,21 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed { down[j] = clamp(most3[j], up[j], dwal[j]); } - call_wallscan(x1, x2, up, down, swal, lwal, yrepeat, mask); + call_wallscan(x1, x2, up, down, swal, lwal, yrep, mask); up = down; down = (down == most1) ? most2 : most1; } partition -= scaledtexheight; dc_texturemid -= texheight; } - call_wallscan(x1, x2, up, dwal, swal, lwal, yrepeat, mask); + call_wallscan(x1, x2, up, dwal, swal, lwal, yrep, mask); } else { // upside down: draw strips from bottom to top - partition = bot - fmod(bot - FIXED2FLOAT(FixedDiv(dc_texturemid, yrepeat)) - ViewPos.Z, scaledtexheight); + partition = bot - fmod(bot - dc_texturemid / yrepeat - ViewPos.Z, scaledtexheight); up = most1; down = dwal; - dc_texturemid = xs_RoundToInt((partition - ViewPos.Z) * yrepeat + texheight); + dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight; while (partition < top) { int j = OWallMost(most3, partition - ViewPos.Z, &WallC); @@ -1376,14 +1377,14 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed { up[j] = clamp(most3[j], uwal[j], down[j]); } - call_wallscan(x1, x2, up, down, swal, lwal, yrepeat, mask); + call_wallscan(x1, x2, up, down, swal, lwal, yrep, mask); down = up; up = (up == most1) ? most2 : most1; } partition -= scaledtexheight; dc_texturemid -= texheight; } - call_wallscan(x1, x2, uwal, down, swal, lwal, yrepeat, mask); + call_wallscan(x1, x2, uwal, down, swal, lwal, yrep, mask); } } } @@ -1454,7 +1455,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixe shiftval = rw_pic->HeightBits; setupmvline (32-shiftval); yrepeat >>= 2 + shiftval; - texturemid = dc_texturemid << (16 - shiftval); + texturemid = xs_ToFixed(32 - shiftval, dc_texturemid); xoffset = rw_offset; basecolormapdata = basecolormap->Maps; fixed_t centeryfrac = FLOAT2FIXED(CenterY); @@ -1628,7 +1629,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, shiftval = rw_pic->HeightBits; setuptmvline (32-shiftval); yrepeat >>= 2 + shiftval; - texturemid = dc_texturemid << (16 - shiftval); + texturemid = xs_ToFixed(32 - shiftval, dc_texturemid); xoffset = rw_offset; basecolormapdata = basecolormap->Maps; fixed_t centeryfrac = FLOAT2FIXED(CenterY); @@ -1997,7 +1998,7 @@ void R_RenderSegLoop () void R_NewWall (bool needlights) { - fixed_t rowoffset; + double rowoffset; double yrepeat; rw_markportal = false; @@ -2026,7 +2027,7 @@ void R_NewWall (bool needlights) { midtexture = TexMan(sidedef->GetTexture(side_t::mid), true); rw_offset_mid = sidedef->GetTextureXOffset(side_t::mid); - rowoffset = sidedef->GetTextureYOffset(side_t::mid); + rowoffset = sidedef->GetTextureYOffsetF(side_t::mid); rw_midtexturescalex = FIXED2DBL(sidedef->GetTextureXScale(side_t::mid)); rw_midtexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::mid)); yrepeat = midtexture->Scale.Y * rw_midtexturescaley; @@ -2034,14 +2035,14 @@ void R_NewWall (bool needlights) { // normal orientation if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom - rw_midtexturemid = FLOAT2FIXED((frontsector->GetPlaneTexZF(sector_t::floor) - ViewPos.Z) * yrepeat + midtexture->GetHeight()); + rw_midtexturemid = (frontsector->GetPlaneTexZF(sector_t::floor) - ViewPos.Z) * yrepeat + midtexture->GetHeight(); } else { // top of texture at top - rw_midtexturemid = FLOAT2FIXED((frontsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat); + rw_midtexturemid = (frontsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat; if (rowoffset < 0 && midtexture != NULL) { - rowoffset += midtexture->GetHeight() << FRACBITS; + rowoffset += midtexture->GetHeight(); } } } @@ -2050,16 +2051,16 @@ void R_NewWall (bool needlights) rowoffset = -rowoffset; if (linedef->flags & ML_DONTPEGBOTTOM) { // top of texture at bottom - rw_midtexturemid = FLOAT2FIXED((frontsector->GetPlaneTexZF(sector_t::floor) - ViewPos.Z) * yrepeat); + rw_midtexturemid = (frontsector->GetPlaneTexZF(sector_t::floor) - ViewPos.Z) * yrepeat; } else { // bottom of texture at top - rw_midtexturemid = FLOAT2FIXED((frontsector->GetPlaneTexZ(sector_t::ceiling) - ViewPos.Z) * yrepeat + midtexture->GetHeight()); + rw_midtexturemid = (frontsector->GetPlaneTexZ(sector_t::ceiling) - ViewPos.Z) * yrepeat + midtexture->GetHeight(); } } if (midtexture->bWorldPanning) { - rw_midtexturemid += xs_FloorToInt(rowoffset * yrepeat); + rw_midtexturemid += rowoffset * yrepeat; } else { @@ -2181,7 +2182,7 @@ void R_NewWall (bool needlights) toptexture = TexMan(sidedef->GetTexture(side_t::top), true); rw_offset_top = sidedef->GetTextureXOffset(side_t::top); - rowoffset = sidedef->GetTextureYOffset(side_t::top); + rowoffset = sidedef->GetTextureYOffsetF(side_t::top); rw_toptexturescalex = FIXED2DBL(sidedef->GetTextureXScale(side_t::top)); rw_toptexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::top)); yrepeat = toptexture->Scale.Y * rw_toptexturescaley; @@ -2189,15 +2190,15 @@ void R_NewWall (bool needlights) { // normal orientation if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top - rw_toptexturemid = FLOAT2FIXED((frontsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat); + rw_toptexturemid = (frontsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat; if (rowoffset < 0 && toptexture != NULL) { - rowoffset += toptexture->GetHeight() << FRACBITS; + rowoffset += toptexture->GetHeight(); } } else { // bottom of texture at bottom - rw_toptexturemid = FLOAT2FIXED((backsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat + toptexture->GetHeight()); + rw_toptexturemid = (backsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat + toptexture->GetHeight(); } } else @@ -2205,16 +2206,16 @@ void R_NewWall (bool needlights) rowoffset = -rowoffset; if (linedef->flags & ML_DONTPEGTOP) { // bottom of texture at top - rw_toptexturemid = FLOAT2FIXED((frontsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat + toptexture->GetHeight()); + rw_toptexturemid = (frontsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat + toptexture->GetHeight(); } else { // top of texture at bottom - rw_toptexturemid = FLOAT2FIXED((backsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat); + rw_toptexturemid = (backsector->GetPlaneTexZF(sector_t::ceiling) - ViewPos.Z) * yrepeat; } } if (toptexture->bWorldPanning) { - rw_toptexturemid += xs_FloorToInt(rowoffset * yrepeat); + rw_toptexturemid += rowoffset * yrepeat; } else { @@ -2226,7 +2227,7 @@ void R_NewWall (bool needlights) bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom), true); rw_offset_bottom = sidedef->GetTextureXOffset(side_t::bottom); - rowoffset = sidedef->GetTextureYOffset(side_t::bottom); + rowoffset = sidedef->GetTextureYOffsetF(side_t::bottom); rw_bottomtexturescalex = FIXED2DBL(sidedef->GetTextureXScale(side_t::bottom)); rw_bottomtexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::bottom)); yrepeat = fixed_t(bottomtexture->Scale.Y * rw_bottomtexturescaley); @@ -2234,14 +2235,14 @@ void R_NewWall (bool needlights) { // normal orientation if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom - rw_bottomtexturemid = FLOAT2FIXED((rw_frontlowertop - ViewPos.Z) * yrepeat); + rw_bottomtexturemid = (rw_frontlowertop - ViewPos.Z) * yrepeat; } else { // top of texture at top - rw_bottomtexturemid = FLOAT2FIXED((backsector->GetPlaneTexZF(sector_t::floor) - ViewPos.Z) * yrepeat); + rw_bottomtexturemid = (backsector->GetPlaneTexZF(sector_t::floor) - ViewPos.Z) * yrepeat; if (rowoffset < 0 && bottomtexture != NULL) { - rowoffset += bottomtexture->GetHeight() << FRACBITS; + rowoffset += bottomtexture->GetHeight(); } } } @@ -2250,16 +2251,16 @@ void R_NewWall (bool needlights) rowoffset = -rowoffset; if (linedef->flags & ML_DONTPEGBOTTOM) { // top of texture at bottom - rw_bottomtexturemid = FLOAT2FIXED((rw_frontlowertop - ViewPos.Z) * yrepeat); + rw_bottomtexturemid = (rw_frontlowertop - ViewPos.Z) * yrepeat; } else { // bottom of texture at top - rw_bottomtexturemid = FLOAT2FIXED((backsector->GetPlaneTexZ(sector_t::floor) - ViewPos.Z) * yrepeat + bottomtexture->GetHeight()); + rw_bottomtexturemid = (backsector->GetPlaneTexZ(sector_t::floor) - ViewPos.Z) * yrepeat + bottomtexture->GetHeight(); } } if (bottomtexture->bWorldPanning) { - rw_bottomtexturemid += xs_FloorToInt(rowoffset * yrepeat); + rw_bottomtexturemid += rowoffset * yrepeat; } else { @@ -2515,7 +2516,7 @@ void R_StoreWallRange (int start, int stop) lwal = (fixed_t *)(openings + ds_p->maskedtexturecol); swal = (fixed_t *)(openings + ds_p->swall); FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true); - fixed_t yrepeat = int(pic->Scale.X * sidedef->GetTextureYScale(side_t::mid)); + double yscale = pic->Scale.X * sidedef->GetTextureYScaleF(side_t::mid); fixed_t xoffset = sidedef->GetTextureXOffset(side_t::mid); if (pic->bWorldPanning) @@ -2529,20 +2530,23 @@ void R_StoreWallRange (int start, int stop) *swal++ = swall[i]; } - fixed_t istart = MulScale18 (*((fixed_t *)(openings + ds_p->swall)), yrepeat); - fixed_t iend = MulScale18 (*(swal - 1), yrepeat); - - if (istart < 3 && istart >= 0) istart = 3; - if (istart > -3 && istart < 0) istart = -3; - if (iend < 3 && iend >= 0) iend = 3; - if (iend > -3 && iend < 0) iend = -3; - istart = DivScale32 (1, istart); - iend = DivScale32 (1, iend); - ds_p->yrepeat = yrepeat; - ds_p->iscale = istart; + double istart = *((fixed_t *)(openings + ds_p->swall)) * yscale / (1 << 18); + double iend = *(swal - 1) * yscale / (1 << 18); +#if 0 + ///This was for avoiding overflow when using fixed point. It might not be needed anymore. + const double mini = 3 / 65536.0; + if (istart < mini && istart >= 0) istart = mini; + if (istart > -mini && istart < 0) istart = -mini; + if (iend < mini && iend >= 0) iend = mini; + if (iend > -mini && iend < 0) iend = -mini; +#endif + istart = 1 / istart; + iend = 1 / iend; + ds_p->yscale = (float)yscale; + ds_p->iscale = (float)istart; if (stop - start > 0) { - ds_p->iscalestep = (iend - istart) / (stop - start); + ds_p->iscalestep = float((iend - istart) / (stop - start)); } else { @@ -3182,7 +3186,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, } topoff = WallSpriteTile->TopOffset << FRACBITS; - dc_texturemid = topoff + xs_ToInt((zpos - ViewPos.Z) * 65536 / yscale); + dc_texturemid = topoff + (zpos - ViewPos.Z) / yscale; // Clip sprite to drawseg x1 = MAX(clipper->x1, x1); @@ -3232,7 +3236,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { sprflipvert = true; yscale = -yscale; - dc_texturemid = dc_texturemid - (WallSpriteTile->GetHeight() << FRACBITS); + dc_texturemid -= WallSpriteTile->GetHeight(); } else { diff --git a/src/r_sky.cpp b/src/r_sky.cpp index f3bdbed35c..727d0bbbf4 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -40,7 +40,7 @@ // FTextureID skyflatnum; FTextureID sky1texture, sky2texture; -fixed_t skytexturemid; +double skytexturemid; fixed_t skyscale; fixed_t skyiscale; bool skystretch; @@ -103,11 +103,11 @@ void R_InitSkyMap () && skyheight >= 128 && level.IsFreelookAllowed() && !(level.flags & LEVEL_FORCENOSKYSTRETCH)) ? 1 : 0; - skytexturemid = -28*FRACUNIT; + skytexturemid = -28; } else if (skyheight > 200) { - skytexturemid = FLOAT2FIXED((200 - skyheight) * skytex1->Scale.Y); + skytexturemid = (200 - skyheight) * skytex1->Scale.Y; } if (viewwidth != 0 && viewheight != 0) @@ -124,7 +124,7 @@ void R_InitSkyMap () { skyscale = Scale(skyscale, SKYSTRETCH_HEIGHT, skyheight); skyiscale = Scale(skyiscale, skyheight, SKYSTRETCH_HEIGHT); - skytexturemid = Scale(skytexturemid, skyheight, SKYSTRETCH_HEIGHT); + skytexturemid = skytexturemid * skyheight / SKYSTRETCH_HEIGHT; } // The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees, diff --git a/src/r_sky.h b/src/r_sky.h index 6b9df2f142..30b106185f 100644 --- a/src/r_sky.h +++ b/src/r_sky.h @@ -29,7 +29,7 @@ extern FTextureID skyflatnum; extern fixed_t sky1cyl, sky2cyl; extern FTextureID sky1texture, sky2texture; extern double sky1pos, sky2pos; -extern fixed_t skytexturemid; +extern double skytexturemid; extern fixed_t skyiscale; extern fixed_t skyscale; extern bool skystretch; diff --git a/src/r_things.cpp b/src/r_things.cpp index ec9822a717..60ae7213b7 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -237,22 +237,23 @@ vissprite_t *R_NewVisSprite (void) short* mfloorclip; short* mceilingclip; -fixed_t spryscale; -fixed_t sprtopscreen; +double spryscale; +double sprtopscreen; bool sprflipvert; void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span) { - fixed_t centeryfrac = FLOAT2FIXED(CenterY); + const fixed_t centeryfrac = FLOAT2FIXED(CenterY); + const fixed_t texturemid = FLOAT2FIXED(dc_texturemid); while (span->Length != 0) { const int length = span->Length; const int top = span->TopOffset; // calculate unclipped screen coordinates for post - dc_yl = (sprtopscreen + spryscale * top) >> FRACBITS; - dc_yh = (sprtopscreen + spryscale * (top + length) - FRACUNIT) >> FRACBITS; + dc_yl = xs_RoundToInt(sprtopscreen + spryscale * top); + dc_yh = xs_RoundToInt(sprtopscreen + spryscale * (top + length)) - 1; if (sprflipvert) { @@ -273,7 +274,7 @@ void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span) if (sprflipvert) { dc_texturefrac = (dc_yl*dc_iscale) - (top << FRACBITS) - - FixedMul (centeryfrac, dc_iscale) - dc_texturemid; + - FixedMul (centeryfrac, dc_iscale) - texturemid; const fixed_t maxfrac = length << FRACBITS; while (dc_texturefrac >= maxfrac) { @@ -291,7 +292,7 @@ void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span) } else { - dc_texturefrac = dc_texturemid - (top << FRACBITS) + dc_texturefrac = texturemid - (top << FRACBITS) + (dc_yl*dc_iscale) - FixedMul (centeryfrac-FRACUNIT, dc_iscale); while (dc_texturefrac < 0) { @@ -433,24 +434,23 @@ void R_DrawVisSprite (vissprite_t *vis) tex = vis->pic; spryscale = vis->yscale; sprflipvert = false; - dc_iscale = 0xffffffffu / (unsigned)vis->yscale; + dc_iscale = FLOAT2FIXED(1 / vis->yscale); frac = vis->startfrac; xiscale = vis->xiscale; dc_texturemid = vis->texturemid; - if (vis->renderflags & RF_YFLIP) { sprflipvert = true; spryscale = -spryscale; dc_iscale = -dc_iscale; - dc_texturemid -= (vis->pic->GetHeight() << FRACBITS); - sprtopscreen = centeryfrac + FixedMul(dc_texturemid, spryscale); + dc_texturemid -= vis->pic->GetHeight(); + sprtopscreen = CenterY + dc_texturemid * spryscale; } else { sprflipvert = false; - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + sprtopscreen = CenterY - dc_texturemid * spryscale; } dc_x = vis->x1; @@ -500,7 +500,7 @@ void R_DrawVisSprite (vissprite_t *vis) void R_DrawWallSprite(vissprite_t *spr) { int x1, x2; - fixed_t yscale; + double iyscale; x1 = MAX(spr->x1, spr->wallc.sx1); x2 = MIN(spr->x2, spr->wallc.sx2); @@ -508,8 +508,8 @@ void R_DrawWallSprite(vissprite_t *spr) return; WallT.InitFromWallCoords(&spr->wallc); PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2); - yscale = spr->yscale; - dc_texturemid = FixedDiv(FLOAT2FIXED(spr->gzt - ViewPos.Z), yscale); + iyscale = 1 / spr->yscale; + dc_texturemid = (spr->gzt - ViewPos.Z) * iyscale; if (spr->renderflags & RF_XFLIP) { int right = (spr->pic->GetWidth() << FRACBITS) - 1; @@ -550,8 +550,8 @@ void R_DrawWallSprite(vissprite_t *spr) if (spr->renderflags & RF_YFLIP) { sprflipvert = true; - yscale = -yscale; - dc_texturemid = dc_texturemid - (spr->pic->GetHeight() << FRACBITS); + iyscale = -iyscale; + dc_texturemid -= spr->pic->GetHeight(); } else { @@ -559,7 +559,7 @@ void R_DrawWallSprite(vissprite_t *spr) } // rw_offset is used as the texture's vertical scale - rw_offset = SafeDivScale30(1, yscale); + rw_offset = xs_Fix<30>::ToFix(iyscale); dc_x = x1; ESPSResult mode; @@ -636,9 +636,9 @@ void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Sp dc_iscale = MulScale16 (swall[dc_x], rw_offset); spryscale = SafeDivScale32 (1, dc_iscale); if (sprflipvert) - sprtopscreen = FLOAT2FIXED(CenterY) + FixedMul (dc_texturemid, spryscale); + sprtopscreen = CenterY + dc_texturemid * spryscale; else - sprtopscreen = FLOAT2FIXED(CenterY) - FixedMul (dc_texturemid, spryscale); + sprtopscreen = CenterY - dc_texturemid * spryscale; const BYTE *column; const FTexture::Span *spans; @@ -680,7 +680,7 @@ void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop // Render the voxel, either directly to the screen or offscreen. R_DrawVoxel(spr->vpos, spr->vang, spr->gpos, spr->angle, - spr->xscale, spr->yscale, spr->voxel, spr->Style.colormap, cliptop, clipbot, + spr->xscale, FLOAT2FIXED(spr->yscale), spr->voxel, spr->Style.colormap, cliptop, clipbot, minslabz, maxslabz, flags); // Blend the voxel, if that's what we need to do. @@ -982,17 +982,17 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor xscale = spriteScale.X * xscale / tex->Scale.X; iscale = (tex->GetWidth() << FRACBITS) / (x2 - x1); - fixed_t yscale = FLOAT2FIXED(spriteScale.Y / tex->Scale.Y); + double yscale = spriteScale.Y / tex->Scale.Y; // store information in a vissprite vis = R_NewVisSprite(); vis->CurrentPortalUniq = CurrentPortalUniq; vis->xscale = FLOAT2FIXED(xscale); - vis->yscale = fixed_t(InvZtoScale * yscale / tz); + vis->yscale = float(InvZtoScale * yscale / tz); vis->idepth = float(1 / tz); - vis->floorclip = FixedDiv (FLOAT2FIXED(thing->Floorclip), yscale); - vis->texturemid = (tex->TopOffset << FRACBITS) - FixedDiv(FLOAT2FIXED(ViewPos.Z - pos.Z + thing->Floorclip), yscale); + vis->floorclip = thing->Floorclip / yscale; + vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale; vis->x1 = x1 < WindowLeft ? WindowLeft : x1; vis->x2 = x2 > WindowRight ? WindowRight : x2; vis->angle = thing->Angles.Yaw.BAMs(); @@ -1017,11 +1017,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->CurrentPortalUniq = CurrentPortalUniq; vis->xscale = FLOAT2FIXED(xscale); - vis->yscale = FLOAT2FIXED(yscale); + vis->yscale = (float)yscale; vis->x1 = WindowLeft; vis->x2 = WindowRight; vis->idepth = 1 / MINZ; - vis->floorclip = FLOAT2FIXED(thing->Floorclip); + vis->floorclip = thing->Floorclip; pos.Z -= thing->Floorclip; @@ -1179,7 +1179,7 @@ static void R_ProjectWallSprite(AActor *thing, const DVector3 &pos, FTextureID p vis->CurrentPortalUniq = CurrentPortalUniq; vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1; vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2; - vis->yscale = FLOAT2FIXED(scale.Y); + vis->yscale = (float)scale.Y; vis->idepth = float(1 / tz); vis->depth = (float)tz; vis->sector = thing->Sector; @@ -1334,7 +1334,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double vis->renderflags = owner->renderflags; vis->floorclip = 0; - vis->texturemid = FLOAT2FIXED((BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset); + vis->texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset; if (camera->player && (RenderTarget != screen || viewheight == RenderTarget->GetHeight() || @@ -1349,11 +1349,11 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double { if (RenderTarget != screen || viewheight == RenderTarget->GetHeight()) { - vis->texturemid -= FLOAT2FIXED(weapon->YAdjust); + vis->texturemid -= weapon->YAdjust; } else { - vis->texturemid -= FLOAT2FIXED(StatusBar->GetDisplacement () * weapon->YAdjust); + vis->texturemid -= StatusBar->GetDisplacement () * weapon->YAdjust; } } } @@ -1364,7 +1364,7 @@ void R_DrawPSprite (pspdef_t* psp, int pspnum, AActor *owner, double sx, double vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth : x2; vis->xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X); - vis->yscale = FLOAT2FIXED(pspriteyscale / tex->Scale.Y); + vis->yscale = float(pspriteyscale / tex->Scale.Y); vis->Translation = 0; // [RH] Use default colors vis->pic = tex; vis->ColormapNum = 0; @@ -1655,9 +1655,9 @@ void R_DrawRemainingPlayerSprites() } screen->DrawTexture(vis->pic, viewwindowx + VisPSpritesX1[i], - viewwindowy + viewheight/2 - (vis->texturemid / 65536.0) * (vis->yscale / 65536.0) - 0.5, + viewwindowy + viewheight/2 - vis->texturemid * vis->yscale - 0.5, DTA_DestWidthF, FIXED2DBL(vis->pic->GetWidth() * vis->xscale), - DTA_DestHeightF, FIXED2DBL(vis->pic->GetHeight() * vis->yscale), + DTA_DestHeightF, vis->pic->GetHeight() * vis->yscale, DTA_Translation, TranslationToTable(vis->Translation), DTA_FlipX, flip, DTA_TopOffset, 0, @@ -2075,12 +2075,11 @@ void R_DrawSprite (vissprite_t *spr) // killough 3/27/98: end special clipping for deep water / fake ceilings else if (!spr->bIsVoxel && spr->floorclip) { // [RH] Move floorclip stuff from R_DrawVisSprite to here - int clip = ((FLOAT2FIXED(CenterY) - FixedMul (spr->texturemid - - (spr->pic->GetHeight() << FRACBITS) + - spr->floorclip, spr->yscale)) >> FRACBITS); + //int clip = ((FLOAT2FIXED(CenterY) - FixedMul (spr->texturemid - (spr->pic->GetHeight() << FRACBITS) + spr->floorclip, spr->yscale)) >> FRACBITS); + int clip = xs_RoundToInt(CenterY - (spr->texturemid - spr->pic->GetHeight() + spr->floorclip) * spr->yscale); if (clip < botclip) { - botclip = MAX (0, clip); + botclip = MAX(0, clip); } } @@ -2295,8 +2294,8 @@ void R_DrawSprite (vissprite_t *spr) { clearbufshort(cliptop + x2, viewwidth - x2, viewheight); } - int minvoxely = spr->gzt <= hzt ? 0 : FLOAT2FIXED(spr->gzt - hzt) / spr->yscale; - int maxvoxely = spr->gzb > hzb ? INT_MAX : FLOAT2FIXED(spr->gzt - hzb) / spr->yscale; + int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale); + int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale); R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot); } spr->Style.colormap = colormap; @@ -2526,8 +2525,9 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, vis = R_NewVisSprite (); vis->CurrentPortalUniq = CurrentPortalUniq; vis->heightsec = heightsec; - vis->yscale = vis->xscale = FLOAT2FIXED(xscale); -// vis->yscale = FixedMul (xscale, InvZtoScale); + vis->xscale = FLOAT2FIXED(xscale); + vis->yscale = (float)xscale; +// vis->yscale *= InvZtoScale; vis->depth = (float)tz; vis->idepth = float(1 / tz); vis->gpos = { (float)particle->Pos.X, (float)particle->Pos.Y, (float)particle->Pos.Z }; diff --git a/src/r_things.h b/src/r_things.h index 5723a5737d..64dcb82b80 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -39,12 +39,13 @@ struct vissprite_t int y1, y2; // top / bottom of particle on screen }; angle_t angle; - fixed_t xscale, yscale; + fixed_t xscale; + float yscale; float depth; float idepth; // 1/z float deltax, deltay; DWORD FillColor; - fixed_t floorclip; + double floorclip; union { FTexture *pic; @@ -55,7 +56,7 @@ struct vissprite_t // Used by face sprites struct { - fixed_t texturemid; + double texturemid; fixed_t startfrac; // horizontal position of x1 fixed_t xiscale; // negative if flipped }; @@ -108,8 +109,8 @@ extern short screenheightarray[MAXWIDTH]; // vars for R_DrawMaskedColumn extern short* mfloorclip; extern short* mceilingclip; -extern fixed_t spryscale; -extern fixed_t sprtopscreen; +extern double spryscale; +extern double sprtopscreen; extern bool sprflipvert; extern double pspritexscale; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 7097ebd27d..dccbfdc936 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -202,30 +202,23 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms) double centeryback = CenterY; CenterY = 0; - sprtopscreen = FLOAT2FIXED(y0); // There is not enough precision in the drawing routines to keep the full // precision for y0. :( - sprtopscreen &= ~(FRACUNIT - 1); + double dummy; + sprtopscreen = modf(y0, &dummy); double yscale = parms.destheight / img->GetHeight(); double iyscale = 1 / yscale; - spryscale = FLOAT2FIXED(yscale); - assert(spryscale > 2); -#if 0 - // Fix precision errors that are noticeable at some resolutions - if ((y0 + parms.destheight) > (y0 + yscale * img->GetHeight())) - { - spryscale++; - } -#endif + spryscale = yscale; + assert(spryscale > 0); sprflipvert = false; //dc_iscale = FLOAT2FIXED(iyscale); - //dc_texturemid = FLOAT2FIXED((-y0) * iyscale); + //dc_texturemid = (-y0) * iyscale; //dc_iscale = 0xffffffffu / (unsigned)spryscale; - dc_iscale = DivScale32(1, spryscale); - dc_texturemid = FixedMul(-sprtopscreen, dc_iscale) + xs_ToInt((CenterY - 1) * dc_iscale); + dc_iscale = FLOAT2FIXED(1 / spryscale); + dc_texturemid = (CenterY - 1 - sprtopscreen) * dc_iscale / 65536; fixed_t frac = 0; double xiscale = img->GetWidth() / parms.destwidth; double x2 = x0 + parms.destwidth; diff --git a/src/xs_Float.h b/src/xs_Float.h index 33150e4ea3..6c676ee3af 100644 --- a/src/xs_Float.h +++ b/src/xs_Float.h @@ -87,14 +87,14 @@ public: // ==================================================================================================================== // Basic Conversion from Numbers // ==================================================================================================================== - finline static Fix ToFix (int32_t val) {return val<>N;} + finline static int32_t ToInt (Fix f) {return f>>N;} @@ -112,6 +112,15 @@ protected: } }; +finline static int32_t xs_ToFixed(int32_t n, real64 val) +{ + #if _xs_DEFAULT_CONVERSION==0 + return xs_CRoundToInt(val, _xs_doublemagic/(1<