mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-02-17 01:31:25 +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; }
|
void SetNull() { texnum = 0; }
|
||||||
bool operator ==(const FTextureID &other) const { return texnum == other.texnum; }
|
bool operator ==(const FTextureID &other) const { return texnum == other.texnum; }
|
||||||
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!
|
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!
|
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 (!isValid()) return *this;
|
||||||
if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1);
|
if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1);
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "animations.h"
|
#include "animations.h"
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -61,14 +62,6 @@ static FRandom pr_animatepictures ("AnimatePics");
|
||||||
|
|
||||||
void FTextureAnimator::DeleteAll()
|
void FTextureAnimator::DeleteAll()
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < mAnimations.Size(); i++)
|
|
||||||
{
|
|
||||||
if (mAnimations[i] != NULL)
|
|
||||||
{
|
|
||||||
M_Free(mAnimations[i]);
|
|
||||||
mAnimations[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mAnimations.Clear();
|
mAnimations.Clear();
|
||||||
|
|
||||||
for (unsigned i = 0; i < mSwitchDefs.Size(); i++)
|
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.
|
// Search for existing duplicate.
|
||||||
for (unsigned int i = 0; i < mAnimations.Size(); ++i)
|
for (unsigned int i = 0; i < mAnimations.Size(); ++i)
|
||||||
{
|
{
|
||||||
if (mAnimations[i]->BasePic == anim->BasePic)
|
if (mAnimations[i].BasePic == anim.BasePic)
|
||||||
{
|
{
|
||||||
// Found one!
|
// Found one!
|
||||||
M_Free (mAnimations[i]);
|
|
||||||
mAnimations[i] = anim;
|
mAnimations[i] = anim;
|
||||||
return anim;
|
return &anim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Didn't find one, so add it at the end.
|
// Didn't find one, so add it at the end.
|
||||||
mAnimations.Push (anim);
|
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)))
|
if (TexMan.AreTexturesCompatible(picnum, picnum + (animcount - 1)))
|
||||||
{
|
{
|
||||||
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
|
FAnimDef anim;
|
||||||
anim->CurFrame = 0;
|
anim.CurFrame = 0;
|
||||||
anim->BasePic = picnum;
|
anim.BasePic = picnum;
|
||||||
anim->NumFrames = animcount;
|
anim.NumFrames = animcount;
|
||||||
anim->AnimType = FAnimDef::ANIM_Forward;
|
anim.AnimType = FAnimDef::ANIM_Forward;
|
||||||
anim->bDiscrete = false;
|
anim.bDiscrete = false;
|
||||||
anim->SwitchTime = 0;
|
anim.SwitchTime = 0;
|
||||||
anim->Frames[0].SpeedMin = speedmin;
|
anim.Frames = (FAnimDef::FAnimFrame*)ImageArena.Alloc(sizeof(FAnimDef::FAnimFrame));
|
||||||
anim->Frames[0].SpeedRange = speedrange;
|
anim.Frames[0].SpeedMin = speedmin;
|
||||||
anim->Frames[0].FramePic = anim->BasePic;
|
anim.Frames[0].SpeedRange = speedrange;
|
||||||
|
anim.Frames[0].FramePic = anim.BasePic;
|
||||||
return AddAnim (anim);
|
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 *FTextureAnimator::AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames)
|
||||||
{
|
{
|
||||||
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef) + (frames.Size()-1) * sizeof(frames[0]));
|
FAnimDef anim;
|
||||||
anim->BasePic = picnum;
|
anim.BasePic = picnum;
|
||||||
anim->NumFrames = frames.Size();
|
anim.NumFrames = frames.Size();
|
||||||
anim->CurFrame = 0;
|
anim.CurFrame = 0;
|
||||||
anim->AnimType = FAnimDef::ANIM_Forward;
|
anim.AnimType = FAnimDef::ANIM_Forward;
|
||||||
anim->bDiscrete = true;
|
anim.bDiscrete = true;
|
||||||
anim->SwitchTime = 0;
|
anim.SwitchTime = 0;
|
||||||
memcpy (&anim->Frames[0], &frames[0], frames.Size() * sizeof(frames[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);
|
return AddAnim (anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -783,7 +777,7 @@ void FTextureAnimator::FixAnimations ()
|
||||||
|
|
||||||
for (i = 0; i < mAnimations.Size(); ++i)
|
for (i = 0; i < mAnimations.Size(); ++i)
|
||||||
{
|
{
|
||||||
FAnimDef *anim = mAnimations[i];
|
const FAnimDef *anim = &mAnimations[i];
|
||||||
if (!anim->bDiscrete)
|
if (!anim->bDiscrete)
|
||||||
{
|
{
|
||||||
bool nodecals;
|
bool nodecals;
|
||||||
|
@ -928,7 +922,7 @@ void FTextureAnimator::UpdateAnimations (uint64_t mstime)
|
||||||
{
|
{
|
||||||
for (unsigned int j = 0; j < mAnimations.Size(); ++j)
|
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
|
// If this is the first time through R_UpdateAnimations, just
|
||||||
// initialize the anim's switch time without actually animating.
|
// initialize the anim's switch time without actually animating.
|
||||||
|
|
|
@ -7,18 +7,20 @@
|
||||||
|
|
||||||
struct FAnimDef
|
struct FAnimDef
|
||||||
{
|
{
|
||||||
|
struct FAnimFrame
|
||||||
|
{
|
||||||
|
uint32_t SpeedMin; // Speeds are in ms, not tics
|
||||||
|
uint32_t SpeedRange;
|
||||||
|
FTextureID FramePic;
|
||||||
|
};
|
||||||
|
|
||||||
FTextureID BasePic;
|
FTextureID BasePic;
|
||||||
uint16_t NumFrames;
|
uint16_t NumFrames;
|
||||||
uint16_t CurFrame;
|
uint16_t CurFrame;
|
||||||
uint8_t AnimType;
|
uint8_t AnimType;
|
||||||
bool bDiscrete; // taken out of AnimType to have better control
|
bool bDiscrete; // taken out of AnimType to have better control
|
||||||
uint64_t SwitchTime; // Time to advance to next frame
|
uint64_t SwitchTime; // Time to advance to next frame
|
||||||
struct FAnimFrame
|
FAnimFrame* Frames;
|
||||||
{
|
|
||||||
uint32_t SpeedMin; // Speeds are in ms, not tics
|
|
||||||
uint32_t SpeedRange;
|
|
||||||
FTextureID FramePic;
|
|
||||||
} Frames[1];
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
ANIM_Forward,
|
ANIM_Forward,
|
||||||
|
@ -59,7 +61,7 @@ struct FDoorAnimation
|
||||||
|
|
||||||
class FTextureAnimator
|
class FTextureAnimator
|
||||||
{
|
{
|
||||||
TArray<FAnimDef*> mAnimations;
|
TArray<FAnimDef> mAnimations;
|
||||||
TArray<FSwitchDef*> mSwitchDefs;
|
TArray<FSwitchDef*> mSwitchDefs;
|
||||||
TArray<FDoorAnimation> mAnimatedDoors;
|
TArray<FDoorAnimation> mAnimatedDoors;
|
||||||
|
|
||||||
|
@ -88,7 +90,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Animation stuff
|
// Animation stuff
|
||||||
FAnimDef* AddAnim(FAnimDef* anim);
|
FAnimDef* AddAnim(FAnimDef& anim);
|
||||||
void DeleteAll();
|
void DeleteAll();
|
||||||
|
|
||||||
FAnimDef* AddSimpleAnim(FTextureID picnum, int animcount, uint32_t speedmin, uint32_t speedrange = 0);
|
FAnimDef* AddSimpleAnim(FTextureID picnum, int animcount, uint32_t speedmin, uint32_t speedrange = 0);
|
||||||
|
@ -98,7 +100,7 @@ public:
|
||||||
FDoorAnimation* FindAnimatedDoor(FTextureID picnum);
|
FDoorAnimation* FindAnimatedDoor(FTextureID picnum);
|
||||||
void UpdateAnimations(uint64_t mstime);
|
void UpdateAnimations(uint64_t mstime);
|
||||||
|
|
||||||
const TArray<FAnimDef*>& GetAnimations() const { return mAnimations; }
|
const TArray<FAnimDef>& GetAnimations() const { return mAnimations; }
|
||||||
|
|
||||||
void Init()
|
void Init()
|
||||||
{
|
{
|
||||||
|
|
|
@ -102,11 +102,11 @@ static void AddToList(uint8_t *hitlist, FTextureID texid, int bitmask)
|
||||||
|
|
||||||
const auto addAnimations = [hitlist, bitmask](const FTextureID texid)
|
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;
|
hitlist[i] |= (uint8_t)bitmask;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue