mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-08 14:01:32 +00:00
61cbb1d2e1
- Fixed: The recent changes in the DECORATE parser require the special parameter to A_CallSpecial to be an expression, not a constant. - Removed game filters from old style decorations. No WAD in existence ever used them and removing them allows to make the parser more robust. SVN r1170 (trunk)
349 lines
11 KiB
C++
349 lines
11 KiB
C++
#ifndef __TEXTURES_H
|
|
#define __TEXTURES_H
|
|
|
|
#include "doomtype.h"
|
|
#include "m_fixed.h"
|
|
|
|
class FBitmap;
|
|
struct FRemapTable;
|
|
struct FCopyInfo;
|
|
class FScanner;
|
|
|
|
// Texture IDs
|
|
class FTextureManager;
|
|
class FTerrainTypeArray;
|
|
|
|
class FTextureID
|
|
{
|
|
friend class FTextureManager;
|
|
friend FArchive &operator<< (FArchive &arc, FTextureID &tex);
|
|
friend FTextureID GetHUDIcon(const PClass *cls);
|
|
friend void R_InitSpriteDefs ();
|
|
|
|
public:
|
|
FTextureID() throw() {}
|
|
bool isNull() const { return texnum == 0; }
|
|
bool isValid() const { return texnum > 0; }
|
|
bool Exists() const { return texnum >= 0; }
|
|
void SetInvalid() { texnum = -1; }
|
|
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!
|
|
|
|
// 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;
|
|
};
|
|
|
|
class FNullTextureID : public FTextureID
|
|
{
|
|
public:
|
|
FNullTextureID() : FTextureID(0) {}
|
|
};
|
|
|
|
FArchive &operator<< (FArchive &arc, FTextureID &tex);
|
|
|
|
|
|
// Patches.
|
|
// A patch holds one or more columns.
|
|
// Patches are used for sprites and all masked pictures, and we compose
|
|
// textures from the TEXTURE1/2 lists of patches.
|
|
struct patch_t
|
|
{
|
|
SWORD width; // bounding box size
|
|
SWORD height;
|
|
SWORD leftoffset; // pixels to the left of origin
|
|
SWORD topoffset; // pixels below the origin
|
|
DWORD columnofs[8]; // only [width] used
|
|
// the [0] is &columnofs[width]
|
|
};
|
|
|
|
class FileReader;
|
|
|
|
// 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
|
|
{
|
|
TEX_Pal,
|
|
TEX_Gray,
|
|
TEX_RGB, // Actually ARGB
|
|
TEX_DXT1,
|
|
TEX_DXT2,
|
|
TEX_DXT3,
|
|
TEX_DXT4,
|
|
TEX_DXT5,
|
|
};
|
|
|
|
class FNativeTexture;
|
|
|
|
// Base texture class
|
|
class FTexture
|
|
{
|
|
public:
|
|
static FTexture *CreateTexture(int lumpnum, int usetype);
|
|
virtual ~FTexture ();
|
|
|
|
SWORD LeftOffset, TopOffset;
|
|
|
|
BYTE WidthBits, HeightBits;
|
|
|
|
fixed_t xScale;
|
|
fixed_t yScale;
|
|
|
|
char Name[9];
|
|
BYTE UseType; // This texture's primary purpose
|
|
|
|
BYTE bNoDecals:1; // Decals should not stick to texture
|
|
BYTE bNoRemap0:1; // Do not remap color 0 (used by front layer of parallax skies)
|
|
BYTE bWorldPanning:1; // Texture is panned in world units rather than texels
|
|
BYTE bMasked:1; // Texture (might) have holes
|
|
BYTE bAlphaTexture:1; // Texture is an alpha channel without color information
|
|
BYTE bHasCanvas:1; // Texture is based off FCanvasTexture
|
|
BYTE bWarped:2; // This is a warped texture. Used to avoid multiple warps on one texture
|
|
BYTE bComplex:1; // Will be used to mark extended MultipatchTextures that have to be
|
|
// fully composited before subjected to any kinf of postprocessing instead of
|
|
// doing it per patch.
|
|
|
|
WORD Rotations;
|
|
|
|
enum // UseTypes
|
|
{
|
|
TEX_Any,
|
|
TEX_Wall,
|
|
TEX_Flat,
|
|
TEX_Sprite,
|
|
TEX_WallPatch,
|
|
TEX_Build,
|
|
TEX_SkinSprite,
|
|
TEX_Decal,
|
|
TEX_MiscPatch,
|
|
TEX_FontChar,
|
|
TEX_Override, // For patches between TX_START/TX_END
|
|
TEX_Autopage, // Automap background - used to enable the use of FAutomapTexture
|
|
TEX_Null,
|
|
TEX_FirstDefined,
|
|
};
|
|
|
|
struct Span
|
|
{
|
|
WORD TopOffset;
|
|
WORD Length; // A length of 0 terminates this column
|
|
};
|
|
|
|
// Returns a single column of the texture
|
|
virtual const BYTE *GetColumn (unsigned int column, const Span **spans_out) = 0;
|
|
|
|
// Returns the whole texture, stored in column-major order
|
|
virtual const BYTE *GetPixels () = 0;
|
|
|
|
virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL);
|
|
int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, FRemapTable *remap, FCopyInfo *inf = NULL);
|
|
virtual bool UseBasePalette();
|
|
virtual int GetSourceLump() { return -1; }
|
|
virtual FTexture *GetRedirect(bool wantwarped);
|
|
|
|
virtual void Unload () = 0;
|
|
|
|
// Returns the native pixel format for this image
|
|
virtual FTextureFormat GetFormat();
|
|
|
|
// Returns a native 3D representation of the texture
|
|
FNativeTexture *GetNative(bool wrapping);
|
|
|
|
// Frees the native 3D representation of the texture
|
|
void KillNative();
|
|
|
|
// Fill the native texture buffer with pixel data for this image
|
|
virtual void FillBuffer(BYTE *buff, int pitch, int height, FTextureFormat fmt);
|
|
|
|
int GetWidth () { return Width; }
|
|
int GetHeight () { return Height; }
|
|
|
|
int GetScaledWidth () { int foo = (Width << 17) / xScale; return (foo >> 1) + (foo & 1); }
|
|
int GetScaledHeight () { int foo = (Height << 17) / yScale; return (foo >> 1) + (foo & 1); }
|
|
|
|
int GetScaledLeftOffset () { int foo = (LeftOffset << 17) / xScale; return (foo >> 1) + (foo & 1); }
|
|
int GetScaledTopOffset () { int foo = (TopOffset << 17) / yScale; return (foo >> 1) + (foo & 1); }
|
|
|
|
virtual void SetFrontSkyLayer();
|
|
|
|
void CopyToBlock (BYTE *dest, int dwidth, int dheight, int x, int y, const BYTE *translation=NULL)
|
|
{
|
|
CopyToBlock(dest, dwidth, dheight, x, y, 0, translation);
|
|
}
|
|
|
|
void CopyToBlock (BYTE *dest, int dwidth, int dheight, int x, int y, int rotate, const BYTE *translation=NULL);
|
|
|
|
// Returns true if the next call to GetPixels() will return an image different from the
|
|
// last call to GetPixels(). This should be considered valid only if a call to CheckModified()
|
|
// is immediately followed by a call to GetPixels().
|
|
virtual bool CheckModified ();
|
|
|
|
static void InitGrayMap();
|
|
|
|
void CopySize(FTexture *BaseTexture)
|
|
{
|
|
Width = BaseTexture->GetWidth();
|
|
Height = BaseTexture->GetHeight();
|
|
TopOffset = BaseTexture->TopOffset;
|
|
LeftOffset = BaseTexture->LeftOffset;
|
|
WidthBits = BaseTexture->WidthBits;
|
|
HeightBits = BaseTexture->HeightBits;
|
|
xScale = BaseTexture->xScale;
|
|
yScale = BaseTexture->yScale;
|
|
WidthMask = (1 << WidthBits) - 1;
|
|
}
|
|
|
|
void SetScaledSize(int fitwidth, int fitheight)
|
|
{
|
|
xScale = DivScale16(Width, fitwidth);
|
|
yScale = DivScale16(Height,fitheight);
|
|
// compensate for roundoff errors
|
|
if (MulScale16(xScale, fitwidth) != Width) xScale++;
|
|
if (MulScale16(yScale, fitheight) != Height) yScale++;
|
|
}
|
|
|
|
virtual void HackHack (int newheight); // called by FMultipatchTexture to discover corrupt patches.
|
|
|
|
protected:
|
|
WORD Width, Height, WidthMask;
|
|
static BYTE GrayMap[256];
|
|
FNativeTexture *Native;
|
|
|
|
FTexture ();
|
|
|
|
Span **CreateSpans (const BYTE *pixels) const;
|
|
void FreeSpans (Span **spans) const;
|
|
void CalcBitSize ();
|
|
|
|
static void FlipSquareBlock (BYTE *block, int x, int y);
|
|
static void FlipSquareBlockRemap (BYTE *block, int x, int y, const BYTE *remap);
|
|
static void FlipNonSquareBlock (BYTE *blockto, const BYTE *blockfrom, int x, int y, int srcpitch);
|
|
static void FlipNonSquareBlockRemap (BYTE *blockto, const BYTE *blockfrom, int x, int y, int srcpitch, const BYTE *remap);
|
|
|
|
friend class D3DTex;
|
|
};
|
|
|
|
|
|
// Texture manager
|
|
class FTextureManager
|
|
{
|
|
public:
|
|
FTextureManager ();
|
|
~FTextureManager ();
|
|
|
|
// Get texture without translation
|
|
FTexture *operator[] (FTextureID texnum)
|
|
{
|
|
if ((unsigned)texnum.GetIndex() >= Textures.Size()) return NULL;
|
|
return Textures[texnum.GetIndex()].Texture;
|
|
}
|
|
FTexture *operator[] (const char *texname)
|
|
{
|
|
FTextureID texnum = GetTexture (texname, FTexture::TEX_MiscPatch);
|
|
if (!texnum.Exists()) return NULL;
|
|
return Textures[texnum.GetIndex()].Texture;
|
|
}
|
|
FTexture *ByIndex(int i)
|
|
{
|
|
if (unsigned(i) >= Textures.Size()) return NULL;
|
|
return Textures[i].Texture;
|
|
}
|
|
FTexture *FindTexture(const char *texname, int usetype = FTexture::TEX_MiscPatch, BITFIELD flags = TEXMAN_TryAny);
|
|
|
|
// Get texture with translation
|
|
FTexture *operator() (FTextureID texnum)
|
|
{
|
|
if ((size_t)texnum.texnum >= Textures.Size()) return NULL;
|
|
return Textures[Translation[texnum.texnum]].Texture;
|
|
}
|
|
FTexture *operator() (const char *texname)
|
|
{
|
|
FTextureID texnum = GetTexture (texname, FTexture::TEX_MiscPatch);
|
|
if (texnum.texnum==-1) return NULL;
|
|
return Textures[Translation[texnum.texnum]].Texture;
|
|
}
|
|
|
|
void 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;
|
|
}
|
|
}
|
|
|
|
enum
|
|
{
|
|
TEXMAN_TryAny = 1,
|
|
TEXMAN_Overridable = 2,
|
|
TEXMAN_ReturnFirst = 4,
|
|
};
|
|
|
|
FTextureID CheckForTexture (const char *name, int usetype, BITFIELD flags=TEXMAN_TryAny);
|
|
FTextureID GetTexture (const char *name, int usetype, BITFIELD flags=0);
|
|
int ListTextures (const char *name, TArray<FTextureID> &list);
|
|
|
|
void AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup=0, bool texture1=false);
|
|
void AddTexturesLumps (int lump1, int lump2, int patcheslump);
|
|
void AddGroup(int wadnum, const char * startlump, const char * endlump, int ns, int usetype);
|
|
void AddPatches (int lumpnum);
|
|
void AddTiles (void *tileFile);
|
|
void AddHiresTextures (int wadnum);
|
|
void LoadTextureDefs(int wadnum, const char *lumpname);
|
|
void ParseXTexture(FScanner &sc, int usetype);
|
|
void SortTexturesByType(int start, int end);
|
|
|
|
FTextureID CreateTexture (int lumpnum, int usetype=FTexture::TEX_Any); // Also calls AddTexture
|
|
FTextureID AddTexture (FTexture *texture);
|
|
FTextureID AddPatch (const char *patchname, int namespc=0, bool tryany = false);
|
|
|
|
void LoadTextureX(int wadnum);
|
|
void AddTexturesForWad(int wadnum);
|
|
void Init();
|
|
|
|
// Replaces one texture with another. The new texture will be assigned
|
|
// the same name, slot, and use type as the texture it is replacing.
|
|
// The old texture will no longer be managed. Set free true if you want
|
|
// the old texture to be deleted or set it false if you want it to
|
|
// be left alone in memory. You will still need to delete it at some
|
|
// point, because the texture manager no longer knows about it.
|
|
// This function can be used for such things as warping textures.
|
|
void ReplaceTexture (FTextureID picnum, FTexture *newtexture, bool free);
|
|
|
|
void UnloadAll ();
|
|
|
|
int NumTextures () const { return (int)Textures.Size(); }
|
|
|
|
void WriteTexture (FArchive &arc, int picnum);
|
|
int ReadTexture (FArchive &arc);
|
|
|
|
|
|
private:
|
|
struct TextureHash
|
|
{
|
|
FTexture *Texture;
|
|
int HashNext;
|
|
};
|
|
enum { HASH_END = -1, HASH_SIZE = 1027 };
|
|
TArray<TextureHash> Textures;
|
|
TArray<int> Translation;
|
|
int HashFirst[HASH_SIZE];
|
|
FTextureID DefaultTexture;
|
|
};
|
|
|
|
extern FTextureManager TexMan;
|
|
|
|
#endif
|
|
|
|
|