- split animation management out of the texture manager into a separate class.

This commit is contained in:
Christoph Oelckers 2020-04-11 18:54:54 +02:00
parent 7d192decc7
commit be24023722
14 changed files with 394 additions and 345 deletions

View file

@ -107,6 +107,7 @@
#include "c_buttons.h"
#include "d_buttons.h"
#include "i_interface.h"
#include "animations.h"
EXTERN_CVAR(Bool, hud_althud)
EXTERN_CVAR(Int, vr_mode)
@ -900,7 +901,7 @@ void D_Display ()
}
screen->FrameTime = I_msTimeFS();
TexMan.UpdateAnimations(screen->FrameTime);
TexAnim.UpdateAnimations(screen->FrameTime);
R_UpdateSky(screen->FrameTime);
screen->BeginFrame();
screen->ClearClipRect();
@ -2945,6 +2946,7 @@ static int D_DoomMain_Internal (void)
if (!batchrun) Printf ("Texman.Init: Init texture manager.\n");
TexMan.Init();
TexAnim.Init();
C_InitConback();
StartScreen->Progress();
@ -3273,6 +3275,7 @@ void D_Cleanup()
DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods
DeinitMenus();
LightDefaults.DeleteAndClear(); // this can leak heap memory if it isn't cleared.
TexAnim.DeleteAll();
// delete DoomStartupInfo data
DoomStartupInfo.Name = "";

View file

@ -38,63 +38,7 @@ typedef TMap<int, PClassActor *> FClassMap;
// Bounding box coordinate storage.
#include "palentry.h"
enum class ETextureType : uint8_t
{
Any,
Wall,
Flat,
Sprite,
WallPatch,
Build, // no longer used but needs to remain for ZScript
SkinSprite,
Decal,
MiscPatch,
FontChar,
Override, // For patches between TX_START/TX_END
Autopage, // Automap background - used to enable the use of FAutomapTexture
SkinGraphic,
Null,
FirstDefined,
SWCanvas,
};
class FTextureID
{
friend class FTextureManager;
friend void R_InitSpriteDefs();
public:
FTextureID() = default;
bool isNull() const { return texnum == 0; }
bool isValid() const { return texnum > 0; }
bool Exists() const { return texnum >= 0; }
void SetInvalid() { texnum = -1; }
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();
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!
// The switch list needs these to sort the switches by texture index
int operator -(FTextureID other) const { return texnum - other.texnum; }
bool operator < (FTextureID other) const { return texnum < other.texnum; }
bool operator > (FTextureID other) const { return texnum > other.texnum; }
protected:
FTextureID(int num) { texnum = num; }
private:
int texnum;
};
// This is for the script interface which needs to do casts from int to texture.
class FSetTextureID : public FTextureID
{
public:
FSetTextureID(int v) : FTextureID(v) {}
};
#include "textureid.h"
enum class ELightMode : int8_t
{

View file

@ -40,6 +40,7 @@
#include "cmdlib.h"
#include "sc_man.h"
#include "gi.h"
#include "animations.h"
static int SortSwitchDefs (const void *a, const void *b)
@ -57,9 +58,9 @@ static int SortSwitchDefs (const void *a, const void *b)
//
//==========================================================================
void FTextureManager::InitSwitchList ()
void FTextureAnimator::InitSwitchList ()
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
int lump = fileSystem.CheckNumForName ("SWITCHES");
if (lump != -1)
@ -78,13 +79,13 @@ void FTextureManager::InitSwitchList ()
continue;
}
// [RH] Skip this switch if its textures can't be found.
if (CheckForTexture (list_p /* .name1 */, ETextureType::Wall, texflags).Exists() &&
CheckForTexture (list_p + 9 /* .name2 */, ETextureType::Wall, texflags).Exists())
if (TexMan.CheckForTexture (list_p /* .name1 */, ETextureType::Wall, texflags).Exists() &&
TexMan.CheckForTexture (list_p + 9 /* .name2 */, ETextureType::Wall, texflags).Exists())
{
def1 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def1->PreTexture = def2->frames[0].Texture = CheckForTexture (list_p /* .name1 */, ETextureType::Wall, texflags);
def2->PreTexture = def1->frames[0].Texture = CheckForTexture (list_p + 9, ETextureType::Wall, texflags);
def1->PreTexture = def2->frames[0].Texture = TexMan.CheckForTexture (list_p /* .name1 */, ETextureType::Wall, texflags);
def2->PreTexture = def1->frames[0].Texture = TexMan.CheckForTexture (list_p + 9, ETextureType::Wall, texflags);
def1->Sound = def2->Sound = 0;
def1->NumFrames = def2->NumFrames = 1;
def1->frames[0].TimeMin = def2->frames[0].TimeMin = 0;
@ -104,16 +105,16 @@ void FTextureManager::InitSwitchList ()
//
//==========================================================================
void FTextureManager::ProcessSwitchDef (FScanner &sc)
void FTextureAnimator::ProcessSwitchDef (FScanner &sc)
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
FString picname;
FSwitchDef *def1, *def2;
FTextureID picnum;
int gametype;
bool quest = false;
def1 = def2 = NULL;
def1 = def2 = nullptr;
sc.MustGetString ();
if (sc.Compare ("doom"))
{
@ -145,7 +146,7 @@ void FTextureManager::ProcessSwitchDef (FScanner &sc)
}
sc.MustGetString ();
picnum = CheckForTexture (sc.String, ETextureType::Wall, texflags);
picnum = TexMan.CheckForTexture (sc.String, ETextureType::Wall, texflags);
picname = sc.String;
while (sc.GetString ())
{
@ -155,7 +156,7 @@ void FTextureManager::ProcessSwitchDef (FScanner &sc)
}
else if (sc.Compare ("on"))
{
if (def1 != NULL)
if (def1 != nullptr)
{
sc.ScriptError ("Switch already has an on state");
}
@ -163,7 +164,7 @@ void FTextureManager::ProcessSwitchDef (FScanner &sc)
}
else if (sc.Compare ("off"))
{
if (def2 != NULL)
if (def2 != nullptr)
{
sc.ScriptError ("Switch already has an off state");
}
@ -176,14 +177,14 @@ void FTextureManager::ProcessSwitchDef (FScanner &sc)
}
}
if (def1 == NULL || !picnum.Exists() ||
if (def1 == nullptr || !picnum.Exists() ||
(gametype != GAME_Any && !(gametype & gameinfo.gametype)))
{
if (def2 != NULL)
if (def2 != nullptr)
{
M_Free (def2);
}
if (def1 != NULL)
if (def1 != nullptr)
{
M_Free (def1);
}
@ -192,7 +193,7 @@ void FTextureManager::ProcessSwitchDef (FScanner &sc)
// If the switch did not have an off state, create one that just returns
// it to the original texture without doing anything interesting
if (def2 == NULL)
if (def2 == nullptr)
{
def2 = (FSwitchDef *)M_Malloc (sizeof(FSwitchDef));
def2->Sound = def1->Sound;
@ -218,9 +219,9 @@ void FTextureManager::ProcessSwitchDef (FScanner &sc)
//
//==========================================================================
FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad)
FSwitchDef *FTextureAnimator::ParseSwitchDef (FScanner &sc, bool ignoreBad)
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
FSwitchDef *def;
TArray<FSwitchDef::frame> frames;
FSwitchDef::frame thisframe;
@ -244,7 +245,7 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad)
else if (sc.Compare ("pic"))
{
sc.MustGetString ();
picnum = CheckForTexture (sc.String, ETextureType::Wall, texflags);
picnum = TexMan.CheckForTexture (sc.String, ETextureType::Wall, texflags);
if (!picnum.Exists() && !ignoreBad)
{
//Printf ("Unknown switch texture %s\n", sc.String);
@ -293,14 +294,14 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad)
}
if (bad)
{
return NULL;
return nullptr;
}
def = (FSwitchDef *)M_Malloc (myoffsetof (FSwitchDef, frames[0]) + frames.Size()*sizeof(frames[0]));
def->Sound = sound;
def->NumFrames = frames.Size();
memcpy (&def->frames[0], &frames[0], frames.Size() * sizeof(frames[0]));
def->PairDef = NULL;
def->PairDef = nullptr;
return def;
}
@ -310,11 +311,11 @@ FSwitchDef *FTextureManager::ParseSwitchDef (FScanner &sc, bool ignoreBad)
//
//==========================================================================
void FTextureManager::AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2)
void FTextureAnimator::AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2)
{
unsigned int i;
FSwitchDef *sw1 = NULL;
FSwitchDef *sw2 = NULL;
FSwitchDef *sw1 = nullptr;
FSwitchDef *sw2 = nullptr;
unsigned int index1 = 0xffffffff, index2 = 0xffffffff;
for (i = mSwitchDefs.Size (); i-- > 0; )
@ -336,7 +337,7 @@ void FTextureManager::AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2)
def1->PairDef = def2;
def2->PairDef = def1;
if (sw1 != NULL && sw2 != NULL && sw1->PairDef == sw2 && sw2->PairDef == sw1)
if (sw1 != nullptr && sw2 != nullptr && sw1->PairDef == sw2 && sw2->PairDef == sw1)
{
//We are replacing an existing pair so we can safely delete the old definitions
M_Free(sw1);
@ -350,10 +351,10 @@ void FTextureManager::AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2)
// We should not break up an old pair if the new one only redefined one
// of the two textures. These paired definitions will only be used
// as the return animation so their names don't matter. Better clear them to be safe.
if (sw1 != NULL) sw1->PreTexture.SetInvalid();
if (sw2 != NULL) sw2->PreTexture.SetInvalid();
sw1 = NULL;
sw2 = NULL;
if (sw1 != nullptr) sw1->PreTexture.SetInvalid();
if (sw2 != nullptr) sw2->PreTexture.SetInvalid();
sw1 = nullptr;
sw2 = nullptr;
unsigned int pos = mSwitchDefs.Reserve(2);
mSwitchDefs[pos] = def1;
mSwitchDefs[pos+1] = def2;
@ -366,7 +367,7 @@ void FTextureManager::AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2)
//
//==========================================================================
FSwitchDef *FTextureManager::FindSwitch (FTextureID texture)
FSwitchDef *FTextureAnimator::FindSwitch (FTextureID texture)
{
int mid, low, high;
@ -391,6 +392,6 @@ FSwitchDef *FTextureManager::FindSwitch (FTextureID texture)
}
} while (low <= high);
}
return NULL;
return nullptr;
}

View file

@ -41,6 +41,7 @@
#include "p_spec.h"
#include "filesystem.h"
#include "serializer.h"
#include "animations.h"
// MACROS ------------------------------------------------------------------
@ -49,6 +50,7 @@
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
// PUBLIC DATA DEFINITIONS -------------------------------------------------
FTextureAnimator TexAnim;
// PRIVATE DATA DEFINITIONS ------------------------------------------------
@ -56,16 +58,49 @@ static FRandom pr_animatepictures ("AnimatePics");
// CODE --------------------------------------------------------------------
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++)
{
if (mSwitchDefs[i] != NULL)
{
M_Free(mSwitchDefs[i]);
mSwitchDefs[i] = NULL;
}
}
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();
}
//==========================================================================
//
// FTextureManager :: AddAnim
// FTextureAnimator :: AddAnim
//
// Adds a new animation to the array. If one with the same basepic as the
// new one already exists, it is replaced.
//
//==========================================================================
FAnimDef *FTextureManager::AddAnim (FAnimDef *anim)
FAnimDef *FTextureAnimator::AddAnim (FAnimDef *anim)
{
// Search for existing duplicate.
for (unsigned int i = 0; i < mAnimations.Size(); ++i)
@ -85,16 +120,16 @@ FAnimDef *FTextureManager::AddAnim (FAnimDef *anim)
//==========================================================================
//
// FTextureManager :: AddSimpleAnim
// FTextureAnimator :: AddSimpleAnim
//
// Creates an animation with simple characteristics. This is used for
// original Doom (non-ANIMDEFS-style) animations and Build animations.
//
//==========================================================================
FAnimDef *FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, uint32_t speedmin, uint32_t speedrange)
FAnimDef *FTextureAnimator::AddSimpleAnim (FTextureID picnum, int animcount, uint32_t speedmin, uint32_t speedrange)
{
if (AreTexturesCompatible(picnum, picnum + (animcount - 1)))
if (TexMan.AreTexturesCompatible(picnum, picnum + (animcount - 1)))
{
FAnimDef *anim = (FAnimDef *)M_Malloc (sizeof(FAnimDef));
anim->CurFrame = 0;
@ -113,13 +148,13 @@ FAnimDef *FTextureManager::AddSimpleAnim (FTextureID picnum, int animcount, uint
//==========================================================================
//
// FTextureManager :: AddComplexAnim
// FTextureAnimator :: AddComplexAnim
//
// Creates an animation with individually defined frames.
//
//==========================================================================
FAnimDef *FTextureManager::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]));
anim->BasePic = picnum;
@ -134,7 +169,7 @@ FAnimDef *FTextureManager::AddComplexAnim (FTextureID picnum, const TArray<FAnim
//==========================================================================
//
// FTextureManager :: Initanimated
// FTextureAnimator :: Initanimated
//
// [description copied from BOOM]
// Load the table of animation definitions, checking for existence of
@ -172,12 +207,12 @@ FAnimDef *FTextureManager::AddComplexAnim (FTextureID picnum, const TArray<FAnim
CVAR(Bool, debuganimated, false, 0)
void FTextureManager::InitAnimated (void)
void FTextureAnimator::InitAnimated (void)
{
const BITFIELD texflags = TEXMAN_Overridable;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable;
// I think better not! This is only for old ANIMATED definitions that
// don't know about ZDoom's more flexible texture system.
// | FTextureManager::TEXMAN_TryAny;
// | FTextureAnimator::FTextureManager::TEXMAN_TryAny;
int lumpnum = fileSystem.CheckNumForName ("ANIMATED");
if (lumpnum != -1)
@ -203,22 +238,24 @@ void FTextureManager::InitAnimated (void)
if (*anim_p /* .istexture */ & 1)
{
// different episode ?
if (!(pic1 = CheckForTexture ((const char*)(anim_p + 10) /* .startname */, ETextureType::Wall, texflags)).Exists() ||
!(pic2 = CheckForTexture ((const char*)(anim_p + 1) /* .endname */, ETextureType::Wall, texflags)).Exists())
if (!(pic1 = TexMan.CheckForTexture ((const char*)(anim_p + 10) /* .startname */, ETextureType::Wall, texflags)).Exists() ||
!(pic2 = TexMan.CheckForTexture ((const char*)(anim_p + 1) /* .endname */, ETextureType::Wall, texflags)).Exists())
continue;
// [RH] Bit 1 set means allow decals on walls with this texture
Texture(pic2)->bNoDecals = Texture(pic1)->bNoDecals = !(*anim_p & 2);
bool nodecals = !(*anim_p & 2);
TexMan.Texture(pic2)->SetNoDecals(nodecals);
TexMan.Texture(pic1)->SetNoDecals(nodecals);
}
else
{
if (!(pic1 = CheckForTexture ((const char*)(anim_p + 10) /* .startname */, ETextureType::Flat, texflags)).Exists() ||
!(pic2 = CheckForTexture ((const char*)(anim_p + 1) /* .startname */, ETextureType::Flat, texflags)).Exists())
if (!(pic1 = TexMan.CheckForTexture ((const char*)(anim_p + 10) /* .startname */, ETextureType::Flat, texflags)).Exists() ||
!(pic2 = TexMan.CheckForTexture ((const char*)(anim_p + 1) /* .startname */, ETextureType::Flat, texflags)).Exists())
continue;
}
FTexture *tex1 = Texture(pic1);
FTexture *tex2 = Texture(pic2);
FTexture *tex1 = TexMan.Texture(pic1);
FTexture *tex2 = TexMan.Texture(pic2);
animspeed = (anim_p[19] << 0) | (anim_p[20] << 8) |
(anim_p[21] << 16) | (anim_p[22] << 24);
@ -226,13 +263,13 @@ void FTextureManager::InitAnimated (void)
// SMMU-style swirly hack? Don't apply on already-warping texture
if (animspeed > 65535 && tex1 != NULL && !tex1->isWarped())
{
tex1->bWarped = 2;
tex1->SetWarpStyle(2);
}
// These tests were not really relevant for swirling textures, or even potentially
// harmful, so they have been moved to the else block.
else
{
if (tex1->UseType != tex2->UseType)
if (tex1->GetUseType() != tex2->GetUseType())
{
// not the same type -
continue;
@ -241,8 +278,8 @@ void FTextureManager::InitAnimated (void)
if (debuganimated)
{
Printf("Defining animation '%s' (texture %d, lump %d, file %d) to '%s' (texture %d, lump %d, file %d)\n",
tex1->Name.GetChars(), pic1.GetIndex(), tex1->GetSourceLump(), fileSystem.GetFileContainer(tex1->GetSourceLump()),
tex2->Name.GetChars(), pic2.GetIndex(), tex2->GetSourceLump(), fileSystem.GetFileContainer(tex2->GetSourceLump()));
tex1->GetName().GetChars(), pic1.GetIndex(), tex1->GetSourceLump(), fileSystem.GetFileContainer(tex1->GetSourceLump()),
tex2->GetName().GetChars(), pic2.GetIndex(), tex2->GetSourceLump(), fileSystem.GetFileContainer(tex2->GetSourceLump()));
}
if (pic1 == pic2)
@ -268,15 +305,15 @@ void FTextureManager::InitAnimated (void)
//==========================================================================
//
// FTextureManager :: InitAnimDefs
// FTextureAnimator :: InitAnimDefs
//
// This uses a Hexen ANIMDEFS lump to define the animation sequences
//
//==========================================================================
void FTextureManager::InitAnimDefs ()
void FTextureAnimator::InitAnimDefs ()
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
int lump, lastlump = 0;
while ((lump = fileSystem.FindLump ("ANIMDEFS", &lastlump)) != -1)
@ -313,11 +350,11 @@ void FTextureManager::InitAnimDefs ()
else if (sc.Compare("skyoffset"))
{
sc.MustGetString ();
FTextureID picnum = CheckForTexture (sc.String, ETextureType::Wall, texflags);
FTextureID picnum = TexMan.CheckForTexture (sc.String, ETextureType::Wall, texflags);
sc.MustGetNumber();
if (picnum.Exists())
{
Texture(picnum)->SkyOffset = sc.Number;
TexMan.Texture(picnum)->SetSkyOffset(sc.Number);
}
}
else
@ -330,16 +367,16 @@ void FTextureManager::InitAnimDefs ()
//==========================================================================
//
// FTextureManager :: ParseAnim
// FTextureAnimator :: ParseAnim
//
// Parse a single animation definition out of an ANIMDEFS lump and
// create the corresponding animation structure.
//
//==========================================================================
void FTextureManager::ParseAnim (FScanner &sc, ETextureType usetype)
void FTextureAnimator::ParseAnim (FScanner &sc, ETextureType usetype)
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
TArray<FAnimDef::FAnimFrame> frames (32);
FTextureID picnum;
int defined = 0;
@ -353,7 +390,7 @@ void FTextureManager::ParseAnim (FScanner &sc, ETextureType usetype)
optional = true;
sc.MustGetString ();
}
picnum = CheckForTexture (sc.String, usetype, texflags);
picnum = TexMan.CheckForTexture (sc.String, usetype, texflags);
if (!picnum.Exists())
{
@ -370,7 +407,7 @@ void FTextureManager::ParseAnim (FScanner &sc, ETextureType usetype)
// no decals on animating textures, by default
if (picnum.isValid())
{
Texture(picnum)->bNoDecals = true;
TexMan.Texture(picnum)->SetNoDecals(true);
}
while (sc.GetString ())
@ -379,7 +416,7 @@ void FTextureManager::ParseAnim (FScanner &sc, ETextureType usetype)
{
if (picnum.isValid())
{
Texture(picnum)->bNoDecals = false;
TexMan.Texture(picnum)->SetNoDecals(false);
}
continue;
}
@ -401,7 +438,7 @@ void FTextureManager::ParseAnim (FScanner &sc, ETextureType usetype)
}
else if (sc.Compare ("range"))
{
if (picnum.Exists() && Texture(picnum)->Name.IsEmpty())
if (picnum.Exists() && TexMan.Texture(picnum)->GetName().IsEmpty())
{
// long texture name: We cannot do ranged anims on these because they have no defined order
sc.ScriptError ("You cannot use \"range\" for long texture names.");
@ -452,14 +489,14 @@ void FTextureManager::ParseAnim (FScanner &sc, ETextureType usetype)
//==========================================================================
//
// FTextureManager :: ParseRangeAnim
// FTextureAnimator :: ParseRangeAnim
//
// Parse an animation defined using "range". Not that one range entry is
// enough to define a complete animation, unlike "pic".
//
//==========================================================================
FAnimDef *FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, ETextureType usetype, bool missing)
FAnimDef *FTextureAnimator::ParseRangeAnim (FScanner &sc, FTextureID picnum, ETextureType usetype, bool missing)
{
int type;
FTextureID framenum;
@ -475,7 +512,7 @@ FAnimDef *FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, ETex
return NULL; // Animation is only one frame or does not exist
}
if (Texture(framenum)->Name.IsEmpty())
if (TexMan.Texture(framenum)->GetName().IsEmpty())
{
// long texture name: We cannot do ranged anims on these because they have no defined order
sc.ScriptError ("You cannot use \"range\" for long texture names.");
@ -484,7 +521,7 @@ FAnimDef *FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, ETex
if (framenum < picnum)
{
type = FAnimDef::ANIM_Backward;
Texture(framenum)->bNoDecals = Texture(picnum)->bNoDecals;
TexMan.Texture(framenum)->SetNoDecals(TexMan.Texture(picnum)->allowNoDecals());
std::swap (framenum, picnum);
}
FAnimDef *ani = AddSimpleAnim (picnum, framenum - picnum + 1, min, max - min);
@ -494,13 +531,13 @@ FAnimDef *FTextureManager::ParseRangeAnim (FScanner &sc, FTextureID picnum, ETex
//==========================================================================
//
// FTextureManager :: ParsePicAnim
// FTextureAnimator :: ParsePicAnim
//
// Parse a single frame from ANIMDEFS defined using "pic".
//
//==========================================================================
void FTextureManager::ParsePicAnim (FScanner &sc, FTextureID picnum, ETextureType usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames)
void FTextureAnimator::ParsePicAnim (FScanner &sc, FTextureID picnum, ETextureType usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames)
{
FTextureID framenum;
uint32_t min = 1, max = 1;
@ -521,16 +558,16 @@ void FTextureManager::ParsePicAnim (FScanner &sc, FTextureID picnum, ETextureTyp
//==========================================================================
//
// FTextureManager :: ParseFramenum
// FTextureAnimator :: ParseFramenum
//
// Reads a frame's texture from ANIMDEFS. It can either be an integral
// offset from basepicnum or a specific texture name.
//
//==========================================================================
FTextureID FTextureManager::ParseFramenum (FScanner &sc, FTextureID basepicnum, ETextureType usetype, bool allowMissing)
FTextureID FTextureAnimator::ParseFramenum (FScanner &sc, FTextureID basepicnum, ETextureType usetype, bool allowMissing)
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
FTextureID framenum;
sc.MustGetString ();
@ -540,7 +577,7 @@ FTextureID FTextureManager::ParseFramenum (FScanner &sc, FTextureID basepicnum,
}
else
{
framenum = CheckForTexture (sc.String, usetype, texflags);
framenum = TexMan.CheckForTexture (sc.String, usetype, texflags);
if (!framenum.Exists() && !allowMissing)
{
sc.ScriptError ("Unknown texture %s", sc.String);
@ -551,13 +588,13 @@ FTextureID FTextureManager::ParseFramenum (FScanner &sc, FTextureID basepicnum,
//==========================================================================
//
// FTextureManager :: ParseTime
// FTextureAnimator :: ParseTime
//
// Reads a tics or rand time definition from ANIMDEFS.
//
//==========================================================================
void FTextureManager::ParseTime (FScanner &sc, uint32_t &min, uint32_t &max)
void FTextureAnimator::ParseTime (FScanner &sc, uint32_t &min, uint32_t &max)
{
sc.MustGetString ();
if (sc.Compare ("tics"))
@ -581,15 +618,15 @@ void FTextureManager::ParseTime (FScanner &sc, uint32_t &min, uint32_t &max)
//==========================================================================
//
// FTextureManager :: ParseWarp
// FTextureAnimator :: ParseWarp
//
// Parses a warping texture definition
//
//==========================================================================
void FTextureManager::ParseWarp(FScanner &sc)
void FTextureAnimator::ParseWarp(FScanner &sc)
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
bool isflat = false;
bool type2 = sc.Compare ("warp2"); // [GRB]
sc.MustGetString ();
@ -607,13 +644,13 @@ void FTextureManager::ParseWarp(FScanner &sc)
{
sc.ScriptError (NULL);
}
FTextureID picnum = CheckForTexture (sc.String, isflat ? ETextureType::Flat : ETextureType::Wall, texflags);
FTextureID picnum = TexMan.CheckForTexture (sc.String, isflat ? ETextureType::Flat : ETextureType::Wall, texflags);
if (picnum.isValid())
{
FTexture *warper = Texture(picnum);
FTexture *warper = TexMan.Texture(picnum);
if (warper->Name.IsEmpty())
if (warper->GetName().IsEmpty())
{
// long texture name: We cannot do warps on these due to the way the texture manager implements warping as a texture replacement.
sc.ScriptError ("You cannot use \"warp\" for long texture names.");
@ -623,7 +660,7 @@ void FTextureManager::ParseWarp(FScanner &sc)
// don't warp a texture more than once
if (!warper->isWarped())
{
warper->bWarped = type2? 2:1;
warper->SetWarpStyle(type2 ? 2 : 1);
}
if (sc.CheckFloat())
@ -634,12 +671,12 @@ void FTextureManager::ParseWarp(FScanner &sc)
// No decals on warping textures, by default.
// Warping information is taken from the last warp
// definition for this texture.
warper->bNoDecals = true;
warper->SetNoDecals(true);
if (sc.GetString ())
{
if (sc.Compare ("allowdecals"))
{
warper->bNoDecals = false;
warper->SetNoDecals(false);
}
else
{
@ -657,9 +694,9 @@ void FTextureManager::ParseWarp(FScanner &sc)
//
//==========================================================================
void FTextureManager::ParseCameraTexture(FScanner &sc)
void FTextureAnimator::ParseCameraTexture(FScanner &sc)
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ShortNameOnly;
int width, height;
int fitwidth, fitheight;
FString picname;
@ -670,23 +707,23 @@ void FTextureManager::ParseCameraTexture(FScanner &sc)
width = sc.Number;
sc.MustGetNumber ();
height = sc.Number;
FTextureID picnum = CheckForTexture (picname, ETextureType::Flat, texflags);
FTextureID picnum = TexMan.CheckForTexture (picname, ETextureType::Flat, texflags);
FTexture *viewer = new FCanvasTexture (picname, width, height);
if (picnum.Exists())
{
FTexture *oldtex = Texture(picnum);
fitwidth = oldtex->GetScaledWidth ();
fitheight = oldtex->GetScaledHeight ();
viewer->UseType = oldtex->UseType;
ReplaceTexture (picnum, viewer, true);
FTexture *oldtex = TexMan.Texture(picnum);
fitwidth = oldtex->GetDisplayWidth ();
fitheight = oldtex->GetDisplayHeight ();
viewer->SetUseType(oldtex->GetUseType());
TexMan.ReplaceTexture (picnum, viewer, true);
}
else
{
fitwidth = width;
fitheight = height;
// [GRB] No need for oldtex
viewer->UseType = ETextureType::Wall;
AddTexture (viewer);
viewer->SetUseType(ETextureType::Wall);
TexMan.AddTexture (viewer);
}
if (sc.GetString())
{
@ -706,19 +743,19 @@ void FTextureManager::ParseCameraTexture(FScanner &sc)
{
if (sc.Compare("WorldPanning"))
{
viewer->bWorldPanning = true;
viewer->SetWorldPanning(true);
}
else
{
sc.UnGet();
}
}
viewer->SetScaledSize(fitwidth, fitheight);
viewer->SetDisplaySize(fitwidth, fitheight);
}
//==========================================================================
//
// FTextureManager :: FixAnimations
// FTextureAnimator :: FixAnimations
//
// Copy the "front sky" flag from an animated texture to the rest
// of the textures in the animation, and make every texture in an
@ -726,7 +763,7 @@ void FTextureManager::ParseCameraTexture(FScanner &sc)
//
//==========================================================================
void FTextureManager::FixAnimations ()
void FTextureAnimator::FixAnimations ()
{
unsigned int i;
int j;
@ -736,11 +773,11 @@ void FTextureManager::FixAnimations ()
FAnimDef *anim = mAnimations[i];
if (anim->bDiscrete)
{
if (Texture(anim->BasePic)->bNoRemap0)
if (TexMan.Texture(anim->BasePic)->IsFrontSkyLayer())
{
for (j = 0; j < anim->NumFrames; ++j)
{
Texture(anim->Frames[j].FramePic)->SetFrontSkyLayer ();
TexMan.Texture(anim->Frames[j].FramePic)->SetFrontSkyLayer ();
}
}
}
@ -750,19 +787,19 @@ void FTextureManager::FixAnimations ()
bool noremap = false;
const char *name;
name = Texture(anim->BasePic)->Name;
nodecals = Texture(anim->BasePic)->bNoDecals;
name = TexMan.Texture(anim->BasePic)->GetName();
nodecals = TexMan.Texture(anim->BasePic)->allowNoDecals();
for (j = 0; j < anim->NumFrames; ++j)
{
FTexture *tex = Texture(anim->BasePic + j);
noremap |= tex->bNoRemap0;
tex->bNoDecals = nodecals;
FTexture *tex = TexMan.Texture(anim->BasePic + j);
noremap |= tex->IsFrontSkyLayer();
tex->SetNoDecals(nodecals);
}
if (noremap)
{
for (j = 0; j < anim->NumFrames; ++j)
{
Texture(anim->BasePic + j)->SetFrontSkyLayer ();
TexMan.Texture(anim->BasePic + j)->SetFrontSkyLayer ();
}
}
}
@ -777,16 +814,16 @@ void FTextureManager::FixAnimations ()
//
//==========================================================================
void FTextureManager::ParseAnimatedDoor(FScanner &sc)
void FTextureAnimator::ParseAnimatedDoor(FScanner &sc)
{
const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny;
const BITFIELD texflags = FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny;
FDoorAnimation anim;
TArray<FTextureID> frames;
bool error = false;
FTextureID v;
sc.MustGetString();
anim.BaseTexture = CheckForTexture (sc.String, ETextureType::Wall, texflags);
anim.BaseTexture = TexMan.CheckForTexture (sc.String, ETextureType::Wall, texflags);
anim.OpenSound = anim.CloseSound = NAME_None;
if (!anim.BaseTexture.Exists())
@ -795,7 +832,7 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc)
}
else
{
Texture(anim.BaseTexture)->bNoDecals = true;
TexMan.Texture(anim.BaseTexture)->SetNoDecals(true);
}
while (sc.GetString())
{
@ -818,7 +855,7 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc)
}
else
{
v = CheckForTexture (sc.String, ETextureType::Wall, texflags);
v = TexMan.CheckForTexture (sc.String, ETextureType::Wall, texflags);
if (!v.Exists() && anim.BaseTexture.Exists() && !error)
{
sc.ScriptError ("Unknown texture %s", sc.String);
@ -828,7 +865,7 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc)
}
else if (sc.Compare("allowdecals"))
{
if (anim.BaseTexture.Exists()) Texture(anim.BaseTexture)->bNoDecals = false;
if (anim.BaseTexture.Exists()) TexMan.Texture(anim.BaseTexture)->SetNoDecals(false);
}
else
{
@ -851,7 +888,7 @@ void FTextureManager::ParseAnimatedDoor(FScanner &sc)
//
//==========================================================================
FDoorAnimation *FTextureManager::FindAnimatedDoor (FTextureID picnum)
FDoorAnimation *FTextureAnimator::FindAnimatedDoor (FTextureID picnum)
{
unsigned int i;
@ -886,34 +923,13 @@ void FAnimDef::SetSwitchTime (uint64_t mstime)
//==========================================================================
//
// FTextureManager :: SetTranslation
//
// Sets animation translation for a texture
//
//==========================================================================
void FTextureManager::SetTranslation (FTextureID fromtexnum, FTextureID totexnum)
{
if ((size_t)fromtexnum.texnum < Translation.Size())
{
if ((size_t)totexnum.texnum >= Textures.Size())
{
totexnum.texnum = fromtexnum.texnum;
}
Translation[fromtexnum.texnum] = totexnum.texnum;
}
}
//==========================================================================
//
// FTextureManager :: UpdateAnimations
// FTextureAnimator :: UpdateAnimations
//
// Updates texture translations for each animation and scrolls the skies.
//
//==========================================================================
void FTextureManager::UpdateAnimations (uint64_t mstime)
void FTextureAnimator::UpdateAnimations (uint64_t mstime)
{
for (unsigned int j = 0; j < mAnimations.Size(); ++j)
{
@ -978,13 +994,13 @@ void FTextureManager::UpdateAnimations (uint64_t mstime)
if (anim->bDiscrete)
{
SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic);
TexMan.SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic);
}
else
{
for (unsigned int i = 0; i < anim->NumFrames; i++)
{
SetTranslation (anim->BasePic + i, anim->BasePic + (i + anim->CurFrame) % anim->NumFrames);
TexMan.SetTranslation (anim->BasePic + i, anim->BasePic + (i + anim->CurFrame) % anim->NumFrames);
}
}
}
@ -1002,7 +1018,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDoorAnimat
Serialize(arc, key, tex, def ? &(*def)->BaseTexture : nullptr);
if (arc.isReading())
{
p = TexMan.FindAnimatedDoor(tex);
p = TexAnim.FindAnimatedDoor(tex);
}
return arc;
}

View file

@ -0,0 +1,115 @@
#pragma once
#include <stdint.h>
#include "name.h"
#include "textureid.h"
#include "tarray.h"
struct FAnimDef
{
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];
enum
{
ANIM_Forward,
ANIM_Backward,
ANIM_OscillateUp,
ANIM_OscillateDown,
ANIM_Random
};
void SetSwitchTime(uint64_t mstime);
};
struct FSwitchDef
{
FTextureID PreTexture; // texture to switch from
FSwitchDef* PairDef; // switch def to use to return to PreTexture
uint16_t NumFrames; // # of animation frames
bool QuestPanel; // Special texture for Strife mission
int Sound; // sound to play at start of animation. Changed to int to avoiud having to include s_sound here.
struct frame // Array of times followed by array of textures
{ // actual length of each array is <NumFrames>
uint16_t TimeMin;
uint16_t TimeRnd;
FTextureID Texture;
} frames[1];
};
struct FDoorAnimation
{
FTextureID BaseTexture;
FTextureID* TextureFrames;
int NumTextureFrames;
FName OpenSound;
FName CloseSound;
};
class FTextureAnimator
{
TArray<FAnimDef*> mAnimations;
TArray<FSwitchDef*> mSwitchDefs;
TArray<FDoorAnimation> mAnimatedDoors;
void ParseAnim(FScanner& sc, ETextureType usetype);
FAnimDef* ParseRangeAnim(FScanner& sc, FTextureID picnum, ETextureType usetype, bool missing);
void ParsePicAnim(FScanner& sc, FTextureID picnum, ETextureType usetype, bool missing, TArray<FAnimDef::FAnimFrame>& frames);
void ParseWarp(FScanner& sc);
void ParseCameraTexture(FScanner& sc);
FTextureID ParseFramenum(FScanner& sc, FTextureID basepicnum, ETextureType usetype, bool allowMissing);
void ParseTime(FScanner& sc, uint32_t& min, uint32_t& max);
void FixAnimations();
void InitAnimated();
void InitAnimDefs();
void InitSwitchList();
void ProcessSwitchDef(FScanner& sc);
FSwitchDef* ParseSwitchDef(FScanner& sc, bool ignoreBad);
void AddSwitchPair(FSwitchDef* def1, FSwitchDef* def2);
void ParseAnimatedDoor(FScanner& sc);
public:
~FTextureAnimator()
{
DeleteAll();
}
// Animation stuff
FAnimDef* AddAnim(FAnimDef* anim);
void DeleteAll();
FAnimDef* AddSimpleAnim(FTextureID picnum, int animcount, uint32_t speedmin, uint32_t speedrange = 0);
FAnimDef* AddComplexAnim(FTextureID picnum, const TArray<FAnimDef::FAnimFrame>& frames);
FSwitchDef* FindSwitch(FTextureID texture);
FDoorAnimation* FindAnimatedDoor(FTextureID picnum);
void UpdateAnimations(uint64_t mstime);
const TArray<FAnimDef*>& GetAnimations() const { return mAnimations; }
void Init()
{
DeleteAll();
InitAnimated();
InitAnimDefs();
FixAnimations();
InitSwitchList();
}
};
extern FTextureAnimator TexAnim;

View file

@ -43,6 +43,7 @@
#include "textures/textures.h"
#include "resourcefile.h"
#include "image.h"
#include "animations.h"
//==========================================================================
@ -234,7 +235,7 @@ void AddTiles(const FString& pathprefix, const void* tiles, int translation)
speed = (anm >> 24) & 15;
speed = MAX(1, (1 << speed) * 1000 / 120); // Convert from 120 Hz to 1000 Hz.
TexMan.AddSimpleAnim(texnum, picanm[pic] & 63, type, speed);
TexAnim.AddSimpleAnim(texnum, picanm[pic] & 63, type, speed);
}
// Blood's rotation types:

View file

@ -188,17 +188,6 @@ FTexture::~FTexture ()
}
}
//==========================================================================
//
//
//
//==========================================================================
void FTexture::SetFrontSkyLayer ()
{
bNoRemap0 = true;
}
//===========================================================================
//
// FTexture::GetBgraBitmap
@ -248,7 +237,7 @@ FTexture *FTexture::GetRawTexture()
return OffsetLess;
}
void FTexture::SetScaledSize(int fitwidth, int fitheight)
void FTexture::SetDisplaySize(int fitwidth, int fitheight)
{
Scale.X = double(Width) / fitwidth;
Scale.Y =double(Height) / fitheight;

View file

@ -0,0 +1,58 @@
#pragma once
enum class ETextureType : uint8_t
{
Any,
Wall,
Flat,
Sprite,
WallPatch,
Build, // no longer used but needs to remain for ZScript
SkinSprite,
Decal,
MiscPatch,
FontChar,
Override, // For patches between TX_START/TX_END
Autopage, // Automap background - used to enable the use of FAutomapTexture
SkinGraphic,
Null,
FirstDefined,
SWCanvas,
};
class FTextureID
{
friend class FTextureManager;
friend void R_InitSpriteDefs();
public:
FTextureID() = default;
bool isNull() const { return texnum == 0; }
bool isValid() const { return texnum > 0; }
bool Exists() const { return texnum >= 0; }
void SetInvalid() { texnum = -1; }
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();
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!
// The switch list needs these to sort the switches by texture index
int operator -(FTextureID other) const { return texnum - other.texnum; }
bool operator < (FTextureID other) const { return texnum < other.texnum; }
bool operator > (FTextureID other) const { return texnum > other.texnum; }
protected:
FTextureID(int num) { texnum = num; }
private:
int texnum;
};
// This is for the script interface which needs to do casts from int to texture.
class FSetTextureID : public FTextureID
{
public:
FSetTextureID(int v) : FTextureID(v) {}
};

View file

@ -111,35 +111,6 @@ void FTextureManager::DeleteAll()
memset (HashFirst, -1, sizeof(HashFirst));
DefaultTexture.SetInvalid();
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++)
{
if (mSwitchDefs[i] != NULL)
{
M_Free (mSwitchDefs[i]);
mSwitchDefs[i] = NULL;
}
}
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();
BuildTileData.Clear();
tmanips.Clear();
}
@ -668,7 +639,7 @@ void FTextureManager::AddHiresTextures (int wadnum)
// Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true;
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
newtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
@ -765,7 +736,7 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
{
// Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true;
newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight());
newtex->SetDisplaySize(oldtex->GetDisplayWidth(), oldtex->GetDisplayHeight());
newtex->_LeftOffset[0] = int(oldtex->GetScaledLeftOffset(0) * newtex->Scale.X);
newtex->_LeftOffset[1] = int(oldtex->GetScaledLeftOffset(1) * newtex->Scale.X);
newtex->_TopOffset[0] = int(oldtex->GetScaledTopOffset(0) * newtex->Scale.Y);
@ -805,7 +776,7 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build
{
// Replace the entire texture and adjust the scaling and offset factors.
newtex->bWorldPanning = true;
newtex->SetScaledSize(width, height);
newtex->SetDisplaySize(width, height);
FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch);
if (oldtex.isValid())
@ -1241,10 +1212,6 @@ void FTextureManager::Init()
}
}
InitAnimated();
InitAnimDefs();
FixAnimations();
InitSwitchList();
InitPalettedVersions();
AdjustSpriteOffsets();
// Add auto materials to each texture after everything has been set up.
@ -1533,6 +1500,29 @@ void FTextureManager::SpriteAdjustChanged()
}
}
//==========================================================================
//
// FTextureAnimator :: SetTranslation
//
// Sets animation translation for a texture
//
//==========================================================================
void FTextureManager::SetTranslation(FTextureID fromtexnum, FTextureID totexnum)
{
if ((size_t)fromtexnum.texnum < Translation.Size())
{
if ((size_t)totexnum.texnum >= Textures.Size())
{
totexnum.texnum = fromtexnum.texnum;
}
Translation[fromtexnum.texnum] = totexnum.texnum;
}
}
//==========================================================================
//
//

View file

@ -140,56 +140,6 @@ public:
// [RH] Expanded to work with a Hexen ANIMDEFS lump
//
struct FAnimDef
{
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];
enum
{
ANIM_Forward,
ANIM_Backward,
ANIM_OscillateUp,
ANIM_OscillateDown,
ANIM_Random
};
void SetSwitchTime (uint64_t mstime);
};
struct FSwitchDef
{
FTextureID PreTexture; // texture to switch from
FSwitchDef *PairDef; // switch def to use to return to PreTexture
uint16_t NumFrames; // # of animation frames
bool QuestPanel; // Special texture for Strife mission
int Sound; // sound to play at start of animation. Changed to int to avoiud having to include s_sound here.
struct frame // Array of times followed by array of textures
{ // actual length of each array is <NumFrames>
uint16_t TimeMin;
uint16_t TimeRnd;
FTextureID Texture;
} frames[1];
};
struct FDoorAnimation
{
FTextureID BaseTexture;
FTextureID *TextureFrames;
int NumTextureFrames;
FName OpenSound;
FName CloseSound;
};
// All FTextures present their data to the world in 8-bit format, but if
// the source data is something else, this is it.
enum FTextureFormat : uint32_t
@ -321,9 +271,12 @@ public:
bool isSprite() const { return UseType == ETextureType::Sprite || UseType == ETextureType::SkinSprite || UseType == ETextureType::Decal; }
const FString &GetName() const { return Name; }
void SetNoDecals(bool on) { bNoDecals = on; }
void SetWarpStyle(int style) { bWarped = style; }
bool allowNoDecals() const { return bNoDecals; }
bool isScaled() const { return Scale.X != 1 || Scale.Y != 1; }
bool isMasked() const { return bMasked; }
void SetSkyOffset(int offs) { SkyOffset = offs; }
int GetSkyOffset() const { return SkyOffset; }
FTextureID GetID() const { return id; }
PalEntry GetSkyCapColor(bool bottom);
@ -339,6 +292,12 @@ public:
void SetUseType(ETextureType type) { UseType = type; }
int GetSourceLump() const { return SourceLump; }
ETextureType GetUseType() const { return UseType; }
void SetSpeed(float fac) { shaderspeed = fac; }
void SetWorldPanning(bool on) { bWorldPanning = on; }
void SetDisplaySize(int fitwidth, int fitheight);
void SetFrontSkyLayer(bool on = true) { bNoRemap0 = on; }
bool IsFrontSkyLayer() { return bNoRemap0; }
void CopySize(FTexture* BaseTexture)
{
@ -436,8 +395,6 @@ protected:
Height = h;
}
void SetSpeed(float fac) { shaderspeed = fac; }
int GetScaledWidth () { int foo = int((Width * 2) / Scale.X); return (foo >> 1) + (foo & 1); }
int GetScaledHeight () { int foo = int((Height * 2) / Scale.Y); return (foo >> 1) + (foo & 1); }
double GetScaledWidthDouble () { return Width / Scale.X; }
@ -461,11 +418,8 @@ protected:
virtual void ResolvePatches() {}
void SetFrontSkyLayer();
static void InitGrayMap();
void SetScaledSize(int fitwidth, int fitheight);
void SetScale(const DVector2 &scale)
{
Scale = scale;
@ -600,12 +554,8 @@ public:
int NumTextures () const { return (int)Textures.Size(); }
void UpdateAnimations (uint64_t mstime);
int GuesstimateNumTextures ();
FSwitchDef *FindSwitch (FTextureID texture);
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
TextureManipulation* GetTextureManipulation(FName name)
{
return tmanips.CheckKey(name);
@ -629,14 +579,7 @@ private:
// Build tiles
//int CountBuildTiles ();
// Animation stuff
FAnimDef *AddAnim (FAnimDef *anim);
void FixAnimations ();
void InitAnimated ();
void InitAnimDefs ();
public:
FAnimDef *AddSimpleAnim (FTextureID picnum, int animcount, uint32_t speedmin, uint32_t speedrange=0);
FAnimDef *AddComplexAnim (FTextureID picnum, const TArray<FAnimDef::FAnimFrame> &frames);
TArray<uint8_t>& GetNewBuildTileData()
{
@ -644,27 +587,15 @@ public:
return BuildTileData.Last();
}
private:
void ParseAnim (FScanner &sc, ETextureType usetype);
FAnimDef *ParseRangeAnim (FScanner &sc, FTextureID picnum, ETextureType usetype, bool missing);
void ParsePicAnim (FScanner &sc, FTextureID picnum, ETextureType usetype, bool missing, TArray<FAnimDef::FAnimFrame> &frames);
void ParseWarp(FScanner &sc);
void ParseCameraTexture(FScanner &sc);
FTextureID ParseFramenum (FScanner &sc, FTextureID basepicnum, ETextureType usetype, bool allowMissing);
void ParseTime (FScanner &sc, uint32_t &min, uint32_t &max);
FTexture* Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; }
void SetTranslation(FTextureID fromtexnum, FTextureID totexnum);
void ParseAnimatedDoor(FScanner &sc);
private:
void InitPalettedVersions();
// Switches
void InitSwitchList ();
void ProcessSwitchDef (FScanner &sc);
FSwitchDef *ParseSwitchDef (FScanner &sc, bool ignoreBad);
void AddSwitchPair (FSwitchDef *def1, FSwitchDef *def2);
struct TextureHash
{
FTexture *Texture;
@ -674,18 +605,15 @@ private:
enum { HASH_END = -1, HASH_SIZE = 1027 };
TArray<TextureHash> Textures;
TMap<uint64_t, int> LocalizedTextures;
TArray<int> Translation;
int HashFirst[HASH_SIZE];
FTextureID DefaultTexture;
TArray<int> FirstTextureForFile;
TArray<TArray<uint8_t> > BuildTileData;
TArray<int> Translation;
TArray<FSwitchDef *> mSwitchDefs;
TArray<FDoorAnimation> mAnimatedDoors;
TMap<FName, TextureManipulation> tmanips;
public:
TArray<FAnimDef *> mAnimations;
short sintable[2048]; // for texture warping
enum

View file

@ -76,6 +76,7 @@
#include "v_video.h"
#include "fragglescript/t_script.h"
#include "s_music.h"
#include "animations.h"
extern AActor *SpawnMapThing (int index, FMapThing *mthing, int position);
@ -98,7 +99,7 @@ static void AddToList(uint8_t *hitlist, FTextureID texid, int bitmask)
const auto addAnimations = [hitlist, bitmask](const FTextureID texid)
{
for (auto anim : TexMan.mAnimations)
for (auto anim : TexAnim.GetAnimations())
{
if (texid == anim->BasePic || (!anim->bDiscrete && anim->BasePic < texid && texid < anim->BasePic + anim->NumFrames))
{
@ -112,7 +113,7 @@ static void AddToList(uint8_t *hitlist, FTextureID texid, int bitmask)
addAnimations(texid);
auto switchdef = TexMan.FindSwitch(texid);
auto switchdef = TexAnim.FindSwitch(texid);
if (switchdef)
{
const FSwitchDef *const pair = switchdef->PairDef;
@ -136,7 +137,7 @@ static void AddToList(uint8_t *hitlist, FTextureID texid, int bitmask)
}
}
auto adoor = TexMan.FindAnimatedDoor(texid);
auto adoor = TexAnim.FindAnimatedDoor(texid);
if (adoor)
{
for (int i = 0; i < adoor->NumTextureFrames; i++)

View file

@ -38,6 +38,7 @@
#include "d_player.h"
#include "p_spec.h"
#include "g_levellocals.h"
#include "animations.h"
//============================================================================
//
@ -780,7 +781,7 @@ bool FLevelLocals::EV_SlidingDoor (line_t *line, AActor *actor, int tag, int spe
// Do not attempt to close the door if it already is
else if (type == DAnimatedDoor::adClose)
return false;
FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top));
FDoorAnimation *anim = TexAnim.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top));
if (anim != NULL)
{
CreateThinker<DAnimatedDoor>(sec, line, speed, delay, anim, type);
@ -816,7 +817,7 @@ bool FLevelLocals::EV_SlidingDoor (line_t *line, AActor *actor, int tag, int spe
{
continue;
}
FDoorAnimation *anim = TexMan.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top));
FDoorAnimation *anim = TexAnim.FindAnimatedDoor (line->sidedef[0]->GetTexture(side_t::top));
if (anim != NULL)
{
rtn = true;

View file

@ -47,6 +47,7 @@
#include "textures.h"
#include "actor.h"
#include "actorinlines.h"
#include "animations.h"
static FRandom pr_switchanim ("AnimSwitch");
@ -174,7 +175,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 *
if (open.range <= 0)
goto onesided;
if ((TexMan.FindSwitch(side->GetTexture(side_t::top))) != NULL)
if ((TexAnim.FindSwitch(side->GetTexture(side_t::top))) != NULL)
{
// Check 3D floors on back side
@ -198,7 +199,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 *
? (user->Top() >= open.top)
: (user->Top() > open.top);
}
else if ((TexMan.FindSwitch(side->GetTexture(side_t::bottom))) != NULL)
else if ((TexAnim.FindSwitch(side->GetTexture(side_t::bottom))) != NULL)
{
// Check 3D floors on back side
{
@ -222,7 +223,7 @@ bool P_CheckSwitchRange(AActor *user, line_t *line, int sideno, const DVector3 *
? (user->Z() <= open.bottom)
: (user->Z() < open.bottom);
}
else if ((flags & ML_3DMIDTEX) || (TexMan.FindSwitch(side->GetTexture(side_t::mid))) != NULL)
else if ((flags & ML_3DMIDTEX) || (TexAnim.FindSwitch(side->GetTexture(side_t::mid))) != NULL)
{
// 3DMIDTEX lines will force a mid texture check if no switch is found on this line
// to keep compatibility with Eternity's implementation.
@ -252,15 +253,15 @@ bool P_ChangeSwitchTexture (side_t *side, int useAgain, uint8_t special, bool *q
int sound;
FSwitchDef *Switch;
if ((Switch = TexMan.FindSwitch (side->GetTexture(side_t::top))) != NULL)
if ((Switch = TexAnim.FindSwitch (side->GetTexture(side_t::top))) != NULL)
{
texture = side_t::top;
}
else if ((Switch = TexMan.FindSwitch (side->GetTexture(side_t::bottom))) != NULL)
else if ((Switch = TexAnim.FindSwitch (side->GetTexture(side_t::bottom))) != NULL)
{
texture = side_t::bottom;
}
else if ((Switch = TexMan.FindSwitch (side->GetTexture(side_t::mid))) != NULL)
else if ((Switch = TexAnim.FindSwitch (side->GetTexture(side_t::mid))) != NULL)
{
texture = side_t::mid;
}
@ -353,7 +354,7 @@ template<> FSerializer &Serialize (FSerializer &arc, const char *key, FSwitchDef
FTextureID tex;
tex.SetInvalid();
Serialize(arc, key, tex, nullptr);
Switch = TexMan.FindSwitch(tex);
Switch = TexAnim.FindSwitch(tex);
}
return arc;
}

View file

@ -91,6 +91,7 @@ class DoomSoundEngine : public SoundEngine
{
auto ndx = SoundEngine::AddSoundLump(logicalname, lump, CurrentPitchMask, resid, nearlimit);
S_sfx[ndx].UserData.Resize(1);
S_sfx[ndx].UserData[0] = 0;
return ndx;
}
bool CheckSoundLimit(sfxinfo_t* sfx, const FVector3& pos, int near_limit, float limit_range, int sourcetype, const void* actor, int channel) override