From acbe3a191e7228816046948ba36de16d73b55c32 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 11 Dec 2007 03:29:31 +0000 Subject: [PATCH] - Fixed: Redefining a decal did not rebind any old references to the decal, so they would be left pointing at invalid data. SVN r594 (trunk) --- docs/rh-log.txt | 2 ++ src/decallib.cpp | 27 +++++++++++++++++++++++++++ src/decallib.h | 3 +++ src/weightedlist.h | 16 ++++++++++++++++ 4 files changed, 48 insertions(+) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index db1722f732..410185320b 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,6 @@ December 10, 2007 +- Fixed: Redefining a decal did not rebind any old references to the decal, so + they would be left pointing at invalid data. - Fixed some more GCC warnings. - Updated project files for nasm 2.0, which is now named nasm.exe for the Windows version, rather than nasmw.exe. Also fixed the annoying new warnings diff --git a/src/decallib.cpp b/src/decallib.cpp index 25cb29db51..e7163820f3 100644 --- a/src/decallib.cpp +++ b/src/decallib.cpp @@ -66,6 +66,10 @@ class FDecalGroup : public FDecalBase public: FDecalGroup () : Choices (pr_decalchoice) {} const FDecalTemplate *GetDecal () const; + void ReplaceDecalRef (FDecalBase *from, FDecalBase *to) + { + Choices.ReplaceValues(from, to); + } void AddDecal (FDecalBase *decal, WORD weight) { Choices.AddEntry (decal, weight); @@ -301,6 +305,14 @@ const FDecalTemplate *FDecalBase::GetDecal () const return NULL; } +void FDecalTemplate::ReplaceDecalRef(FDecalBase *from, FDecalBase *to) +{ + if (LowerDecal == from) + { + LowerDecal = to; + } +} + FDecalLib::FDecalLib () { Root = NULL; @@ -828,6 +840,17 @@ void FDecalLib::ParseCombiner () } } +void FDecalLib::ReplaceDecalRef (FDecalBase *from, FDecalBase *to, FDecalBase *root) +{ + if (root == NULL) + { + return; + } + ReplaceDecalRef (from, to, root->Left); + ReplaceDecalRef (from, to, root->Right); + root->ReplaceDecalRef (from, to); +} + void FDecalLib::AddDecal (const char *name, BYTE num, const FDecalTemplate &decal) { FDecalTemplate *newDecal = new FDecalTemplate; @@ -873,6 +896,10 @@ void FDecalLib::AddDecal (FDecalBase *decal) } else { // Yes, replace the old one. + // If this decal has been used as the lowerdecal for another decal, + // be sure and update the lowerdecal to use the new decal. + ReplaceDecalRef(node, decal, Root); + decal->Left = node->Left; decal->Right = node->Right; *prev = decal; diff --git a/src/decallib.h b/src/decallib.h index 6793a694f6..e1cc4bf1db 100644 --- a/src/decallib.h +++ b/src/decallib.h @@ -52,6 +52,7 @@ class FDecalBase friend class FDecalLib; public: virtual const FDecalTemplate *GetDecal () const; + virtual void ReplaceDecalRef (FDecalBase *from, FDecalBase *to) = 0; protected: FDecalBase (); @@ -71,6 +72,7 @@ public: void ApplyToDecal (DBaseDecal *actor, side_s *wall) const; const FDecalTemplate *GetDecal () const; + void ReplaceDecalRef (FDecalBase *from, FDecalBase *to); fixed_t ScaleX, ScaleY; DWORD ShadeColor; @@ -104,6 +106,7 @@ private: static void DelTree (FDecalBase *root); static FDecalBase *ScanTreeForNum (const BYTE num, FDecalBase *root); static FDecalBase *ScanTreeForName (const char *name, FDecalBase *root); + static void ReplaceDecalRef (FDecalBase *from, FDecalBase *to, FDecalBase *root); FTranslation *GenerateTranslation (DWORD start, DWORD end); void AddDecal (const char *name, BYTE num, const FDecalTemplate &decal); void AddDecal (FDecalBase *decal); diff --git a/src/weightedlist.h b/src/weightedlist.h index 38e1d2fb6d..0e4294e842 100644 --- a/src/weightedlist.h +++ b/src/weightedlist.h @@ -66,6 +66,7 @@ class TWeightedList void AddEntry (T value, WORD weight); T PickEntry () const; + void ReplaceValues (T oldval, T newval); private: Choice *Choices; @@ -148,3 +149,18 @@ void TWeightedList::RecalcRandomVals () choice->RandomVal = (BYTE)(randVal * 255.0); } } + +// Replace all values that match oldval with newval +template +void TWeightedList::ReplaceValues(T oldval, T newval) +{ + Choice *choice; + + for (choice = Choices; choice != NULL; choice = choice->Next) + { + if (choice->Value == oldval) + { + choice->Value = newval; + } + } +}