diff --git a/src/p_doors.cpp b/src/p_doors.cpp index e82adbe4c..7f385242d 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -496,51 +496,12 @@ void P_SpawnDoorRaiseIn5Mins (sector_t *sec) new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0); } -// Strife's animated doors. Based on Doom's unused sliding doors, but significantly improved. - -class DeletingDoorArray : public TArray -{ -public: - ~DeletingDoorArray() - { - for(unsigned i=0;iTextureFrames != NULL) - { - delete [] ani->TextureFrames; - ani->TextureFrames = NULL; - } - } - } -}; - -DeletingDoorArray DoorAnimations; - // EV_SlidingDoor : slide a door horizontally // (animate midtexture, then set noblocking line) // -// -// Return index into "DoorAnimations" array for which door type to use -// -static int P_FindSlidingDoorType (FTextureID picnum) -{ - unsigned int i; - - for (i = 0; i < DoorAnimations.Size(); ++i) - { - if (picnum == DoorAnimations[i].BaseTexture) - return i; - } - - return -1; -} - bool DAnimatedDoor::StartClosing () { - FDoorAnimation &ani = DoorAnimations[m_WhichDoorIndex]; - // CAN DOOR CLOSE? if (m_Sector->touching_thinglist != NULL) { @@ -557,9 +518,9 @@ bool DAnimatedDoor::StartClosing () m_Line1->flags |= ML_BLOCKING; m_Line2->flags |= ML_BLOCKING; - if (ani.CloseSound != NAME_None) + if (m_DoorAnim->CloseSound != NAME_None) { - SN_StartSequence (m_Sector, CHAN_CEILING, ani.CloseSound, 1); + SN_StartSequence (m_Sector, CHAN_CEILING, m_DoorAnim->CloseSound, 1); } m_Status = Closing; @@ -569,7 +530,12 @@ bool DAnimatedDoor::StartClosing () void DAnimatedDoor::Tick () { - FDoorAnimation &ani = DoorAnimations[m_WhichDoorIndex]; + if (m_DoorAnim == NULL) + { + // can only happen when a bad savegame is loaded. + Destroy(); + return; + } switch (m_Status) { @@ -581,7 +547,7 @@ void DAnimatedDoor::Tick () case Opening: if (!m_Timer--) { - if (++m_Frame >= ani.NumTextureFrames) + if (++m_Frame >= m_DoorAnim->NumTextureFrames) { // IF DOOR IS DONE OPENING... m_Line1->flags &= ~ML_BLOCKING; @@ -602,10 +568,10 @@ void DAnimatedDoor::Tick () // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... m_Timer = m_Speed; - m_Line1->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line1->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + m_Line1->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); } } break; @@ -648,10 +614,10 @@ void DAnimatedDoor::Tick () // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... m_Timer = m_Speed; - m_Line1->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line1->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); - m_Line2->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); + m_Line1->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); + m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]); } } break; @@ -673,7 +639,12 @@ void DAnimatedDoor::Serialize (FArchive &arc) { Super::Serialize (arc); - FTextureID basetex = DoorAnimations[m_WhichDoorIndex].BaseTexture; + FTextureID basetex; + + if (arc.IsStoring()) + { + basetex = m_DoorAnim->BaseTexture; + } arc << m_Line1 << m_Line2 << m_Frame @@ -694,15 +665,11 @@ void DAnimatedDoor::Serialize (FArchive &arc) if (arc.IsLoading()) { - m_WhichDoorIndex = P_FindSlidingDoorType (basetex); - if (m_WhichDoorIndex == -1) - { // Oh no! The door animation doesn't exist anymore! - m_WhichDoorIndex = 0; - } + m_DoorAnim = TexMan.FindAnimatedDoor (basetex); } } -DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) +DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim) : DMovingCeiling (sec) { fixed_t topdist; @@ -711,13 +678,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) // The DMovingCeiling constructor automatically sets up an interpolation for us. // Stop it, since the ceiling is moving instantly here. StopInterpolation(); - m_WhichDoorIndex = P_FindSlidingDoorType (line->sidedef[0]->GetTexture(side_t::top)); - if (m_WhichDoorIndex < 0) - { - Printf ("EV_SlidingDoor: Textures are not defined for sliding door!"); - m_Status = Dead; - return; - } + m_DoorAnim = anim; m_Line1 = line; m_Line2 = line; @@ -756,9 +717,9 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay) m_Line2->flags |= ML_BLOCKING; m_BotDist = m_Sector->ceilingplane.d; MoveCeiling (2048*FRACUNIT, topdist, 1); - if (DoorAnimations[m_WhichDoorIndex].OpenSound != NAME_None) + if (m_DoorAnim->OpenSound != NAME_None) { - SN_StartSequence (m_Sector, CHAN_INTERIOR, DoorAnimations[m_WhichDoorIndex].OpenSound, 1); + SN_StartSequence (m_Sector, CHAN_INTERIOR, m_DoorAnim->OpenSound, 1); } } @@ -798,9 +759,10 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) } return false; } - if (P_FindSlidingDoorType (line->sidedef[0]->GetTexture(side_t::top)) >= 0) + FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top)); + if (anim != NULL) { - new DAnimatedDoor (sec, line, speed, delay); + new DAnimatedDoor (sec, line, speed, delay, anim); return true; } return false; @@ -821,10 +783,11 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) { continue; } - if (P_FindSlidingDoorType (line->sidedef[0]->GetTexture(side_t::top)) >= 0) + FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top)); + if (anim != NULL) { rtn = true; - new DAnimatedDoor (sec, line, speed, delay); + new DAnimatedDoor (sec, line, speed, delay, anim); break; } } @@ -832,62 +795,3 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay) return rtn; } -void P_ParseAnimatedDoor(FScanner &sc) -{ - const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny; - FDoorAnimation anim; - TArray frames; - bool error = false; - FTextureID v; - - sc.MustGetString(); - anim.BaseTexture = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); - - if (!anim.BaseTexture.Exists()) - { - error = true; - } - - while (sc.GetString ()) - { - if (sc.Compare ("opensound")) - { - sc.MustGetString (); - anim.OpenSound = sc.String; - } - else if (sc.Compare ("closesound")) - { - sc.MustGetString (); - anim.CloseSound = sc.String; - } - else if (sc.Compare ("pic")) - { - sc.MustGetString (); - if (IsNum (sc.String)) - { - v = anim.BaseTexture + (atoi(sc.String) - 1); - } - else - { - v = TexMan.CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); - if (!v.Exists() && anim.BaseTexture.Exists() && !error) - { - sc.ScriptError ("Unknown texture %s", sc.String); - } - frames.Push (v); - } - } - else - { - sc.UnGet (); - break; - } - } - if (!error) - { - anim.TextureFrames = new FTextureID[frames.Size()]; - memcpy (anim.TextureFrames, &frames[0], sizeof(FTextureID) * frames.Size()); - anim.NumTextureFrames = frames.Size(); - DoorAnimations.Push (anim); - } -} diff --git a/src/p_spec.h b/src/p_spec.h index 916dd690c..21427626e 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -595,23 +595,12 @@ inline FArchive &operator<< (FArchive &arc, DDoor::EVlDoor &type) return arc; } -struct FDoorAnimation -{ - FTextureID BaseTexture; - FTextureID *TextureFrames; - int NumTextureFrames; - FName OpenSound; - FName CloseSound; -}; - -void P_ParseAnimatedDoor (FScanner &sc); - class DAnimatedDoor : public DMovingCeiling { DECLARE_CLASS (DAnimatedDoor, DMovingCeiling) public: DAnimatedDoor (sector_t *sector); - DAnimatedDoor (sector_t *sector, line_t *line, int speed, int delay); + DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, FDoorAnimation *anim); void Serialize (FArchive &arc); void Tick (); @@ -620,7 +609,7 @@ public: protected: line_t *m_Line1, *m_Line2; int m_Frame; - int m_WhichDoorIndex; + FDoorAnimation *m_DoorAnim; int m_Timer; fixed_t m_BotDist; int m_Status; diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 7497fe4e4..3a75334ae 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -282,7 +282,7 @@ void FTextureManager::InitAnimDefs () } else if (sc.Compare ("animatedDoor")) { - P_ParseAnimatedDoor (sc); + ParseAnimatedDoor (sc); } else if (sc.Compare("skyoffset")) { @@ -699,6 +699,93 @@ void FTextureManager::FixAnimations () } } +//========================================================================== +// +// ParseAnimatedDoor +// +// Parses an animated door definition +// +//========================================================================== + +void FTextureManager::ParseAnimatedDoor(FScanner &sc) +{ + const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; + FDoorAnimation anim; + TArray frames; + bool error = false; + FTextureID v; + + sc.MustGetString(); + anim.BaseTexture = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); + + if (!anim.BaseTexture.Exists()) + { + error = true; + } + + while (sc.GetString ()) + { + if (sc.Compare ("opensound")) + { + sc.MustGetString (); + anim.OpenSound = sc.String; + } + else if (sc.Compare ("closesound")) + { + sc.MustGetString (); + anim.CloseSound = sc.String; + } + else if (sc.Compare ("pic")) + { + sc.MustGetString (); + if (IsNum (sc.String)) + { + v = anim.BaseTexture + (atoi(sc.String) - 1); + } + else + { + v = CheckForTexture (sc.String, FTexture::TEX_Wall, texflags); + if (!v.Exists() && anim.BaseTexture.Exists() && !error) + { + sc.ScriptError ("Unknown texture %s", sc.String); + } + frames.Push (v); + } + } + else + { + sc.UnGet (); + break; + } + } + if (!error) + { + anim.TextureFrames = new FTextureID[frames.Size()]; + memcpy (anim.TextureFrames, &frames[0], sizeof(FTextureID) * frames.Size()); + anim.NumTextureFrames = frames.Size(); + mAnimatedDoors.Push (anim); + } +} + +//========================================================================== +// +// Return index into "DoorAnimations" array for which door type to use +// +//========================================================================== + +FDoorAnimation *FTextureManager::FindAnimatedDoor (FTextureID picnum) +{ + unsigned int i; + + for (i = 0; i < mAnimatedDoors.Size(); ++i) + { + if (picnum == mAnimatedDoors[i].BaseTexture) + return &mAnimatedDoors[i]; + } + + return NULL; +} + //========================================================================== // // FAnimDef :: SetSwitchTime @@ -815,3 +902,4 @@ void FTextureManager::UpdateAnimations (DWORD mstime) } } } + diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 6021676ff..fc49d07d8 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -114,6 +114,15 @@ void FTextureManager::DeleteAll() } mSwitchDefs.Clear(); + for (unsigned i = 0; i < mAnimatedDoors.Size(); i++) + { + if (mAnimatedDoors[i].TextureFrames != NULL) + { + delete mAnimatedDoors[i].TextureFrames; + mAnimatedDoors[i].TextureFrames = NULL; + } + } + mAnimatedDoors.Clear(); for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i) { diff --git a/src/textures/textures.h b/src/textures/textures.h index 8da1a8f96..21a57d226 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -96,6 +96,16 @@ struct FSwitchDef } u[1]; }; +struct FDoorAnimation +{ + FTextureID BaseTexture; + FTextureID *TextureFrames; + int NumTextureFrames; + FName OpenSound; + FName CloseSound; +}; + + // Patches. // A patch holds one or more columns. @@ -393,6 +403,7 @@ public: if (index < mSwitchDefs.Size()) return mSwitchDefs[index]; else return NULL; } + FDoorAnimation *FindAnimatedDoor (FTextureID picnum); private: @@ -422,6 +433,7 @@ private: void ParseTime (FScanner &sc, DWORD &min, DWORD &max); FTexture *Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; } void SetTranslation (FTextureID fromtexnum, FTextureID totexnum); + void ParseAnimatedDoor(FScanner &sc); // Switches @@ -444,6 +456,7 @@ private: TArray mAnimations; TArray mSwitchDefs; + TArray mAnimatedDoors; TArray BuildTileFiles; };