diff --git a/docs/rh-log.txt b/docs/rh-log.txt index a99a9204c..498f552d2 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,11 @@ +June 11, 2008 (Changes by Graf Zahl) +- Fixed: Wall scrolling interpolations incremented their reference count twice. +- Fixed: Before a level's thinkers are loaded all previous interpolations must + be cleared. +- Fixed: deleted interpolations didn't NULL the pointer in the interpolated + object. Also added all interpolation pointers to DSectorMarker to ensure + that they are properyl processed by the garbage collector. + June 10, 2008 (Changes by Graf Zahl) - Added scaling to double size for idmypos display. - Changed: Players don't telefrag when they are spawned now but after all diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index ca3344c14..ac59004e1 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -93,6 +93,8 @@ // Number of sectors to mark for each step. #define SECTORSTEPSIZE 32 +#define POLYSTEPSIZE 120 +#define SIDEDEFSTEPSIZE 240 #define GCSTEPSIZE 1024u #define GCSWEEPMAX 40 @@ -108,9 +110,11 @@ class DSectorMarker : public DObject { DECLARE_CLASS(DSectorMarker, DObject) public: - DSectorMarker() : SecNum(0) {} + DSectorMarker() : SecNum(0),PolyNum(0),SideNum(0) {} size_t PropagateMark(); int SecNum; + int PolyNum; + int SideNum; }; IMPLEMENT_CLASS(DSectorMarker) @@ -602,32 +606,66 @@ void DelSoftRoot(DObject *obj) size_t DSectorMarker::PropagateMark() { int i; + int marked = 0; + bool moretodo = false; - if (sectors == NULL) + if (sectors != NULL) { - return 0; + for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i) + { + sector_t *sec = §ors[SecNum + i]; + GC::Mark(sec->SoundTarget); + GC::Mark(sec->CeilingSkyBox); + GC::Mark(sec->FloorSkyBox); + GC::Mark(sec->SecActTarget); + GC::Mark(sec->floordata); + GC::Mark(sec->ceilingdata); + GC::Mark(sec->lightingdata); + for(int j=0;j<4;j++) GC::Mark(sec->interpolations[j]); + } + marked += i * sizeof(sector_t); + if (SecNum + i < numsectors) + { + SecNum += i; + moretodo = true; + } } - for (i = 0; i < SECTORSTEPSIZE && SecNum + i < numsectors; ++i) + if (!moretodo && polyobjs != NULL) { - sector_t *sec = §ors[SecNum + i]; - GC::Mark(sec->SoundTarget); - GC::Mark(sec->CeilingSkyBox); - GC::Mark(sec->FloorSkyBox); - GC::Mark(sec->SecActTarget); - GC::Mark(sec->floordata); - GC::Mark(sec->ceilingdata); - GC::Mark(sec->lightingdata); + for (i = 0; i < POLYSTEPSIZE && PolyNum + i < po_NumPolyobjs; ++i) + { + GC::Mark(polyobjs[PolyNum + i].interpolation); + } + marked += i * sizeof(FPolyObj); + if (PolyNum + i < po_NumPolyobjs) + { + PolyNum += i; + moretodo = true; + } + } + if (!moretodo && sides != NULL) + { + for (i = 0; i < SIDEDEFSTEPSIZE && SideNum + i < numsides; ++i) + { + side_t *side = &sides[SideNum + i]; + for(int j=0;j<3;j++) GC::Mark(side->textures[j].interpolation); + } + marked += i * sizeof(side_t); + if (SideNum + i < numsides) + { + SideNum += i; + moretodo = true; + } } // If there are more sectors to mark, put ourself back into the gray // list. - if (SecNum + i < numsectors) + if (moretodo) { - SecNum += i; Black2Gray(); GCNext = GC::Gray; GC::Gray = this; } - return i * sizeof(sector_t); + return marked; } //========================================================================== diff --git a/src/g_level.cpp b/src/g_level.cpp index 5fac9d282..c73f50816 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -75,6 +75,7 @@ #include "sbarinfo.h" #include "r_translate.h" #include "p_lnspec.h" +#include "r_interpolate.h" #include "gi.h" @@ -2740,6 +2741,7 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad) } FBehavior::StaticSerializeModuleStates (arc); + if (arc.IsLoading()) interpolator.ClearInterpolations(); P_SerializeThinkers (arc, hubLoad); P_SerializeWorld (arc); P_SerializePolyobjs (arc); diff --git a/src/r_interpolate.cpp b/src/r_interpolate.cpp index cbe1553e6..27cb1ffe8 100644 --- a/src/r_interpolate.cpp +++ b/src/r_interpolate.cpp @@ -88,6 +88,7 @@ public: DSectorScrollInterpolation() {} DSectorScrollInterpolation(sector_t *sector, bool plane); + void Destroy(); void UpdateInterpolation(); void Restore(); void Interpolate(fixed_t smoothratio); @@ -114,6 +115,7 @@ public: DWallScrollInterpolation() {} DWallScrollInterpolation(side_t *side, int part); + void Destroy(); void UpdateInterpolation(); void Restore(); void Interpolate(fixed_t smoothratio); @@ -137,6 +139,7 @@ public: DPolyobjInterpolation() {} DPolyobjInterpolation(FPolyObj *poly); + void Destroy(); void UpdateInterpolation(); void Restore(); void Interpolate(fixed_t smoothratio); @@ -180,14 +183,6 @@ FInterpolator interpolator; int FInterpolator::CountInterpolations () { - int count = 0; - - DInterpolation *probe = Head; - while (probe != NULL) - { - count++; - probe = probe->Next; - } return count; } @@ -217,6 +212,7 @@ void FInterpolator::AddInterpolation(DInterpolation *interp) if (Head != NULL) Head->Prev = &interp->Next; Head = interp; interp->Prev = &Head; + count++; } //========================================================================== @@ -233,6 +229,7 @@ void FInterpolator::RemoveInterpolation(DInterpolation *interp) if (interp->Next != NULL) interp->Next->Prev = interp->Prev; interp->Next = NULL; interp->Prev = NULL; + count--; } } @@ -403,6 +400,17 @@ DSectorPlaneInterpolation::DSectorPlaneInterpolation(sector_t *_sector, bool _pl void DSectorPlaneInterpolation::Destroy() { + if (ceiling) + { + assert(sector->interpolations[sector_t::CeilingMove] == this); + sector->interpolations[sector_t::CeilingMove] = NULL; + } + else + { + assert(sector->interpolations[sector_t::FloorMove] == this); + sector->interpolations[sector_t::FloorMove] = NULL; + } + for(unsigned i=0; iDelRef(); @@ -552,6 +560,27 @@ DSectorScrollInterpolation::DSectorScrollInterpolation(sector_t *_sector, bool _ // //========================================================================== +void DSectorScrollInterpolation::Destroy() +{ + if (ceiling) + { + assert(sector->interpolations[sector_t::CeilingScroll] == this); + sector->interpolations[sector_t::CeilingScroll] = NULL; + } + else + { + assert(sector->interpolations[sector_t::FloorScroll] == this); + sector->interpolations[sector_t::FloorScroll] = NULL; + } + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + void DSectorScrollInterpolation::UpdateInterpolation() { if (!ceiling) @@ -654,6 +683,19 @@ DWallScrollInterpolation::DWallScrollInterpolation(side_t *_side, int _part) // //========================================================================== +void DWallScrollInterpolation::Destroy() +{ + assert(side->textures[part].interpolation == this); + side->textures[part].interpolation = NULL; + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + void DWallScrollInterpolation::UpdateInterpolation() { oldx = side->GetTextureXOffset(part); @@ -726,6 +768,19 @@ DPolyobjInterpolation::DPolyobjInterpolation(FPolyObj *po) // //========================================================================== +void DPolyobjInterpolation::Destroy() +{ + assert(poly->interpolation == this); + poly->interpolation = NULL; + Super::Destroy(); +} + +//========================================================================== +// +// +// +//========================================================================== + void DPolyobjInterpolation::UpdateInterpolation() { for(int i = 0; i < poly->numvertices; i++) @@ -801,7 +856,6 @@ DInterpolation *side_t::SetInterpolation(int position) if (textures[position].interpolation == NULL) { textures[position].interpolation = new DWallScrollInterpolation(this, position); - textures[position].interpolation->AddRef(); } textures[position].interpolation->AddRef(); GC::WriteBarrier(textures[position].interpolation); diff --git a/src/r_interpolate.h b/src/r_interpolate.h index 63716e367..9334827e8 100644 --- a/src/r_interpolate.h +++ b/src/r_interpolate.h @@ -41,6 +41,7 @@ struct FInterpolator { DInterpolation *Head; bool didInterp; + int count; int CountInterpolations (); @@ -49,6 +50,7 @@ public: { Head = NULL; didInterp = false; + count = 0; } void UpdateInterpolations(); void AddInterpolation(DInterpolation *); diff --git a/src/version.h b/src/version.h index 13661243b..b7b66e183 100644 --- a/src/version.h +++ b/src/version.h @@ -75,7 +75,7 @@ // SAVESIG should match SAVEVER. // MINSAVEVER is the minimum level snapshot version that can be loaded. -#define MINSAVEVER 1027 +#define MINSAVEVER 1028 #if SVN_REVISION_NUMBER < MINSAVEVER // Never write a savegame with a version lower than what we need