raze/source/common/textures/texturemanager.h
2023-08-19 16:59:05 +02:00

251 lines
6.6 KiB
C++

#pragma once
#include <stdint.h>
#include "tarray.h"
#include "textureid.h"
#include "textures.h"
#include "basics.h"
#include "texmanip.h"
#include "name.h"
class FxAddSub;
struct BuildInfo;
class FMultipatchTextureBuilder;
class FScanner;
// Texture manager
class FTextureManager
{
void (*progressFunc)();
friend class FxAddSub; // needs access to do a bounds check on the texture ID.
public:
FTextureManager ();
~FTextureManager ();
private:
int ResolveLocalizedTexture(int texnum);
int ResolveTextureIndex(int texnum, bool animate) const
{
if ((unsigned)texnum >= Textures.Size()) return -1;
if (animate) texnum = Translation[texnum];
//if (localize && Textures[texnum].Flags & TEXFLAG_HASLOCALIZATION) texnum = ResolveLocalizedTexture(texnum);
return texnum;
}
FGameTexture *InternalGetTexture(int texnum, bool animate) const
{
texnum = ResolveTextureIndex(texnum, animate);
if (texnum == -1) return nullptr;
return Textures[texnum].Texture;
}
FTextureID ResolveTextureIndex(FTextureID texid, bool animate) const
{
return FSetTextureID(ResolveTextureIndex(texid.GetIndex(), animate));
}
public:
// This only gets used in UI code so we do not need PALVERS handling.
FGameTexture* GetGameTextureByName(const char *name, bool animate = false, int flags = 0)
{
FTextureID texnum = GetTextureID(name, ETextureType::MiscPatch, flags);
return InternalGetTexture(texnum.GetIndex(), animate);
}
FGameTexture* GetGameTexture(FTextureID texnum, bool animate = false) const
{
return InternalGetTexture(texnum.GetIndex(), animate);
}
FGameTexture* GetPalettedTexture(FTextureID texnum, bool animate = false, bool allowsubstitute = true) const
{
auto texid = ResolveTextureIndex(texnum.GetIndex(), animate);
if (texid == -1) return nullptr;
if (allowsubstitute && Textures[texid].Paletted > 0) texid = Textures[texid].Paletted;
return Textures[texid].Texture;
}
FGameTexture* GameByIndex(int i, bool animate = false) const
{
return InternalGetTexture(i, animate);
}
FGameTexture* FindGameTexture(const char* texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny);
bool OkForLocalization(FTextureID texnum, const char *substitute, int locnum);
void FlushAll();
void Listaliases();
FTextureID GetFrontSkyLayer(FTextureID);
FTextureID GetRawTexture(FTextureID tex, bool dontlookup = false);
void SetRawTexture(FTextureID texid)
{
int texidx = texid.GetIndex();
if ((unsigned)texidx < Textures.Size())
{
Textures[texidx].RawTexture = texidx;
}
}
//==========================================================================
//
// link a texture with a given lump
//
//==========================================================================
TMap<int, FGameTexture*> linkedMap;
void SetLinkedTexture(int lump, FGameTexture* tex);
FGameTexture* GetLinkedTexture(int lump);
enum
{
TEXMAN_TryAny = 1,
TEXMAN_Overridable = 2,
TEXMAN_ReturnFirst = 4,
TEXMAN_AllowSkins = 8,
TEXMAN_ShortNameOnly = 16,
TEXMAN_DontCreate = 32,
TEXMAN_Localize = 64,
TEXMAN_ForceLookup = 128,
TEXMAN_NoAlias = 256,
TEXMAN_ReturnAll = 512,
};
enum
{
HIT_Wall = 1,
HIT_Flat = 2,
HIT_Sky = 4,
HIT_Sprite = 8,
HIT_Columnmode = HIT_Wall|HIT_Sky|HIT_Sprite
};
FTextureID CheckForTexture (const char *name, ETextureType usetype, BITFIELD flags=TEXMAN_TryAny);
FTextureID GetTextureID (const char *name, ETextureType usetype, BITFIELD flags=0);
int ListTextures (const char *name, TArray<FTextureID> &list, bool listall = false);
void AddGroup(int wadnum, int ns, ETextureType usetype);
void AddPatches (int lumpnum);
void AddHiresTextures (int wadnum);
void LoadTextureDefs(int wadnum, const char *lumpname, FMultipatchTextureBuilder &build);
void ParseColorization(FScanner& sc);
void ParseTextureDef(int remapLump, FMultipatchTextureBuilder &build);
void SortTexturesByType(int start, int end);
bool AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2);
void AddLocalizedVariants();
FTextureID CreateTexture (int lumpnum, ETextureType usetype=ETextureType::Any); // Also calls AddTexture
FTextureID AddGameTexture(FGameTexture* texture, bool addtohash = true);
FTextureID GetDefaultTexture() const { return DefaultTexture; }
void LoadTextureX(int wadnum, FMultipatchTextureBuilder &build);
void AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &build);
void Init();
void AddTextures(void (*progressFunc_)(), void (*checkForHacks)(BuildInfo&), void (*customtexturehandler)() = nullptr);
void DeleteAll();
void ReplaceTexture (FTextureID texid, FGameTexture *newtexture, bool free);
int NumTextures () const { return (int)Textures.Size(); }
int GuesstimateNumTextures ();
TextureManipulation* GetTextureManipulation(FName name)
{
return tmanips.CheckKey(name);
}
void InsertTextureManipulation(FName cname, TextureManipulation tm)
{
tmanips.Insert(cname, tm);
}
void RemoveTextureManipulation(FName cname)
{
tmanips.Remove(cname);
}
void AddAlias(const char* name, int texindex);
void AddAlias(const char* name, FTextureID texindex)
{
AddAlias(name, texindex.GetIndex());
}
private:
// texture counting
int CountTexturesX ();
int CountLumpTextures (int lumpnum);
void AdjustSpriteOffsets();
// Build tiles
//int CountBuildTiles ();
public:
TArray<uint8_t>& GetNewBuildTileData()
{
BuildTileData.Reserve(1);
return BuildTileData.Last();
}
TArray<TArray<uint8_t>>& GetBuildTileDataStore()
{
return BuildTileData;
}
FGameTexture* GameTexture(FTextureID id) { return Textures[id.GetIndex()].Texture; }
void SetTranslation(FTextureID fromtexnum, FTextureID totexnum);
private:
void InitPalettedVersions();
// Switches
struct TextureDescriptor
{
FGameTexture* Texture;
int Paletted; // redirection to paletted variant
int FrontSkyLayer; // and front sky layer,
int RawTexture;
int HashNext;
uint64_t Flags;
};
enum : uint64_t
{
TEXFLAG_HASLOCALIZATION = 1,
};
public:
constexpr static int TEXFLAG_FIRSTUSER = 65536; // this leaves 16 flags to the texture manager and 48 flags to the user
private:
enum { HASH_END = -1, HASH_SIZE = 1027 };
TArray<TextureDescriptor> Textures;
TMap<uint64_t, int> LocalizedTextures;
int HashFirst[HASH_SIZE];
FTextureID DefaultTexture;
TArray<int> FirstTextureForFile;
TArray<TArray<uint8_t> > BuildTileData;
TArray<int> Translation;
TMap<FName, TextureManipulation> tmanips;
TMap<FName, int> aliases;
public:
short sintable[2048]; // for texture warping
enum
{
SINMASK = 2047
};
FTextureID glPart2;
FTextureID glPart;
FTextureID mirrorTexture;
bool usefullnames;
};
extern FTextureManager TexMan;