mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- optimized storage for animation definitions.
Instead of allocating everything on the heap as single blocks, use a value TArray and allocate the frame arrays from the texture manager's memory arena, since lifetime of the data is identical. Most importantly this avoids using a variable size array at the end of the struct.
This commit is contained in:
parent
89f5428a9a
commit
6d635ce715
5 changed files with 44 additions and 48 deletions
|
@ -35,7 +35,7 @@ public:
|
|||
void SetNull() { texnum = 0; }
|
||||
bool operator ==(const FTextureID &other) const { return texnum == other.texnum; }
|
||||
bool operator !=(const FTextureID &other) const { return texnum != other.texnum; }
|
||||
FTextureID operator +(int offset) throw();
|
||||
FTextureID operator +(int offset) const noexcept(true);
|
||||
int GetIndex() const { return texnum; } // Use this only if you absolutely need the index!
|
||||
void SetIndex(int index) { texnum = index; } // Use this only if you absolutely need the index!
|
||||
|
||||
|
|
|
@ -1615,7 +1615,7 @@ void FTextureManager::AddAlias(const char* name, FGameTexture* tex)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FTextureID FTextureID::operator +(int offset) throw()
|
||||
FTextureID FTextureID::operator +(int offset) const noexcept(true)
|
||||
{
|
||||
if (!isValid()) return *this;
|
||||
if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1);
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "serializer.h"
|
||||
#include "animations.h"
|
||||
#include "texturemanager.h"
|
||||
#include "image.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -61,14 +62,6 @@ static FRandom pr_animatepictures ("AnimatePics");
|
|||
|
||||
void FTextureAnimator::DeleteAll()
|
||||
{
|
||||
for (unsigned i = 0; i < mAnimations.Size(); i++)
|
||||
{
|
||||
if (mAnimations[i] != NULL)
|
||||
{
|
||||
M_Free(mAnimations[i]);
|
||||
mAnimations[i] = NULL;
|
||||
}
|
||||
}
|
||||
mAnimations.Clear();
|
||||
|
||||
for (unsigned i = 0; i < mSwitchDefs.Size(); i++)
|
||||
|
@ -101,22 +94,21 @@ void FTextureAnimator::DeleteAll()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FAnimDef *FTextureAnimator::AddAnim (FAnimDef *anim)
|
||||
FAnimDef *FTextureAnimator::AddAnim (FAnimDef& anim)
|
||||
{
|
||||
// Search for existing duplicate.
|
||||
for (unsigned int i = 0; i < mAnimations.Size(); ++i)
|
||||
{
|
||||
if (mAnimations[i]->BasePic == anim->BasePic)
|
||||
if (mAnimations[i].BasePic == anim.BasePic)
|
||||
{
|
||||
// Found one!
|
||||
M_Free (mAnimations[i]);
|
||||
mAnimations[i] = anim;
|
||||
return anim;
|
||||
return &anim;
|
||||
}
|
||||
}
|
||||
// Didn't find one, so add it at the end.
|
||||
mAnimations.Push (anim);
|
||||
return anim;
|
||||
return &anim;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -132,19 +124,20 @@ FAnimDef *FTextureAnimator::AddSimpleAnim (FTextureID picnum, int animcount, uin
|
|||
{
|
||||
if (TexMan.AreTexturesCompatible(picnum, picnum + (animcount - 1)))
|
||||
{
|
||||
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
|
||||
anim->CurFrame = 0;
|
||||
anim->BasePic = picnum;
|
||||
anim->NumFrames = animcount;
|
||||
anim->AnimType = FAnimDef::ANIM_Forward;
|
||||
anim->bDiscrete = false;
|
||||
anim->SwitchTime = 0;
|
||||
anim->Frames[0].SpeedMin = speedmin;
|
||||
anim->Frames[0].SpeedRange = speedrange;
|
||||
anim->Frames[0].FramePic = anim->BasePic;
|
||||
FAnimDef anim;
|
||||
anim.CurFrame = 0;
|
||||
anim.BasePic = picnum;
|
||||
anim.NumFrames = animcount;
|
||||
anim.AnimType = FAnimDef::ANIM_Forward;
|
||||
anim.bDiscrete = false;
|
||||
anim.SwitchTime = 0;
|
||||
anim.Frames = (FAnimDef::FAnimFrame*)ImageArena.Alloc(sizeof(FAnimDef::FAnimFrame));
|
||||
anim.Frames[0].SpeedMin = speedmin;
|
||||
anim.Frames[0].SpeedRange = speedrange;
|
||||
anim.Frames[0].FramePic = anim.BasePic;
|
||||
return AddAnim (anim);
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -157,14 +150,15 @@ FAnimDef *FTextureAnimator::AddSimpleAnim (FTextureID picnum, int animcount, uin
|
|||
|
||||
FAnimDef *FTextureAnimator::AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames)
|
||||
{
|
||||
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0]));
|
||||
anim->BasePic = picnum;
|
||||
anim->NumFrames = frames.Size();
|
||||
anim->CurFrame = 0;
|
||||
anim->AnimType = FAnimDef::ANIM_Forward;
|
||||
anim->bDiscrete = true;
|
||||
anim->SwitchTime = 0;
|
||||
memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[0]));
|
||||
FAnimDef anim;
|
||||
anim.BasePic = picnum;
|
||||
anim.NumFrames = frames.Size();
|
||||
anim.CurFrame = 0;
|
||||
anim.AnimType = FAnimDef::ANIM_Forward;
|
||||
anim.bDiscrete = true;
|
||||
anim.SwitchTime = 0;
|
||||
anim.Frames = (FAnimDef::FAnimFrame*)ImageArena.Alloc(frames.Size() * sizeof(frames[0]));
|
||||
memcpy (&anim.Frames[0], &frames[0], frames.Size() * sizeof(frames[0]));
|
||||
return AddAnim (anim);
|
||||
}
|
||||
|
||||
|
@ -783,7 +777,7 @@ void FTextureAnimator::FixAnimations ()
|
|||
|
||||
for (i = 0; i < mAnimations.Size(); ++i)
|
||||
{
|
||||
FAnimDef *anim = mAnimations[i];
|
||||
const FAnimDef *anim = &mAnimations[i];
|
||||
if (!anim->bDiscrete)
|
||||
{
|
||||
bool nodecals;
|
||||
|
@ -928,7 +922,7 @@ void FTextureAnimator::UpdateAnimations (uint64_t mstime)
|
|||
{
|
||||
for (unsigned int j = 0; j < mAnimations.Size(); ++j)
|
||||
{
|
||||
FAnimDef *anim = mAnimations[j];
|
||||
FAnimDef *anim = &mAnimations[j];
|
||||
|
||||
// If this is the first time through R_UpdateAnimations, just
|
||||
// initialize the anim's switch time without actually animating.
|
||||
|
|
|
@ -7,18 +7,20 @@
|
|||
|
||||
struct FAnimDef
|
||||
{
|
||||
struct FAnimFrame
|
||||
{
|
||||
uint32_t SpeedMin; // Speeds are in ms, not tics
|
||||
uint32_t SpeedRange;
|
||||
FTextureID FramePic;
|
||||
};
|
||||
|
||||
FTextureID BasePic;
|
||||
uint16_t NumFrames;
|
||||
uint16_t CurFrame;
|
||||
uint8_t AnimType;
|
||||
bool bDiscrete; // taken out of AnimType to have better control
|
||||
uint64_t SwitchTime; // Time to advance to next frame
|
||||
struct FAnimFrame
|
||||
{
|
||||
uint32_t SpeedMin; // Speeds are in ms, not tics
|
||||
uint32_t SpeedRange;
|
||||
FTextureID FramePic;
|
||||
} Frames[1];
|
||||
FAnimFrame* Frames;
|
||||
enum
|
||||
{
|
||||
ANIM_Forward,
|
||||
|
@ -59,7 +61,7 @@ struct FDoorAnimation
|
|||
|
||||
class FTextureAnimator
|
||||
{
|
||||
TArray<FAnimDef*> mAnimations;
|
||||
TArray<FAnimDef> mAnimations;
|
||||
TArray<FSwitchDef*> mSwitchDefs;
|
||||
TArray<FDoorAnimation> mAnimatedDoors;
|
||||
|
||||
|
@ -88,7 +90,7 @@ public:
|
|||
}
|
||||
|
||||
// Animation stuff
|
||||
FAnimDef* AddAnim(FAnimDef* anim);
|
||||
FAnimDef* AddAnim(FAnimDef& anim);
|
||||
void DeleteAll();
|
||||
|
||||
FAnimDef* AddSimpleAnim(FTextureID picnum, int animcount, uint32_t speedmin, uint32_t speedrange = 0);
|
||||
|
@ -98,7 +100,7 @@ public:
|
|||
FDoorAnimation* FindAnimatedDoor(FTextureID picnum);
|
||||
void UpdateAnimations(uint64_t mstime);
|
||||
|
||||
const TArray<FAnimDef*>& GetAnimations() const { return mAnimations; }
|
||||
const TArray<FAnimDef>& GetAnimations() const { return mAnimations; }
|
||||
|
||||
void Init()
|
||||
{
|
||||
|
|
|
@ -102,11 +102,11 @@ static void AddToList(uint8_t *hitlist, FTextureID texid, int bitmask)
|
|||
|
||||
const auto addAnimations = [hitlist, bitmask](const FTextureID texid)
|
||||
{
|
||||
for (auto anim : TexAnim.GetAnimations())
|
||||
for (auto& anim : TexAnim.GetAnimations())
|
||||
{
|
||||
if (texid == anim->BasePic || (!anim->bDiscrete && anim->BasePic < texid && texid < anim->BasePic + anim->NumFrames))
|
||||
if (texid == anim.BasePic || (!anim.bDiscrete && anim.BasePic < texid && texid < anim.BasePic + anim.NumFrames))
|
||||
{
|
||||
for (int i = anim->BasePic.GetIndex(); i < anim->BasePic.GetIndex() + anim->NumFrames; i++)
|
||||
for (int i = anim.BasePic.GetIndex(); i < anim.BasePic.GetIndex() + anim.NumFrames; i++)
|
||||
{
|
||||
hitlist[i] |= (uint8_t)bitmask;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue