- moved animated door definitions into texture manager and split all associated code off p_doors.cpp

SVN r3029 (trunk)
This commit is contained in:
Christoph Oelckers 2010-12-12 08:30:12 +00:00
parent d851040ad6
commit e257c4cb64
5 changed files with 147 additions and 144 deletions

View file

@ -496,51 +496,12 @@ void P_SpawnDoorRaiseIn5Mins (sector_t *sec)
new DDoor (sec, DDoor::doorRaiseIn5Mins, 2*FRACUNIT, TICRATE*30/7, 0); 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<FDoorAnimation>
{
public:
~DeletingDoorArray()
{
for(unsigned i=0;i<Size();i++)
{
FDoorAnimation *ani = &((*this)[i]);
if (ani->TextureFrames != NULL)
{
delete [] ani->TextureFrames;
ani->TextureFrames = NULL;
}
}
}
};
DeletingDoorArray DoorAnimations;
// EV_SlidingDoor : slide a door horizontally // EV_SlidingDoor : slide a door horizontally
// (animate midtexture, then set noblocking line) // (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 () bool DAnimatedDoor::StartClosing ()
{ {
FDoorAnimation &ani = DoorAnimations[m_WhichDoorIndex];
// CAN DOOR CLOSE? // CAN DOOR CLOSE?
if (m_Sector->touching_thinglist != NULL) if (m_Sector->touching_thinglist != NULL)
{ {
@ -557,9 +518,9 @@ bool DAnimatedDoor::StartClosing ()
m_Line1->flags |= ML_BLOCKING; m_Line1->flags |= ML_BLOCKING;
m_Line2->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; m_Status = Closing;
@ -569,7 +530,12 @@ bool DAnimatedDoor::StartClosing ()
void DAnimatedDoor::Tick () 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) switch (m_Status)
{ {
@ -581,7 +547,7 @@ void DAnimatedDoor::Tick ()
case Opening: case Opening:
if (!m_Timer--) if (!m_Timer--)
{ {
if (++m_Frame >= ani.NumTextureFrames) if (++m_Frame >= m_DoorAnim->NumTextureFrames)
{ {
// IF DOOR IS DONE OPENING... // IF DOOR IS DONE OPENING...
m_Line1->flags &= ~ML_BLOCKING; m_Line1->flags &= ~ML_BLOCKING;
@ -602,10 +568,10 @@ void DAnimatedDoor::Tick ()
// IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
m_Timer = m_Speed; m_Timer = m_Speed;
m_Line1->sidedef[0]->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, ani.TextureFrames[m_Frame]); m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
m_Line2->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
m_Line2->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
} }
} }
break; break;
@ -648,10 +614,10 @@ void DAnimatedDoor::Tick ()
// IF DOOR NEEDS TO ANIMATE TO NEXT FRAME... // IF DOOR NEEDS TO ANIMATE TO NEXT FRAME...
m_Timer = m_Speed; m_Timer = m_Speed;
m_Line1->sidedef[0]->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, ani.TextureFrames[m_Frame]); m_Line1->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
m_Line2->sidedef[0]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); m_Line2->sidedef[0]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
m_Line2->sidedef[1]->SetTexture(side_t::mid, ani.TextureFrames[m_Frame]); m_Line2->sidedef[1]->SetTexture(side_t::mid, m_DoorAnim->TextureFrames[m_Frame]);
} }
} }
break; break;
@ -673,7 +639,12 @@ void DAnimatedDoor::Serialize (FArchive &arc)
{ {
Super::Serialize (arc); Super::Serialize (arc);
FTextureID basetex = DoorAnimations[m_WhichDoorIndex].BaseTexture; FTextureID basetex;
if (arc.IsStoring())
{
basetex = m_DoorAnim->BaseTexture;
}
arc << m_Line1 << m_Line2 arc << m_Line1 << m_Line2
<< m_Frame << m_Frame
@ -694,15 +665,11 @@ void DAnimatedDoor::Serialize (FArchive &arc)
if (arc.IsLoading()) if (arc.IsLoading())
{ {
m_WhichDoorIndex = P_FindSlidingDoorType (basetex); m_DoorAnim = TexMan.FindAnimatedDoor (basetex);
if (m_WhichDoorIndex == -1)
{ // Oh no! The door animation doesn't exist anymore!
m_WhichDoorIndex = 0;
}
} }
} }
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) : DMovingCeiling (sec)
{ {
fixed_t topdist; 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. // The DMovingCeiling constructor automatically sets up an interpolation for us.
// Stop it, since the ceiling is moving instantly here. // Stop it, since the ceiling is moving instantly here.
StopInterpolation(); StopInterpolation();
m_WhichDoorIndex = P_FindSlidingDoorType (line->sidedef[0]->GetTexture(side_t::top)); m_DoorAnim = anim;
if (m_WhichDoorIndex < 0)
{
Printf ("EV_SlidingDoor: Textures are not defined for sliding door!");
m_Status = Dead;
return;
}
m_Line1 = line; m_Line1 = line;
m_Line2 = 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_Line2->flags |= ML_BLOCKING;
m_BotDist = m_Sector->ceilingplane.d; m_BotDist = m_Sector->ceilingplane.d;
MoveCeiling (2048*FRACUNIT, topdist, 1); 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; 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 true;
} }
return false; return false;
@ -821,10 +783,11 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay)
{ {
continue; 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; rtn = true;
new DAnimatedDoor (sec, line, speed, delay); new DAnimatedDoor (sec, line, speed, delay, anim);
break; break;
} }
} }
@ -832,62 +795,3 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay)
return rtn; return rtn;
} }
void P_ParseAnimatedDoor(FScanner &sc)
{
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
FDoorAnimation anim;
TArray<FTextureID> 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);
}
}

View file

@ -595,23 +595,12 @@ inline FArchive &operator<< (FArchive &arc, DDoor::EVlDoor &type)
return arc; return arc;
} }
struct FDoorAnimation
{
FTextureID BaseTexture;
FTextureID *TextureFrames;
int NumTextureFrames;
FName OpenSound;
FName CloseSound;
};
void P_ParseAnimatedDoor (FScanner &sc);
class DAnimatedDoor : public DMovingCeiling class DAnimatedDoor : public DMovingCeiling
{ {
DECLARE_CLASS (DAnimatedDoor, DMovingCeiling) DECLARE_CLASS (DAnimatedDoor, DMovingCeiling)
public: public:
DAnimatedDoor (sector_t *sector); 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 Serialize (FArchive &arc);
void Tick (); void Tick ();
@ -620,7 +609,7 @@ public:
protected: protected:
line_t *m_Line1, *m_Line2; line_t *m_Line1, *m_Line2;
int m_Frame; int m_Frame;
int m_WhichDoorIndex; FDoorAnimation *m_DoorAnim;
int m_Timer; int m_Timer;
fixed_t m_BotDist; fixed_t m_BotDist;
int m_Status; int m_Status;

View file

@ -282,7 +282,7 @@ void FTextureManager::InitAnimDefs ()
} }
else if (sc.Compare ("animatedDoor")) else if (sc.Compare ("animatedDoor"))
{ {
P_ParseAnimatedDoor (sc); ParseAnimatedDoor (sc);
} }
else if (sc.Compare("skyoffset")) 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<FTextureID> 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 // FAnimDef :: SetSwitchTime
@ -815,3 +902,4 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
} }
} }
} }

View file

@ -114,6 +114,15 @@ void FTextureManager::DeleteAll()
} }
mSwitchDefs.Clear(); 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) for (unsigned int i = 0; i < BuildTileFiles.Size(); ++i)
{ {

View file

@ -96,6 +96,16 @@ struct FSwitchDef
} u[1]; } u[1];
}; };
struct FDoorAnimation
{
FTextureID BaseTexture;
FTextureID *TextureFrames;
int NumTextureFrames;
FName OpenSound;
FName CloseSound;
};
// Patches. // Patches.
// A patch holds one or more columns. // A patch holds one or more columns.
@ -393,6 +403,7 @@ public:
if (index < mSwitchDefs.Size()) return mSwitchDefs[index]; if (index < mSwitchDefs.Size()) return mSwitchDefs[index];
else return NULL; else return NULL;
} }
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
private: private:
@ -422,6 +433,7 @@ private:
void ParseTime (FScanner &sc, DWORD &min, DWORD &max); void ParseTime (FScanner &sc, DWORD &min, DWORD &max);
FTexture *Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; } FTexture *Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; }
void SetTranslation (FTextureID fromtexnum, FTextureID totexnum); void SetTranslation (FTextureID fromtexnum, FTextureID totexnum);
void ParseAnimatedDoor(FScanner &sc);
// Switches // Switches
@ -444,6 +456,7 @@ private:
TArray<FAnimDef *> mAnimations; TArray<FAnimDef *> mAnimations;
TArray<FSwitchDef *> mSwitchDefs; TArray<FSwitchDef *> mSwitchDefs;
TArray<FDoorAnimation> mAnimatedDoors;
TArray<BYTE *> BuildTileFiles; TArray<BYTE *> BuildTileFiles;
}; };