From be24023722f4f6ddfef7294a5a3c11986770d92e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 11 Apr 2020 18:54:54 +0200 Subject: [PATCH] - split animation management out of the texture manager into a separate class. --- src/d_main.cpp | 5 +- src/doomtype.h | 58 +---- src/gamedata/textures/anim_switches.cpp | 63 ++--- src/gamedata/textures/animations.cpp | 236 ++++++++++-------- src/gamedata/textures/animations.h | 115 +++++++++ .../textures/formats/buildtexture.cpp | 3 +- src/gamedata/textures/texture.cpp | 13 +- src/gamedata/textures/textureid.h | 58 +++++ src/gamedata/textures/texturemanager.cpp | 62 ++--- src/gamedata/textures/textures.h | 98 +------- src/p_setup.cpp | 7 +- src/playsim/mapthinkers/a_doors.cpp | 5 +- src/playsim/p_switch.cpp | 15 +- src/sound/s_doomsound.cpp | 1 + 14 files changed, 394 insertions(+), 345 deletions(-) create mode 100644 src/gamedata/textures/animations.h create mode 100644 src/gamedata/textures/textureid.h diff --git a/src/d_main.cpp b/src/d_main.cpp index cce74ed45..c14fcdc72 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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 = ""; diff --git a/src/doomtype.h b/src/doomtype.h index a382522c8..1f40f0f2c 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -38,63 +38,7 @@ typedef TMap 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 { diff --git a/src/gamedata/textures/anim_switches.cpp b/src/gamedata/textures/anim_switches.cpp index 9856e8b49..1212efd2b 100644 --- a/src/gamedata/textures/anim_switches.cpp +++ b/src/gamedata/textures/anim_switches.cpp @@ -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 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; } diff --git a/src/gamedata/textures/animations.cpp b/src/gamedata/textures/animations.cpp index bb7e3b066..c759da4c3 100644 --- a/src/gamedata/textures/animations.cpp +++ b/src/gamedata/textures/animations.cpp @@ -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 &frames) +FAnimDef *FTextureAnimator::AddComplexAnim (FTextureID picnum, const TArray &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 TArraybNoDecals = 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 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 &frames) +void FTextureAnimator::ParsePicAnim (FScanner &sc, FTextureID picnum, ETextureType usetype, bool missing, TArray &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 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; } diff --git a/src/gamedata/textures/animations.h b/src/gamedata/textures/animations.h new file mode 100644 index 000000000..078ed5f67 --- /dev/null +++ b/src/gamedata/textures/animations.h @@ -0,0 +1,115 @@ +#pragma once + +#include +#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 + 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 mAnimations; + TArray mSwitchDefs; + TArray 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& 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& frames); + + FSwitchDef* FindSwitch(FTextureID texture); + FDoorAnimation* FindAnimatedDoor(FTextureID picnum); + void UpdateAnimations(uint64_t mstime); + + const TArray& GetAnimations() const { return mAnimations; } + + void Init() + { + DeleteAll(); + InitAnimated(); + InitAnimDefs(); + FixAnimations(); + InitSwitchList(); + } +}; + +extern FTextureAnimator TexAnim; + + diff --git a/src/gamedata/textures/formats/buildtexture.cpp b/src/gamedata/textures/formats/buildtexture.cpp index fba5c3493..5cbcc0e31 100644 --- a/src/gamedata/textures/formats/buildtexture.cpp +++ b/src/gamedata/textures/formats/buildtexture.cpp @@ -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: diff --git a/src/gamedata/textures/texture.cpp b/src/gamedata/textures/texture.cpp index 95bd356f7..c1923ccff 100644 --- a/src/gamedata/textures/texture.cpp +++ b/src/gamedata/textures/texture.cpp @@ -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; diff --git a/src/gamedata/textures/textureid.h b/src/gamedata/textures/textureid.h new file mode 100644 index 000000000..76cec58b9 --- /dev/null +++ b/src/gamedata/textures/textureid.h @@ -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) {} +}; + diff --git a/src/gamedata/textures/texturemanager.cpp b/src/gamedata/textures/texturemanager.cpp index 42f88ca95..888bb1d5c 100644 --- a/src/gamedata/textures/texturemanager.cpp +++ b/src/gamedata/textures/texturemanager.cpp @@ -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; + } +} + + + //========================================================================== // // diff --git a/src/gamedata/textures/textures.h b/src/gamedata/textures/textures.h index d2dccf614..f78391107 100644 --- a/src/gamedata/textures/textures.h +++ b/src/gamedata/textures/textures.h @@ -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 - 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 &frames); TArray& GetNewBuildTileData() { @@ -644,27 +587,15 @@ public: return BuildTileData.Last(); } + FTexture* Texture(FTextureID id) { return Textures[id.GetIndex()].Texture; } + void SetTranslation(FTextureID fromtexnum, FTextureID totexnum); + 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 &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); 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 Textures; TMap LocalizedTextures; - TArray Translation; int HashFirst[HASH_SIZE]; FTextureID DefaultTexture; TArray FirstTextureForFile; TArray > BuildTileData; + TArray Translation; - TArray mSwitchDefs; - TArray mAnimatedDoors; TMap tmanips; public: - TArray mAnimations; short sintable[2048]; // for texture warping enum diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 7245f4cf0..c7d511990 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -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++) diff --git a/src/playsim/mapthinkers/a_doors.cpp b/src/playsim/mapthinkers/a_doors.cpp index f517d20db..8342ff4b4 100644 --- a/src/playsim/mapthinkers/a_doors.cpp +++ b/src/playsim/mapthinkers/a_doors.cpp @@ -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(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; diff --git a/src/playsim/p_switch.cpp b/src/playsim/p_switch.cpp index 51248e6b5..7453418cc 100644 --- a/src/playsim/p_switch.cpp +++ b/src/playsim/p_switch.cpp @@ -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; } diff --git a/src/sound/s_doomsound.cpp b/src/sound/s_doomsound.cpp index 63967d68f..d99534bad 100644 --- a/src/sound/s_doomsound.cpp +++ b/src/sound/s_doomsound.cpp @@ -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