- 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);
}
// 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
// (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<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;
}
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;

View file

@ -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<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
@ -815,3 +902,4 @@ void FTextureManager::UpdateAnimations (DWORD mstime)
}
}
}

View file

@ -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)
{

View file

@ -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<FAnimDef *> mAnimations;
TArray<FSwitchDef *> mSwitchDefs;
TArray<FDoorAnimation> mAnimatedDoors;
TArray<BYTE *> BuildTileFiles;
};