Renderer floatification: Use floating point for texturemids and Y scales

This commit is contained in:
Randy Heit 2016-04-15 20:30:05 -05:00
parent 4a1cc61822
commit 3ef5a678d5
12 changed files with 185 additions and 182 deletions

View file

@ -66,13 +66,13 @@ struct drawseg_t
{ {
seg_t* curline; seg_t* curline;
float light, lightstep; float light, lightstep;
fixed_t iscale, iscalestep; float iscale, iscalestep;
short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg short x1, x2; // Same as sx1 and sx2, but clipped to the drawseg
short sx1, sx2; // left, right of parent seg on screen short sx1, sx2; // left, right of parent seg on screen
float sz1, sz2; // z for 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 siz1, siz2; // 1/z for left, right of parent seg on screen
float cx, cy, cdx, cdy; float cx, cy, cdx, cdy;
fixed_t yrepeat; float yscale;
BYTE silhouette; // 0=none, 1=bottom, 2=top, 3=both BYTE silhouette; // 0=none, 1=bottom, 2=top, 3=both
BYTE bFogBoundary; BYTE bFogBoundary;
BYTE bFakeBoundary; // for fake walls BYTE bFakeBoundary; // for fake walls

View file

@ -86,6 +86,7 @@ void (*rt_map4cols)(int,int,int);
// R_DrawColumn // R_DrawColumn
// Source is the top of the column to scale. // Source is the top of the column to scale.
// //
double dc_texturemid;
extern "C" { extern "C" {
int dc_pitch=0xABadCafe; // [RH] Distance between rows int dc_pitch=0xABadCafe; // [RH] Distance between rows
@ -94,7 +95,6 @@ int dc_x;
int dc_yl; int dc_yl;
int dc_yh; int dc_yh;
fixed_t dc_iscale; fixed_t dc_iscale;
fixed_t dc_texturemid;
fixed_t dc_texturefrac; fixed_t dc_texturefrac;
int dc_color; // [RH] Color for column filler int dc_color; // [RH] Color for column filler
DWORD dc_srccolor; DWORD dc_srccolor;

View file

@ -34,7 +34,7 @@ extern "C" int dc_x;
extern "C" int dc_yl; extern "C" int dc_yl;
extern "C" int dc_yh; extern "C" int dc_yh;
extern "C" fixed_t dc_iscale; extern "C" fixed_t dc_iscale;
extern "C" fixed_t dc_texturemid; extern double dc_texturemid;
extern "C" fixed_t dc_texturefrac; extern "C" fixed_t dc_texturefrac;
extern "C" int dc_color; // [RH] For flat colors (no texturing) extern "C" int dc_color; // [RH] For flat colors (no texturing)
extern "C" DWORD dc_srccolor; extern "C" DWORD dc_srccolor;

View file

@ -1108,14 +1108,15 @@ void R_FillColumnHorizP (void)
void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span) void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span)
{ {
const fixed_t texturemid = FLOAT2FIXED(dc_texturemid);
while (span->Length != 0) while (span->Length != 0)
{ {
const int length = span->Length; const int length = span->Length;
const int top = span->TopOffset; const int top = span->TopOffset;
// calculate unclipped screen coordinates for post // calculate unclipped screen coordinates for post
dc_yl = (sprtopscreen + spryscale * top) >> FRACBITS; dc_yl = xs_RoundToInt(sprtopscreen + spryscale * top);
dc_yh = (sprtopscreen + spryscale * (top + length) - FRACUNIT) >> FRACBITS; dc_yh = xs_RoundToInt(sprtopscreen + spryscale * (top + length) - 1);
if (sprflipvert) if (sprflipvert)
{ {
@ -1136,7 +1137,7 @@ void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span)
if (sprflipvert) if (sprflipvert)
{ {
dc_texturefrac = (dc_yl*dc_iscale) - (top << FRACBITS) 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; const fixed_t maxfrac = length << FRACBITS;
while (dc_texturefrac >= maxfrac) while (dc_texturefrac >= maxfrac)
{ {
@ -1154,7 +1155,7 @@ void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *span)
} }
else else
{ {
dc_texturefrac = dc_texturemid - (top << FRACBITS) dc_texturefrac = texturemid - (top << FRACBITS)
+ (dc_yl*dc_iscale) - fixed_t((CenterY-1) * dc_iscale); + (dc_yl*dc_iscale) - fixed_t((CenterY-1) * dc_iscale);
while (dc_texturefrac < 0) while (dc_texturefrac < 0)
{ {

View file

@ -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 FTexture *frontskytex, *backskytex;
static angle_t skyflip; static angle_t skyflip;
static int frontpos, backpos; static int frontpos, backpos;
static fixed_t frontyScale; static double frontyScale;
static fixed_t frontcyl, backcyl; static fixed_t frontcyl, backcyl;
static fixed_t skymid; static double skymid;
static angle_t skyangle; static angle_t skyangle;
int frontiScale; static double frontiScale;
extern fixed_t swall[MAXWIDTH]; extern fixed_t swall[MAXWIDTH];
extern fixed_t lwall[MAXWIDTH]; extern fixed_t lwall[MAXWIDTH];
@ -947,8 +947,8 @@ static void R_DrawSky (visplane_t *pl)
rw_pic = frontskytex; rw_pic = frontskytex;
rw_offset = 0; rw_offset = 0;
frontyScale = FLOAT2FIXED(rw_pic->Scale.Y); frontyScale = rw_pic->Scale.Y;
dc_texturemid = MulScale16 (skymid, frontyScale); dc_texturemid = skymid * frontyScale;
if (1 << frontskytex->HeightBits == frontskytex->GetHeight()) if (1 << frontskytex->HeightBits == frontskytex->GetHeight())
{ // The texture tiles nicely { // The texture tiles nicely
@ -957,19 +957,19 @@ static void R_DrawSky (visplane_t *pl)
lastskycol[x] = 0xffffffff; lastskycol[x] = 0xffffffff;
} }
wallscan (pl->left, pl->right, (short *)pl->top, (short *)pl->bottom, swall, lwall, 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 else
{ // The texture does not tile nicely { // The texture does not tile nicely
frontyScale = DivScale16 (skyscale, frontyScale); frontyScale *= skyscale;
frontiScale = DivScale32 (1, frontyScale); frontiScale = 1 / frontyScale;
// Sodding crap. Fixed point sucks when you want precision. // Sodding crap. Fixed point sucks when you want precision.
// TODO (if I'm feeling adventurous): Rewrite the renderer to use floating point // TODO (if I'm feeling adventurous): Rewrite the renderer to use floating point
// coordinates to keep as much precision as possible until the final // coordinates to keep as much precision as possible until the final
// rasterization stage so fudges like this aren't needed. // rasterization stage so fudges like this aren't needed.
if (viewheight <= 600) if (viewheight <= 600)
{ {
skymid -= FRACUNIT; skymid -= 1;
} }
R_DrawSkyStriped (pl); R_DrawSkyStriped (pl);
} }
@ -977,22 +977,18 @@ static void R_DrawSky (visplane_t *pl)
static void R_DrawSkyStriped (visplane_t *pl) static void R_DrawSkyStriped (visplane_t *pl)
{ {
double centerysave = CenterY; short drawheight = short(frontskytex->GetHeight() * frontyScale);
short drawheight = (short)MulScale16 (frontskytex->GetHeight(), frontyScale); double topfrac;
fixed_t topfrac; double iscale = frontiScale;
fixed_t iscale = frontiScale;
short top[MAXWIDTH], bot[MAXWIDTH]; short top[MAXWIDTH], bot[MAXWIDTH];
short yl, yh; short yl, yh;
int x; int x;
// So that I don't have to worry about fractional precision, chop off the topfrac = fmod(skymid + iscale * (1 - CenterY), frontskytex->GetHeight());
// fractional part of centeryfrac. if (topfrac < 0) topfrac += frontskytex->GetHeight();
CenterY = centery;
topfrac = (skymid + iscale * (1-centery)) % (frontskytex->GetHeight() << FRACBITS);
if (topfrac < 0) topfrac += frontskytex->GetHeight() << FRACBITS;
yl = 0; yl = 0;
yh = (short)MulScale32 ((frontskytex->GetHeight() << FRACBITS) - topfrac, frontyScale); yh = short((frontskytex->GetHeight() - topfrac) * frontyScale);
dc_texturemid = topfrac - iscale * (1-centery); dc_texturemid = topfrac - iscale * (1 - CenterY);
fixed_t yScale = FLOAT2FIXED(rw_pic->Scale.Y); fixed_t yScale = FLOAT2FIXED(rw_pic->Scale.Y);
while (yl < viewheight) while (yl < viewheight)
@ -1012,7 +1008,6 @@ static void R_DrawSkyStriped (visplane_t *pl)
yh += drawheight; yh += drawheight;
dc_texturemid = iscale * (centery-yl-1); dc_texturemid = iscale * (centery-yl-1);
} }
CenterY = centerysave;
} }
//========================================================================== //==========================================================================
@ -1461,7 +1456,7 @@ void R_DrawSkyPlane (visplane_t *pl)
skyangle += s->GetTextureXOffset(pos); skyangle += s->GetTextureXOffset(pos);
// Vertical offset allows careful sky positioning. // Vertical offset allows careful sky positioning.
skymid = s->GetTextureYOffset(pos) - 28*FRACUNIT; skymid = s->GetTextureYOffsetF(pos) - 28;
// We sometimes flip the picture horizontally. // We sometimes flip the picture horizontally.
// //
@ -1474,7 +1469,7 @@ void R_DrawSkyPlane (visplane_t *pl)
frontcyl = MAX(frontskytex->GetWidth(), frontxscale); frontcyl = MAX(frontskytex->GetWidth(), frontxscale);
if (skystretch) if (skystretch)
{ {
skymid = Scale(skymid, frontskytex->GetScaledHeight(), SKYSTRETCH_HEIGHT); skymid = skymid * frontskytex->GetScaledHeightDouble() / SKYSTRETCH_HEIGHT;
} }
} }
} }

View file

@ -119,10 +119,10 @@ static double rw_frontlowertop;
static int rw_x; static int rw_x;
static int rw_stopx; static int rw_stopx;
fixed_t rw_offset; fixed_t rw_offset;
static fixed_t rw_scalestep; static double rw_scalestep;
static fixed_t rw_midtexturemid; static double rw_midtexturemid;
static fixed_t rw_toptexturemid; static double rw_toptexturemid;
static fixed_t rw_bottomtexturemid; static double rw_bottomtexturemid;
static double rw_midtexturescalex; static double rw_midtexturescalex;
static double rw_midtexturescaley; static double rw_midtexturescaley;
static double rw_toptexturescalex; static double rw_toptexturescalex;
@ -170,7 +170,7 @@ CVAR(Bool, r_drawmirrors, true, 0)
// R_RenderMaskedSegRange // R_RenderMaskedSegRange
// //
fixed_t *MaskedSWall; fixed_t *MaskedSWall;
fixed_t MaskedScaleY; double MaskedScaleY;
static void BlastMaskedColumn (void (*blastfunc)(const BYTE *pixels, const FTexture::Span *spans), FTexture *tex) 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_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) if (sprflipvert)
sprtopscreen = FLOAT2FIXED(CenterY) + FixedMul(dc_texturemid, spryscale); sprtopscreen = CenterY + dc_texturemid * spryscale;
else else
sprtopscreen = FLOAT2FIXED(CenterY) - FixedMul(dc_texturemid, spryscale); sprtopscreen = CenterY - dc_texturemid * spryscale;
// killough 1/25/98: here's where Medusa came in, because // killough 1/25/98: here's where Medusa came in, because
// it implicitly assumed that the column was all one patch. // 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 sector_t tempsec; // killough 4/13/98
double texheight, texheightscale; double texheight, texheightscale;
bool notrelevant = false; bool notrelevant = false;
fixed_t rowoffset; double rowoffset;
const sector_t *sec; 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; MaskedSWall = (fixed_t *)(openings + ds->swall) - ds->x1;
MaskedScaleY = ds->yrepeat; MaskedScaleY = ds->yscale;
maskedtexturecol = (fixed_t *)(openings + ds->maskedtexturecol) - ds->x1; maskedtexturecol = (fixed_t *)(openings + ds->maskedtexturecol) - ds->x1;
spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1); spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1);
rw_scalestep = ds->iscalestep; rw_scalestep = ds->iscalestep;
@ -325,14 +325,14 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
} }
if (curline->linedef->flags & ML_DONTPEGBOTTOM) 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 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) && if (!(curline->linedef->flags & ML_WRAP_MIDTEX) &&
!(curline->sidedef->Flags & WALLF_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) 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. // still be positioned in world units rather than texels.
dc_texturemid += rowoffset - FLOAT2FIXED(ViewPos.Z); dc_texturemid += rowoffset - ViewPos.Z;
textop = FIXED2FLOAT(dc_texturemid); textop = dc_texturemid;
dc_texturemid = MulScale16 (dc_texturemid, MaskedScaleY); dc_texturemid *= MaskedScaleY;
} }
else else
{ {
// rowoffset is added outside the multiply so that it positions the texture // rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units. // by texels instead of world units.
textop = FIXED2FLOAT(dc_texturemid + SafeDivScale16 (rowoffset, MaskedScaleY)) - ViewPos.Z; textop = dc_texturemid + rowoffset / MaskedScaleY - ViewPos.Z;
dc_texturemid = MulScale16 (dc_texturemid - FLOAT2FIXED(ViewPos.Z), MaskedScaleY) + rowoffset; dc_texturemid = (dc_texturemid - ViewPos.Z) * MaskedScaleY + rowoffset;
} }
if (sprflipvert) if (sprflipvert)
{ {
@ -433,6 +433,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
mfloorclip = walllower; mfloorclip = walllower;
mceilingclip = wallupper; mceilingclip = wallupper;
MaskedScaleY /= 4; // [RH] Wish I could remember why this needs to be done
// draw the columns one at a time // draw the columns one at a time
if (drawmode == DoDraw0) if (drawmode == DoDraw0)
@ -480,16 +481,15 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
{ // Texture does wrap vertically. { // Texture does wrap vertically.
if (tex->bWorldPanning) 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. // still be positioned in world units rather than texels.
dc_texturemid += rowoffset - FLOAT2FIXED(ViewPos.Z); dc_texturemid = (dc_texturemid + rowoffset - ViewPos.Z) * MaskedScaleY;
dc_texturemid = MulScale16 (dc_texturemid, MaskedScaleY);
} }
else else
{ {
// rowoffset is added outside the multiply so that it positions the texture // rowoffset is added outside the multiply so that it positions the texture
// by texels instead of world units. // 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; WallC.sz1 = ds->sz1;
@ -531,7 +531,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2)
rw_offset = 0; rw_offset = 0;
rw_pic = tex; 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: clearfog:
@ -601,23 +601,23 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover)
scaledpart = side_t::mid; scaledpart = side_t::mid;
} }
xscale = fixed_t(rw_pic->Scale.X * scaledside->GetTextureXScale(scaledpart)); 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); double planez = rover->model->GetPlaneTexZF(sector_t::ceiling);
rw_offset = curline->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid); rw_offset = curline->sidedef->GetTextureXOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureXOffset(side_t::mid);
if (rowoffset < 0) 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) 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. // still be positioned in world units rather than texels.
dc_texturemid += xs_FloorToInt(rowoffset * yscale); dc_texturemid = dc_texturemid + rowoffset * yscale;
rw_offset = MulScale16 (rw_offset, xscale); ///Is this really supposed to be xscale and not yscale? rw_offset = MulScale16 (rw_offset, xscale);
} }
else else
{ {
@ -1101,7 +1101,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed_t
shiftval = rw_pic->HeightBits; shiftval = rw_pic->HeightBits;
setupvline (32-shiftval); setupvline (32-shiftval);
yrepeat >>= 2 + shiftval; yrepeat >>= 2 + shiftval;
texturemid = dc_texturemid << (16 - shiftval); texturemid = xs_ToFixed(32 - shiftval, dc_texturemid);
xoffset = rw_offset; xoffset = rw_offset;
basecolormapdata = basecolormap->Maps; basecolormapdata = basecolormap->Maps;
fixed_t centeryfrac = FLOAT2FIXED(CenterY); 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) if (!r_np2)
{ {
call_wallscan(x1, x2, uwal, dwal, swal, lwal, yrepeat, mask); call_wallscan(x1, x2, uwal, dwal, swal, lwal, yrep, mask);
} }
else else
{ {
short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH]; short most1[MAXWIDTH], most2[MAXWIDTH], most3[MAXWIDTH];
short *up, *down; short *up, *down;
fixed_t texheight = rw_pic->GetHeight() << FRACBITS; double texheight = rw_pic->GetHeight();
double scaledtexheight = FIXED2FLOAT(FixedDiv(texheight, yrepeat));
double partition; double partition;
double top = FIXED2FLOAT(itop); double top = FIXED2FLOAT(itop);
double bot = FIXED2FLOAT(ibot); double bot = FIXED2FLOAT(ibot);
double yrepeat = FIXED2FLOAT(yrep);
double scaledtexheight = texheight / yrepeat;
if (yrepeat >= 0) if (yrepeat >= 0)
{ // normal orientation: draw strips from top to bottom { // 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) if (partition == top)
{ {
partition -= scaledtexheight; partition -= scaledtexheight;
} }
up = uwal; up = uwal;
down = most1; down = most1;
dc_texturemid = xs_RoundToInt((partition - ViewPos.Z) * yrepeat + texheight); dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
while (partition > bot) while (partition > bot)
{ {
int j = OWallMost(most3, partition - ViewPos.Z, &WallC); 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]); 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; up = down;
down = (down == most1) ? most2 : most1; down = (down == most1) ? most2 : most1;
} }
partition -= scaledtexheight; partition -= scaledtexheight;
dc_texturemid -= texheight; dc_texturemid -= texheight;
} }
call_wallscan(x1, x2, up, dwal, swal, lwal, yrepeat, mask); call_wallscan(x1, x2, up, dwal, swal, lwal, yrep, mask);
} }
else else
{ // upside down: draw strips from bottom to top { // 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; up = most1;
down = dwal; down = dwal;
dc_texturemid = xs_RoundToInt((partition - ViewPos.Z) * yrepeat + texheight); dc_texturemid = (partition - ViewPos.Z) * yrepeat + texheight;
while (partition < top) while (partition < top)
{ {
int j = OWallMost(most3, partition - ViewPos.Z, &WallC); 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]); 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; down = up;
up = (up == most1) ? most2 : most1; up = (up == most1) ? most2 : most1;
} }
partition -= scaledtexheight; partition -= scaledtexheight;
dc_texturemid -= texheight; 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; shiftval = rw_pic->HeightBits;
setupmvline (32-shiftval); setupmvline (32-shiftval);
yrepeat >>= 2 + shiftval; yrepeat >>= 2 + shiftval;
texturemid = dc_texturemid << (16 - shiftval); texturemid = xs_ToFixed(32 - shiftval, dc_texturemid);
xoffset = rw_offset; xoffset = rw_offset;
basecolormapdata = basecolormap->Maps; basecolormapdata = basecolormap->Maps;
fixed_t centeryfrac = FLOAT2FIXED(CenterY); 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; shiftval = rw_pic->HeightBits;
setuptmvline (32-shiftval); setuptmvline (32-shiftval);
yrepeat >>= 2 + shiftval; yrepeat >>= 2 + shiftval;
texturemid = dc_texturemid << (16 - shiftval); texturemid = xs_ToFixed(32 - shiftval, dc_texturemid);
xoffset = rw_offset; xoffset = rw_offset;
basecolormapdata = basecolormap->Maps; basecolormapdata = basecolormap->Maps;
fixed_t centeryfrac = FLOAT2FIXED(CenterY); fixed_t centeryfrac = FLOAT2FIXED(CenterY);
@ -1997,7 +1998,7 @@ void R_RenderSegLoop ()
void R_NewWall (bool needlights) void R_NewWall (bool needlights)
{ {
fixed_t rowoffset; double rowoffset;
double yrepeat; double yrepeat;
rw_markportal = false; rw_markportal = false;
@ -2026,7 +2027,7 @@ void R_NewWall (bool needlights)
{ {
midtexture = TexMan(sidedef->GetTexture(side_t::mid), true); midtexture = TexMan(sidedef->GetTexture(side_t::mid), true);
rw_offset_mid = sidedef->GetTextureXOffset(side_t::mid); 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_midtexturescalex = FIXED2DBL(sidedef->GetTextureXScale(side_t::mid));
rw_midtexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::mid)); rw_midtexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::mid));
yrepeat = midtexture->Scale.Y * rw_midtexturescaley; yrepeat = midtexture->Scale.Y * rw_midtexturescaley;
@ -2034,14 +2035,14 @@ void R_NewWall (bool needlights)
{ // normal orientation { // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom { // 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 else
{ // top of texture at top { // 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) if (rowoffset < 0 && midtexture != NULL)
{ {
rowoffset += midtexture->GetHeight() << FRACBITS; rowoffset += midtexture->GetHeight();
} }
} }
} }
@ -2050,16 +2051,16 @@ void R_NewWall (bool needlights)
rowoffset = -rowoffset; rowoffset = -rowoffset;
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom { // 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 else
{ // bottom of texture at top { // 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) if (midtexture->bWorldPanning)
{ {
rw_midtexturemid += xs_FloorToInt(rowoffset * yrepeat); rw_midtexturemid += rowoffset * yrepeat;
} }
else else
{ {
@ -2181,7 +2182,7 @@ void R_NewWall (bool needlights)
toptexture = TexMan(sidedef->GetTexture(side_t::top), true); toptexture = TexMan(sidedef->GetTexture(side_t::top), true);
rw_offset_top = sidedef->GetTextureXOffset(side_t::top); 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_toptexturescalex = FIXED2DBL(sidedef->GetTextureXScale(side_t::top));
rw_toptexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::top)); rw_toptexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::top));
yrepeat = toptexture->Scale.Y * rw_toptexturescaley; yrepeat = toptexture->Scale.Y * rw_toptexturescaley;
@ -2189,15 +2190,15 @@ void R_NewWall (bool needlights)
{ // normal orientation { // normal orientation
if (linedef->flags & ML_DONTPEGTOP) if (linedef->flags & ML_DONTPEGTOP)
{ // top of texture at top { // 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) if (rowoffset < 0 && toptexture != NULL)
{ {
rowoffset += toptexture->GetHeight() << FRACBITS; rowoffset += toptexture->GetHeight();
} }
} }
else else
{ // bottom of texture at bottom { // 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 else
@ -2205,16 +2206,16 @@ void R_NewWall (bool needlights)
rowoffset = -rowoffset; rowoffset = -rowoffset;
if (linedef->flags & ML_DONTPEGTOP) if (linedef->flags & ML_DONTPEGTOP)
{ // bottom of texture at top { // 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 else
{ // top of texture at bottom { // 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) if (toptexture->bWorldPanning)
{ {
rw_toptexturemid += xs_FloorToInt(rowoffset * yrepeat); rw_toptexturemid += rowoffset * yrepeat;
} }
else else
{ {
@ -2226,7 +2227,7 @@ void R_NewWall (bool needlights)
bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom), true); bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom), true);
rw_offset_bottom = sidedef->GetTextureXOffset(side_t::bottom); 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_bottomtexturescalex = FIXED2DBL(sidedef->GetTextureXScale(side_t::bottom));
rw_bottomtexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::bottom)); rw_bottomtexturescaley = FIXED2DBL(sidedef->GetTextureYScale(side_t::bottom));
yrepeat = fixed_t(bottomtexture->Scale.Y * rw_bottomtexturescaley); yrepeat = fixed_t(bottomtexture->Scale.Y * rw_bottomtexturescaley);
@ -2234,14 +2235,14 @@ void R_NewWall (bool needlights)
{ // normal orientation { // normal orientation
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
{ // bottom of texture at bottom { // bottom of texture at bottom
rw_bottomtexturemid = FLOAT2FIXED((rw_frontlowertop - ViewPos.Z) * yrepeat); rw_bottomtexturemid = (rw_frontlowertop - ViewPos.Z) * yrepeat;
} }
else else
{ // top of texture at top { // 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) if (rowoffset < 0 && bottomtexture != NULL)
{ {
rowoffset += bottomtexture->GetHeight() << FRACBITS; rowoffset += bottomtexture->GetHeight();
} }
} }
} }
@ -2250,16 +2251,16 @@ void R_NewWall (bool needlights)
rowoffset = -rowoffset; rowoffset = -rowoffset;
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
{ // top of texture at bottom { // top of texture at bottom
rw_bottomtexturemid = FLOAT2FIXED((rw_frontlowertop - ViewPos.Z) * yrepeat); rw_bottomtexturemid = (rw_frontlowertop - ViewPos.Z) * yrepeat;
} }
else else
{ // bottom of texture at top { // 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) if (bottomtexture->bWorldPanning)
{ {
rw_bottomtexturemid += xs_FloorToInt(rowoffset * yrepeat); rw_bottomtexturemid += rowoffset * yrepeat;
} }
else else
{ {
@ -2515,7 +2516,7 @@ void R_StoreWallRange (int start, int stop)
lwal = (fixed_t *)(openings + ds_p->maskedtexturecol); lwal = (fixed_t *)(openings + ds_p->maskedtexturecol);
swal = (fixed_t *)(openings + ds_p->swall); swal = (fixed_t *)(openings + ds_p->swall);
FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true); 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); fixed_t xoffset = sidedef->GetTextureXOffset(side_t::mid);
if (pic->bWorldPanning) if (pic->bWorldPanning)
@ -2529,20 +2530,23 @@ void R_StoreWallRange (int start, int stop)
*swal++ = swall[i]; *swal++ = swall[i];
} }
fixed_t istart = MulScale18 (*((fixed_t *)(openings + ds_p->swall)), yrepeat); double istart = *((fixed_t *)(openings + ds_p->swall)) * yscale / (1 << 18);
fixed_t iend = MulScale18 (*(swal - 1), yrepeat); double iend = *(swal - 1) * yscale / (1 << 18);
#if 0
if (istart < 3 && istart >= 0) istart = 3; ///This was for avoiding overflow when using fixed point. It might not be needed anymore.
if (istart > -3 && istart < 0) istart = -3; const double mini = 3 / 65536.0;
if (iend < 3 && iend >= 0) iend = 3; if (istart < mini && istart >= 0) istart = mini;
if (iend > -3 && iend < 0) iend = -3; if (istart > -mini && istart < 0) istart = -mini;
istart = DivScale32 (1, istart); if (iend < mini && iend >= 0) iend = mini;
iend = DivScale32 (1, iend); if (iend > -mini && iend < 0) iend = -mini;
ds_p->yrepeat = yrepeat; #endif
ds_p->iscale = istart; istart = 1 / istart;
iend = 1 / iend;
ds_p->yscale = (float)yscale;
ds_p->iscale = (float)istart;
if (stop - start > 0) if (stop - start > 0)
{ {
ds_p->iscalestep = (iend - istart) / (stop - start); ds_p->iscalestep = float((iend - istart) / (stop - start));
} }
else else
{ {
@ -3182,7 +3186,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
} }
topoff = WallSpriteTile->TopOffset << FRACBITS; 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 // Clip sprite to drawseg
x1 = MAX<int>(clipper->x1, x1); x1 = MAX<int>(clipper->x1, x1);
@ -3232,7 +3236,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper,
{ {
sprflipvert = true; sprflipvert = true;
yscale = -yscale; yscale = -yscale;
dc_texturemid = dc_texturemid - (WallSpriteTile->GetHeight() << FRACBITS); dc_texturemid -= WallSpriteTile->GetHeight();
} }
else else
{ {

View file

@ -40,7 +40,7 @@
// //
FTextureID skyflatnum; FTextureID skyflatnum;
FTextureID sky1texture, sky2texture; FTextureID sky1texture, sky2texture;
fixed_t skytexturemid; double skytexturemid;
fixed_t skyscale; fixed_t skyscale;
fixed_t skyiscale; fixed_t skyiscale;
bool skystretch; bool skystretch;
@ -103,11 +103,11 @@ void R_InitSkyMap ()
&& skyheight >= 128 && skyheight >= 128
&& level.IsFreelookAllowed() && level.IsFreelookAllowed()
&& !(level.flags & LEVEL_FORCENOSKYSTRETCH)) ? 1 : 0; && !(level.flags & LEVEL_FORCENOSKYSTRETCH)) ? 1 : 0;
skytexturemid = -28*FRACUNIT; skytexturemid = -28;
} }
else if (skyheight > 200) else if (skyheight > 200)
{ {
skytexturemid = FLOAT2FIXED((200 - skyheight) * skytex1->Scale.Y); skytexturemid = (200 - skyheight) * skytex1->Scale.Y;
} }
if (viewwidth != 0 && viewheight != 0) if (viewwidth != 0 && viewheight != 0)
@ -124,7 +124,7 @@ void R_InitSkyMap ()
{ {
skyscale = Scale(skyscale, SKYSTRETCH_HEIGHT, skyheight); skyscale = Scale(skyscale, SKYSTRETCH_HEIGHT, skyheight);
skyiscale = Scale(skyiscale, skyheight, SKYSTRETCH_HEIGHT); 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, // The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees,

View file

@ -29,7 +29,7 @@ extern FTextureID skyflatnum;
extern fixed_t sky1cyl, sky2cyl; extern fixed_t sky1cyl, sky2cyl;
extern FTextureID sky1texture, sky2texture; extern FTextureID sky1texture, sky2texture;
extern double sky1pos, sky2pos; extern double sky1pos, sky2pos;
extern fixed_t skytexturemid; extern double skytexturemid;
extern fixed_t skyiscale; extern fixed_t skyiscale;
extern fixed_t skyscale; extern fixed_t skyscale;
extern bool skystretch; extern bool skystretch;

View file

@ -237,22 +237,23 @@ vissprite_t *R_NewVisSprite (void)
short* mfloorclip; short* mfloorclip;
short* mceilingclip; short* mceilingclip;
fixed_t spryscale; double spryscale;
fixed_t sprtopscreen; double sprtopscreen;
bool sprflipvert; bool sprflipvert;
void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span) 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) while (span->Length != 0)
{ {
const int length = span->Length; const int length = span->Length;
const int top = span->TopOffset; const int top = span->TopOffset;
// calculate unclipped screen coordinates for post // calculate unclipped screen coordinates for post
dc_yl = (sprtopscreen + spryscale * top) >> FRACBITS; dc_yl = xs_RoundToInt(sprtopscreen + spryscale * top);
dc_yh = (sprtopscreen + spryscale * (top + length) - FRACUNIT) >> FRACBITS; dc_yh = xs_RoundToInt(sprtopscreen + spryscale * (top + length)) - 1;
if (sprflipvert) if (sprflipvert)
{ {
@ -273,7 +274,7 @@ void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span)
if (sprflipvert) if (sprflipvert)
{ {
dc_texturefrac = (dc_yl*dc_iscale) - (top << FRACBITS) 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; const fixed_t maxfrac = length << FRACBITS;
while (dc_texturefrac >= maxfrac) while (dc_texturefrac >= maxfrac)
{ {
@ -291,7 +292,7 @@ void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *span)
} }
else else
{ {
dc_texturefrac = dc_texturemid - (top << FRACBITS) dc_texturefrac = texturemid - (top << FRACBITS)
+ (dc_yl*dc_iscale) - FixedMul (centeryfrac-FRACUNIT, dc_iscale); + (dc_yl*dc_iscale) - FixedMul (centeryfrac-FRACUNIT, dc_iscale);
while (dc_texturefrac < 0) while (dc_texturefrac < 0)
{ {
@ -433,24 +434,23 @@ void R_DrawVisSprite (vissprite_t *vis)
tex = vis->pic; tex = vis->pic;
spryscale = vis->yscale; spryscale = vis->yscale;
sprflipvert = false; sprflipvert = false;
dc_iscale = 0xffffffffu / (unsigned)vis->yscale; dc_iscale = FLOAT2FIXED(1 / vis->yscale);
frac = vis->startfrac; frac = vis->startfrac;
xiscale = vis->xiscale; xiscale = vis->xiscale;
dc_texturemid = vis->texturemid; dc_texturemid = vis->texturemid;
if (vis->renderflags & RF_YFLIP) if (vis->renderflags & RF_YFLIP)
{ {
sprflipvert = true; sprflipvert = true;
spryscale = -spryscale; spryscale = -spryscale;
dc_iscale = -dc_iscale; dc_iscale = -dc_iscale;
dc_texturemid -= (vis->pic->GetHeight() << FRACBITS); dc_texturemid -= vis->pic->GetHeight();
sprtopscreen = centeryfrac + FixedMul(dc_texturemid, spryscale); sprtopscreen = CenterY + dc_texturemid * spryscale;
} }
else else
{ {
sprflipvert = false; sprflipvert = false;
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); sprtopscreen = CenterY - dc_texturemid * spryscale;
} }
dc_x = vis->x1; dc_x = vis->x1;
@ -500,7 +500,7 @@ void R_DrawVisSprite (vissprite_t *vis)
void R_DrawWallSprite(vissprite_t *spr) void R_DrawWallSprite(vissprite_t *spr)
{ {
int x1, x2; int x1, x2;
fixed_t yscale; double iyscale;
x1 = MAX<int>(spr->x1, spr->wallc.sx1); x1 = MAX<int>(spr->x1, spr->wallc.sx1);
x2 = MIN<int>(spr->x2, spr->wallc.sx2); x2 = MIN<int>(spr->x2, spr->wallc.sx2);
@ -508,8 +508,8 @@ void R_DrawWallSprite(vissprite_t *spr)
return; return;
WallT.InitFromWallCoords(&spr->wallc); WallT.InitFromWallCoords(&spr->wallc);
PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2); PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2);
yscale = spr->yscale; iyscale = 1 / spr->yscale;
dc_texturemid = FixedDiv(FLOAT2FIXED(spr->gzt - ViewPos.Z), yscale); dc_texturemid = (spr->gzt - ViewPos.Z) * iyscale;
if (spr->renderflags & RF_XFLIP) if (spr->renderflags & RF_XFLIP)
{ {
int right = (spr->pic->GetWidth() << FRACBITS) - 1; int right = (spr->pic->GetWidth() << FRACBITS) - 1;
@ -550,8 +550,8 @@ void R_DrawWallSprite(vissprite_t *spr)
if (spr->renderflags & RF_YFLIP) if (spr->renderflags & RF_YFLIP)
{ {
sprflipvert = true; sprflipvert = true;
yscale = -yscale; iyscale = -iyscale;
dc_texturemid = dc_texturemid - (spr->pic->GetHeight() << FRACBITS); dc_texturemid -= spr->pic->GetHeight();
} }
else else
{ {
@ -559,7 +559,7 @@ void R_DrawWallSprite(vissprite_t *spr)
} }
// rw_offset is used as the texture's vertical scale // 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; dc_x = x1;
ESPSResult mode; 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); dc_iscale = MulScale16 (swall[dc_x], rw_offset);
spryscale = SafeDivScale32 (1, dc_iscale); spryscale = SafeDivScale32 (1, dc_iscale);
if (sprflipvert) if (sprflipvert)
sprtopscreen = FLOAT2FIXED(CenterY) + FixedMul (dc_texturemid, spryscale); sprtopscreen = CenterY + dc_texturemid * spryscale;
else else
sprtopscreen = FLOAT2FIXED(CenterY) - FixedMul (dc_texturemid, spryscale); sprtopscreen = CenterY - dc_texturemid * spryscale;
const BYTE *column; const BYTE *column;
const FTexture::Span *spans; 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. // Render the voxel, either directly to the screen or offscreen.
R_DrawVoxel(spr->vpos, spr->vang, spr->gpos, spr->angle, 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); minslabz, maxslabz, flags);
// Blend the voxel, if that's what we need to do. // 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; xscale = spriteScale.X * xscale / tex->Scale.X;
iscale = (tex->GetWidth() << FRACBITS) / (x2 - x1); 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 // store information in a vissprite
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->CurrentPortalUniq = CurrentPortalUniq; vis->CurrentPortalUniq = CurrentPortalUniq;
vis->xscale = FLOAT2FIXED(xscale); vis->xscale = FLOAT2FIXED(xscale);
vis->yscale = fixed_t(InvZtoScale * yscale / tz); vis->yscale = float(InvZtoScale * yscale / tz);
vis->idepth = float(1 / tz); vis->idepth = float(1 / tz);
vis->floorclip = FixedDiv (FLOAT2FIXED(thing->Floorclip), yscale); vis->floorclip = thing->Floorclip / yscale;
vis->texturemid = (tex->TopOffset << FRACBITS) - FixedDiv(FLOAT2FIXED(ViewPos.Z - pos.Z + thing->Floorclip), yscale); vis->texturemid = tex->TopOffset - (ViewPos.Z - pos.Z + thing->Floorclip) / yscale;
vis->x1 = x1 < WindowLeft ? WindowLeft : x1; vis->x1 = x1 < WindowLeft ? WindowLeft : x1;
vis->x2 = x2 > WindowRight ? WindowRight : x2; vis->x2 = x2 > WindowRight ? WindowRight : x2;
vis->angle = thing->Angles.Yaw.BAMs(); vis->angle = thing->Angles.Yaw.BAMs();
@ -1017,11 +1017,11 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor
vis->CurrentPortalUniq = CurrentPortalUniq; vis->CurrentPortalUniq = CurrentPortalUniq;
vis->xscale = FLOAT2FIXED(xscale); vis->xscale = FLOAT2FIXED(xscale);
vis->yscale = FLOAT2FIXED(yscale); vis->yscale = (float)yscale;
vis->x1 = WindowLeft; vis->x1 = WindowLeft;
vis->x2 = WindowRight; vis->x2 = WindowRight;
vis->idepth = 1 / MINZ; vis->idepth = 1 / MINZ;
vis->floorclip = FLOAT2FIXED(thing->Floorclip); vis->floorclip = thing->Floorclip;
pos.Z -= 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->CurrentPortalUniq = CurrentPortalUniq;
vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1; vis->x1 = wallc.sx1 < WindowLeft ? WindowLeft : wallc.sx1;
vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2; vis->x2 = wallc.sx2 >= WindowRight ? WindowRight : wallc.sx2;
vis->yscale = FLOAT2FIXED(scale.Y); vis->yscale = (float)scale.Y;
vis->idepth = float(1 / tz); vis->idepth = float(1 / tz);
vis->depth = (float)tz; vis->depth = (float)tz;
vis->sector = thing->Sector; 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->renderflags = owner->renderflags;
vis->floorclip = 0; 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 || if (camera->player && (RenderTarget != screen ||
viewheight == RenderTarget->GetHeight() || 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()) if (RenderTarget != screen || viewheight == RenderTarget->GetHeight())
{ {
vis->texturemid -= FLOAT2FIXED(weapon->YAdjust); vis->texturemid -= weapon->YAdjust;
} }
else 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->x1 = x1 < 0 ? 0 : x1;
vis->x2 = x2 >= viewwidth ? viewwidth : x2; vis->x2 = x2 >= viewwidth ? viewwidth : x2;
vis->xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X); 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->Translation = 0; // [RH] Use default colors
vis->pic = tex; vis->pic = tex;
vis->ColormapNum = 0; vis->ColormapNum = 0;
@ -1655,9 +1655,9 @@ void R_DrawRemainingPlayerSprites()
} }
screen->DrawTexture(vis->pic, screen->DrawTexture(vis->pic,
viewwindowx + VisPSpritesX1[i], 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_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_Translation, TranslationToTable(vis->Translation),
DTA_FlipX, flip, DTA_FlipX, flip,
DTA_TopOffset, 0, 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 // killough 3/27/98: end special clipping for deep water / fake ceilings
else if (!spr->bIsVoxel && spr->floorclip) else if (!spr->bIsVoxel && spr->floorclip)
{ // [RH] Move floorclip stuff from R_DrawVisSprite to here { // [RH] Move floorclip stuff from R_DrawVisSprite to here
int clip = ((FLOAT2FIXED(CenterY) - FixedMul (spr->texturemid - //int clip = ((FLOAT2FIXED(CenterY) - FixedMul (spr->texturemid - (spr->pic->GetHeight() << FRACBITS) + spr->floorclip, spr->yscale)) >> FRACBITS);
(spr->pic->GetHeight() << FRACBITS) + int clip = xs_RoundToInt(CenterY - (spr->texturemid - spr->pic->GetHeight() + spr->floorclip) * spr->yscale);
spr->floorclip, spr->yscale)) >> FRACBITS);
if (clip < botclip) if (clip < botclip)
{ {
botclip = MAX<short> (0, clip); botclip = MAX<short>(0, clip);
} }
} }
@ -2295,8 +2294,8 @@ void R_DrawSprite (vissprite_t *spr)
{ {
clearbufshort(cliptop + x2, viewwidth - x2, viewheight); clearbufshort(cliptop + x2, viewwidth - x2, viewheight);
} }
int minvoxely = spr->gzt <= hzt ? 0 : FLOAT2FIXED(spr->gzt - hzt) / spr->yscale; int minvoxely = spr->gzt <= hzt ? 0 : xs_RoundToInt((spr->gzt - hzt) / spr->yscale);
int maxvoxely = spr->gzb > hzb ? INT_MAX : FLOAT2FIXED(spr->gzt - hzb) / spr->yscale; int maxvoxely = spr->gzb > hzb ? INT_MAX : xs_RoundToInt((spr->gzt - hzb) / spr->yscale);
R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot); R_DrawVisVoxel(spr, minvoxely, maxvoxely, cliptop, clipbot);
} }
spr->Style.colormap = colormap; spr->Style.colormap = colormap;
@ -2526,8 +2525,9 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade,
vis = R_NewVisSprite (); vis = R_NewVisSprite ();
vis->CurrentPortalUniq = CurrentPortalUniq; vis->CurrentPortalUniq = CurrentPortalUniq;
vis->heightsec = heightsec; vis->heightsec = heightsec;
vis->yscale = vis->xscale = FLOAT2FIXED(xscale); vis->xscale = FLOAT2FIXED(xscale);
// vis->yscale = FixedMul (xscale, InvZtoScale); vis->yscale = (float)xscale;
// vis->yscale *= InvZtoScale;
vis->depth = (float)tz; vis->depth = (float)tz;
vis->idepth = float(1 / tz); vis->idepth = float(1 / tz);
vis->gpos = { (float)particle->Pos.X, (float)particle->Pos.Y, (float)particle->Pos.Z }; vis->gpos = { (float)particle->Pos.X, (float)particle->Pos.Y, (float)particle->Pos.Z };

View file

@ -39,12 +39,13 @@ struct vissprite_t
int y1, y2; // top / bottom of particle on screen int y1, y2; // top / bottom of particle on screen
}; };
angle_t angle; angle_t angle;
fixed_t xscale, yscale; fixed_t xscale;
float yscale;
float depth; float depth;
float idepth; // 1/z float idepth; // 1/z
float deltax, deltay; float deltax, deltay;
DWORD FillColor; DWORD FillColor;
fixed_t floorclip; double floorclip;
union union
{ {
FTexture *pic; FTexture *pic;
@ -55,7 +56,7 @@ struct vissprite_t
// Used by face sprites // Used by face sprites
struct struct
{ {
fixed_t texturemid; double texturemid;
fixed_t startfrac; // horizontal position of x1 fixed_t startfrac; // horizontal position of x1
fixed_t xiscale; // negative if flipped fixed_t xiscale; // negative if flipped
}; };
@ -108,8 +109,8 @@ extern short screenheightarray[MAXWIDTH];
// vars for R_DrawMaskedColumn // vars for R_DrawMaskedColumn
extern short* mfloorclip; extern short* mfloorclip;
extern short* mceilingclip; extern short* mceilingclip;
extern fixed_t spryscale; extern double spryscale;
extern fixed_t sprtopscreen; extern double sprtopscreen;
extern bool sprflipvert; extern bool sprflipvert;
extern double pspritexscale; extern double pspritexscale;

View file

@ -202,30 +202,23 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
double centeryback = CenterY; double centeryback = CenterY;
CenterY = 0; CenterY = 0;
sprtopscreen = FLOAT2FIXED(y0);
// There is not enough precision in the drawing routines to keep the full // There is not enough precision in the drawing routines to keep the full
// precision for y0. :( // precision for y0. :(
sprtopscreen &= ~(FRACUNIT - 1); double dummy;
sprtopscreen = modf(y0, &dummy);
double yscale = parms.destheight / img->GetHeight(); double yscale = parms.destheight / img->GetHeight();
double iyscale = 1 / yscale; double iyscale = 1 / yscale;
spryscale = FLOAT2FIXED(yscale); spryscale = yscale;
assert(spryscale > 2); assert(spryscale > 0);
#if 0
// Fix precision errors that are noticeable at some resolutions
if ((y0 + parms.destheight) > (y0 + yscale * img->GetHeight()))
{
spryscale++;
}
#endif
sprflipvert = false; sprflipvert = false;
//dc_iscale = FLOAT2FIXED(iyscale); //dc_iscale = FLOAT2FIXED(iyscale);
//dc_texturemid = FLOAT2FIXED((-y0) * iyscale); //dc_texturemid = (-y0) * iyscale;
//dc_iscale = 0xffffffffu / (unsigned)spryscale; //dc_iscale = 0xffffffffu / (unsigned)spryscale;
dc_iscale = DivScale32(1, spryscale); dc_iscale = FLOAT2FIXED(1 / spryscale);
dc_texturemid = FixedMul(-sprtopscreen, dc_iscale) + xs_ToInt((CenterY - 1) * dc_iscale); dc_texturemid = (CenterY - 1 - sprtopscreen) * dc_iscale / 65536;
fixed_t frac = 0; fixed_t frac = 0;
double xiscale = img->GetWidth() / parms.destwidth; double xiscale = img->GetWidth() / parms.destwidth;
double x2 = x0 + parms.destwidth; double x2 = x0 + parms.destwidth;

View file

@ -87,14 +87,14 @@ public:
// ==================================================================================================================== // ====================================================================================================================
// Basic Conversion from Numbers // Basic Conversion from Numbers
// ==================================================================================================================== // ====================================================================================================================
finline static Fix ToFix (int32_t val) {return val<<N;} finline static Fix ToFix (int32_t val) {return val<<N;}
finline static Fix ToFix (real64 val) {return xs_ConvertToFixed(val);} finline static Fix ToFix (real64 val) {return xs_ConvertToFixed(val);}
// ==================================================================================================================== // ====================================================================================================================
// Basic Conversion to Numbers // Basic Conversion to Numbers
// ==================================================================================================================== // ====================================================================================================================
finline static real64 ToReal (Fix f) {return real64(f)/real64(1<<N);} finline static real64 ToReal (Fix f) {return real64(f)/real64(1<<N);}
finline static int32_t ToInt (Fix f) {return f>>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<<n));
#else
return (long)((val)*(1<<N));
#endif
}