diff --git a/src/farchive.cpp b/src/farchive.cpp index 477d227186..fc3d75bbbb 100644 --- a/src/farchive.cpp +++ b/src/farchive.cpp @@ -1054,6 +1054,12 @@ FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize) FArchive &FArchive::SerializeObject (DObject *&object, PClass *type) { + if (!m_ThinkersAllowed && type->IsDescendantOf(RUNTIME_CLASS(DThinker))) + { + assert(true); + I_Error("Tried to serialize a thinker before P_SerializeThinkers"); + } + if (!type->IsDescendantOf(RUNTIME_CLASS(PClass))) { // a regular object if (IsStoring()) diff --git a/src/farchive.h b/src/farchive.h index b6722986a3..44ae8c001e 100644 --- a/src/farchive.h +++ b/src/farchive.h @@ -216,6 +216,16 @@ inline FArchive& operator<< (signed char *&str) { return operator<< ((char *&)st inline FArchive& operator<< (bool &b) { return operator<< ((BYTE &)b); } inline FArchive& operator<< (DObject* &object) { return ReadObject (object, RUNTIME_CLASS(DObject)); } + void EnableThinkers() + { + m_ThinkersAllowed = true; + } + + bool ThinkersAllowed() + { + return m_ThinkersAllowed; + } + protected: enum { EObjectHashSize = 137 }; @@ -253,6 +263,7 @@ protected: int *m_SpriteMap; size_t m_NumSprites; + bool m_ThinkersAllowed = false; FArchive (); void AttachToFile (FFile &file); diff --git a/src/g_shared/a_quake.cpp b/src/g_shared/a_quake.cpp index 1d11171254..7908c907cf 100644 --- a/src/g_shared/a_quake.cpp +++ b/src/g_shared/a_quake.cpp @@ -72,10 +72,7 @@ void DEarthquake::Serialize (FArchive &arc) << m_QuakeSFX << m_Flags << m_CountdownStart << m_WaveSpeed << m_Falloff << m_Highpoint << m_MiniCount; - if (SaveVersion >= 4544) - { - arc << m_RollIntensity << m_RollWave; - } + << m_RollIntensity << m_RollWave; } //========================================================================== diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index fdefa19874..e32a98e4b8 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -428,7 +428,6 @@ void P_SerializeWorld (FArchive &arc) << si->LeftSide << si->RightSide << si->Index; - DBaseDecal::SerializeChain (arc, &si->AttachedDecals); } } @@ -457,6 +456,7 @@ void P_SerializeWorldActors(FArchive &arc) { int i; sector_t *sec; + line_t *line; for (i = 0, sec = sectors; i < numsectors; i++, sec++) { @@ -470,6 +470,16 @@ void P_SerializeWorldActors(FArchive &arc) { arc << s.mSkybox; } + for (i = 0, line = lines; i < numlines; i++, line++) + { + for (int s = 0; s < 2; s++) + { + if (line->sidedef[s] != NULL) + { + DBaseDecal::SerializeChain(arc, &line->sidedef[s]->AttachedDecals); + } + } + } } void extsector_t::Serialize(FArchive &arc) @@ -509,6 +519,7 @@ FArchive &operator<< (FArchive &arc, sector_t::splane &p) void P_SerializeThinkers (FArchive &arc, bool hubLoad) { + arc.EnableThinkers(); DImpactDecal::SerializeTime (arc); DThinker::SerializeAll (arc, hubLoad); } diff --git a/src/r_main.cpp b/src/r_main.cpp index fdeffb93b0..58e94e5445 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -501,63 +501,61 @@ void R_SetupColormap(player_t *player) void R_SetupFreelook() { - { - double dy; + double dy; - if (camera != NULL) + if (camera != NULL) + { + dy = FocalLengthY * (-ViewPitch).Tan(); + } + else + { + dy = 0; + } + + CenterY = (viewheight / 2.0) + dy; + centery = xs_ToInt(CenterY); + globaluclip = -CenterY / InvZtoScale; + globaldclip = (viewheight - CenterY) / InvZtoScale; + + //centeryfrac &= 0xffff0000; + int e, i; + + i = 0; + e = viewheight; + float focus = float(FocalLengthY); + float den; + float cy = float(CenterY); + if (i < centery) + { + den = cy - i - 0.5f; + if (e <= centery) { - dy = FocalLengthY * (-ViewPitch).Tan(); - } - else - { - dy = 0; - } - - CenterY = (viewheight / 2.0) + dy; - centery = xs_ToInt(CenterY); - globaluclip = -CenterY / InvZtoScale; - globaldclip = (viewheight - CenterY) / InvZtoScale; - - //centeryfrac &= 0xffff0000; - int e, i; - - i = 0; - e = viewheight; - float focus = float(FocalLengthY); - float den; - float cy = float(CenterY); - if (i < centery) - { - den = cy - i - 0.5f; - if (e <= centery) - { - do { - yslope[i] = FLOAT2FIXED(focus / den); - den -= 1; - } while (++i < e); - } - else - { - do { - yslope[i] = FLOAT2FIXED(focus / den); - den -= 1; - } while (++i < centery); - den = i - cy + 0.5f; - do { - yslope[i] = FLOAT2FIXED(focus / den); - den += 1; - } while (++i < e); - } + do { + yslope[i] = focus / den; + den -= 1; + } while (++i < e); } else { + do { + yslope[i] = focus / den; + den -= 1; + } while (++i < centery); den = i - cy + 0.5f; do { - yslope[i] = FLOAT2FIXED(focus / den); + yslope[i] = focus / den; den += 1; } while (++i < e); } } + else + { + den = i - cy + 0.5f; + do { + yslope[i] = focus / den; + den += 1; + } while (++i < e); + } } //========================================================================== diff --git a/src/r_plane.cpp b/src/r_plane.cpp index d18ad19a5e..2fb90fa6f4 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -141,10 +141,10 @@ fixed_t pviewx, pviewy; void R_DrawTiltedPlane_ASM (int y, int x1); } -fixed_t yslope[MAXHEIGHT]; +float yslope[MAXHEIGHT]; static fixed_t xscale, yscale; -static DWORD xstepscale, ystepscale; -static DWORD basexfrac, baseyfrac; +static double xstepscale, ystepscale; +static double basexfrac, baseyfrac; #ifdef X86_ASM extern "C" void R_SetSpanSource_ASM (const BYTE *flat); @@ -205,7 +205,7 @@ void R_DeinitPlanes () void R_MapPlane (int y, int x1) { int x2 = spanend[y]; - fixed_t distance; + double distance; #ifdef RANGECHECK if (x2 < x1 || x1<0 || x2>=viewwidth || (unsigned)y>=(unsigned)viewheight) @@ -217,12 +217,12 @@ void R_MapPlane (int y, int x1) // [RH] Notice that I dumped the caching scheme used by Doom. // It did not offer any appreciable speedup. - distance = xs_ToInt(planeheight * yslope[y]); + distance = planeheight * yslope[y]; - ds_xstep = FixedMul (distance, xstepscale); - ds_ystep = FixedMul (distance, ystepscale); - ds_xfrac = FixedMul (distance, basexfrac) + pviewx; - ds_yfrac = FixedMul (distance, baseyfrac) + pviewy; + ds_xstep = xs_ToFixed(32-ds_xbits, distance * xstepscale); + ds_ystep = xs_ToFixed(32-ds_ybits, distance * ystepscale); + ds_xfrac = xs_ToFixed(32-ds_xbits, distance * basexfrac) + pviewx; + ds_yfrac = xs_ToFixed(32-ds_ybits, distance * baseyfrac) + pviewy; if (plane_shade) { @@ -1495,12 +1495,15 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t return; } - DAngle planeang = pl->xform.Angle + pl->xform.baseAngle; + double planeang = (pl->xform.Angle + pl->xform.baseAngle).Radians(); + double xstep, ystep, leftxfrac, leftyfrac, rightxfrac, rightyfrac; + double x; + xscale = xs_ToFixed(32 - ds_xbits, _xscale); yscale = xs_ToFixed(32 - ds_ybits, _yscale); if (planeang != 0) { - double cosine = cos(planeang.Radians()), sine = sin(planeang.Radians()); + double cosine = cos(planeang), sine = sin(planeang); pviewx = FLOAT2FIXED(pl->xform.xOffs + ViewPos.X * cosine - ViewPos.Y * sine); pviewy = FLOAT2FIXED(pl->xform.yOffs - ViewPos.X * sine - ViewPos.Y * cosine); } @@ -1514,23 +1517,32 @@ void R_DrawNormalPlane (visplane_t *pl, double _xscale, double _yscale, fixed_t pviewy = FixedMul (yscale, pviewy); // left to right mapping - planeang = ViewAngle - 90 + planeang; + planeang += (ViewAngle - 90).Radians(); // Scale will be unit scale at FocalLengthX (normally SCREENWIDTH/2) distance - xstepscale = xs_RoundToInt(xscale * cos(planeang.Radians()) / FocalLengthX); - ystepscale = xs_RoundToInt(yscale * -sin(planeang.Radians()) / FocalLengthX); + xstep = cos(planeang) / FocalLengthX; + ystep = -sin(planeang) / FocalLengthX; // [RH] flip for mirrors if (MirrorFlags & RF_XFLIP) { - xstepscale = (DWORD)(-(SDWORD)xstepscale); - ystepscale = (DWORD)(-(SDWORD)ystepscale); + xstep = -xstep; + ystep = -ystep; } - int x = pl->right - centerx; - planeang += 90; - basexfrac = xs_RoundToInt(xscale * cos(planeang.Radians())) + x*xstepscale; - baseyfrac = xs_RoundToInt(yscale * -sin(planeang.Radians())) + x*ystepscale; + planeang += M_PI/2; + double cosine = cos(planeang), sine = -sin(planeang); + x = pl->right - centerx - 0.5; + rightxfrac = _xscale * (cosine + x * xstep); + rightyfrac = _yscale * (sine + x * ystep); + x = pl->left - centerx - 0.5; + leftxfrac = _xscale * (cosine + x * xstep); + leftyfrac = _yscale * (sine + x * ystep); + + basexfrac = rightxfrac; + baseyfrac = rightyfrac; + xstepscale = (rightxfrac - leftxfrac) / (pl->right - pl->left); + ystepscale = (rightyfrac - leftyfrac) / (pl->right - pl->left); planeheight = fabs(pl->height.Zat0() - ViewPos.Z); diff --git a/src/r_plane.h b/src/r_plane.h index fcd02ed68f..d4db3dc09c 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -80,7 +80,7 @@ extern planefunction_t ceilingfunc_t; extern short floorclip[MAXWIDTH]; extern short ceilingclip[MAXWIDTH]; -extern fixed_t yslope[MAXHEIGHT]; +extern float yslope[MAXHEIGHT]; void R_InitPlanes (); void R_DeinitPlanes (); diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 546544f81d..4c91a13147 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -231,6 +231,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) double texheight, texheightscale; bool notrelevant = false; double rowoffset; + bool wrap = false; const sector_t *sec; @@ -334,8 +335,8 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid); - if (!(curline->linedef->flags & ML_WRAP_MIDTEX) && - !(curline->sidedef->Flags & WALLF_WRAP_MIDTEX)) + wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX); + if (!wrap) { // Texture does not wrap vertically. double textop; @@ -482,7 +483,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) { // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. - dc_texturemid = (dc_texturemid + rowoffset - ViewPos.Z) * MaskedScaleY; + dc_texturemid = (dc_texturemid - ViewPos.Z + rowoffset) * MaskedScaleY; } else { @@ -543,8 +544,11 @@ clearfog: { if (fake3D & FAKE3D_REFRESHCLIP) { - assert(ds->bkup >= 0); - memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2 - ds->x1) * 2); + if (!wrap) + { + assert(ds->bkup >= 0); + memcpy(openings + ds->sprtopclip, openings + ds->bkup, (ds->x2 - ds->x1) * 2); + } } else { @@ -1134,7 +1138,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); dovline1(); } @@ -1153,7 +1157,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l bufplce[z] = getcol (rw_pic, (lwal[x+z] + xoffset) >> FRACBITS); iscale = swal[x + z] * yrepeat; vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 1)); + vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 0.5)); } if (bad == 15) { @@ -1229,7 +1233,7 @@ void wallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *l dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); dovline1(); } @@ -1484,7 +1488,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); domvline1(); } @@ -1501,7 +1505,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ bufplce[z] = getcol (rw_pic, (lwal[dax] + xoffset) >> FRACBITS); iscale = swal[dax] * yrepeat; vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 1)); + vplce[z] = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[z] - CenterY + 0.5)); } if (bad == 15) { @@ -1575,7 +1579,7 @@ void maskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, fixed_ dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); domvline1(); } @@ -1660,7 +1664,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); tmvline1(); } @@ -1677,7 +1681,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f bufplce[z] = getcol (rw_pic, (lwal[dax] + xoffset) >> FRACBITS); iscale = swal[dax] * yrepeat; vince[z] = xs_ToFixed(fracbits, iscale); - vplce[z] = xs_ToFixed(fracbits, dc_texturemid + vince[z] * (y1ve[z] - CenterY + 1)); + vplce[z] = xs_ToFixed(fracbits, dc_texturemid + vince[z] * (y1ve[z] - CenterY + 0.5)); } if (bad == 15) { @@ -1754,7 +1758,7 @@ void transmaskwallscan (int x1, int x2, short *uwal, short *dwal, float *swal, f dc_count = y2ve[0] - y1ve[0]; iscale = swal[x] * yrepeat; dc_iscale = xs_ToFixed(fracbits, iscale); - dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 1)); + dc_texturefrac = xs_ToFixed(fracbits, dc_texturemid + iscale * (y1ve[0] - CenterY + 0.5)); tmvline1(); } @@ -2683,7 +2687,6 @@ int OWallMost (short *mostbuf, double z, const FWallCoords *wallc) } ix1 = wallc->sx1; iy1 = wallc->sz1; ix2 = wallc->sx2; iy2 = wallc->sz2; -#if 1 if (bad & 3) { // the line intersects the top of the screen double t = (z-s1) / (s2-s1); @@ -2728,40 +2731,8 @@ int OWallMost (short *mostbuf, double z, const FWallCoords *wallc) else { fixed_t yinc = FLOAT2FIXED(((z * InvZtoScale / iy2) - y) / (ix2 - ix1)); - qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY), yinc); + qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY) + FRACUNIT/2, yinc); } -#else - double max = viewheight; - double zz = z / 65536.0; -#if 0 - double z1 = zz * InvZtoScale / wallc->sz1; - double z2 = zz * InvZtoScale / wallc->sz2 - z1; - z2 /= (wallc->sx2 - wallc->sx1); - z1 += centeryfrac / 65536.0; - - for (int x = wallc->sx1; x < wallc->sx2; ++x) - { - mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); - z1 += z2; - } -#else - double top, bot, i; - - i = wallc->sx1 - centerx; - top = WallT.UoverZorg + WallT.UoverZstep * i; - bot = WallT.InvZorg + WallT.InvZstep * i; - double cy = centeryfrac / 65536.0; - - for (int x = wallc->sx1; x < wallc->sx2; x++) - { - double frac = top / bot; - double scale = frac * WallT.DepthScale + WallT.DepthOrg; - mostbuf[x] = xs_RoundToInt(clamp(zz / scale + cy, 0.0, max)); - top += WallT.UoverZstep; - bot += WallT.InvZstep; - } -#endif -#endif return bad; } @@ -2914,7 +2885,7 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) else { fixed_t yinc = FLOAT2FIXED(((z2 * InvZtoScale / iy2) - y) / (ix2-ix1)); - qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY), yinc); + qinterpolatedown16short (&mostbuf[ix1], ix2-ix1, FLOAT2FIXED(y + CenterY) + FRACUNIT/2, yinc); } return bad; diff --git a/src/version.h b/src/version.h index 47f3a347c3..7f998adeaf 100644 --- a/src/version.h +++ b/src/version.h @@ -72,11 +72,11 @@ const char *GetVersionString(); // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 4543 +#define MINSAVEVER 4545 // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4544 +#define SAVEVER 4545 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x) diff --git a/wadsrc/static/xlat/eternity.txt b/wadsrc/static/xlat/eternity.txt index bfdac2cecf..bc5159d11b 100644 --- a/wadsrc/static/xlat/eternity.txt +++ b/wadsrc/static/xlat/eternity.txt @@ -231,3 +231,6 @@ enum 444 = 0, Teleport(0) 445 = 0, Teleport_NoFog(0) 446 = 0, Teleport_Line(0) +447 = 0, Exit_Normal(0) +448 = 0, Exit_Secret(0) +449 = 0, Teleport_NewMap(0)