gzdoom/src/textures/textures.h
Christoph Oelckers 3f2d5db348 - Changed: Textures without a name no longer get added to the texture manager's
hash chains.
- Fixed: specifying texture patches or font characters by full lump name instead
  of texture name didn't work. To do this properly the texture manager needs
  an option to look for a texture by lump number so that such textures can
  be maintained without interfering with regular operation.
- added 'skystretch' and 'autosequences' keywords for MAPINFO so that the effects
  of 'noautosequences' and 'forcenoskystretch' can be cancelled.
- Added a 'gamedefaults' section to MAPINFO after discovering that 'defaultmap'
  gets reset for each MAPINFO. A global section is needed to define a game's
  default setting in zdoom.pk3. The gamedefaults should normally not be changed 
  by PWADs but it can be done if some mod intends to change gameplay settings 
  but wants to allow custom add-ons on its own.


SVN r1300 (trunk)
2008-11-30 12:49:27 +00:00

346 lines
11 KiB
C++

#ifndef __TEXTURES_H
#define __TEXTURES_H
#include "basictypes.h"
class FBitmap;
struct FRemapTable;
struct FCopyInfo;
class FScanner;
struct PClass;
// 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(const char *name, int lumpnum, int usetype);
static FTexture *CreateTexture(int lumpnum, int usetype);
virtual ~FTexture ();
SWORD LeftOffset, TopOffset;
BYTE WidthBits, HeightBits;
fixed_t xScale;
fixed_t yScale;
int SourceLump;
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 SourceLump; }
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);
virtual void HackHack (int newheight); // called by FMultipatchTexture to discover corrupt patches.
protected:
WORD Width, Height, WidthMask;
static BYTE GrayMap[256];
FNativeTexture *Native;
FTexture (const char *name = NULL, int lumpnum = -1);
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);
FTextureID FindTextureByLumpNum (int lumpnum);
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);
void RemoveTexture();
FTextureID CreateTexture (int lumpnum, int usetype=FTexture::TEX_Any); // Also calls AddTexture
FTextureID AddTexture (FTexture *texture);
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