- split up textures.h.

This commit is contained in:
Christoph Oelckers 2020-05-24 07:58:56 +02:00
parent da26d1cec4
commit 498b19873d
10 changed files with 356 additions and 368 deletions

View file

@ -28,7 +28,7 @@ static_assert('\xff' == 255, "Char must be unsigned!");
#include "pragmas.h" #include "pragmas.h"
#include "textures.h" #include "buildtiles.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "cmdlib.h" #include "cmdlib.h"

View file

@ -13,7 +13,7 @@
#include "common.h" #include "common.h"
#include "mdsprite.h" // md3model_t #include "mdsprite.h" // md3model_t
#include "textures.h" #include "buildtiles.h"
#include "bitmap.h" #include "bitmap.h"
#include "m_argv.h" #include "m_argv.h"
#include "gamecontrol.h" #include "gamecontrol.h"

View file

@ -11,7 +11,7 @@ Ken Silverman's official web site: http://www.advsys.net/ken
#include "mdsprite.h" #include "mdsprite.h"
#include "polymost.h" #include "polymost.h"
#include "files.h" #include "files.h"
#include "textures.h" #include "buildtiles.h"
#include "bitmap.h" #include "bitmap.h"
#include "../../glbackend/glbackend.h" #include "../../glbackend/glbackend.h"
#include "c_cvars.h" #include "c_cvars.h"

View file

@ -41,6 +41,7 @@
#include "v_draw.h" #include "v_draw.h"
#include "glbackend/glbackend.h" #include "glbackend/glbackend.h"
#include "palettecontainer.h" #include "palettecontainer.h"
#include "buildtiles.h"
#include "fontinternals.h" #include "fontinternals.h"
@ -116,8 +117,6 @@ FHexFontChar::FHexFontChar (uint8_t *sourcedata, int swidth, int width, int heig
SourceWidth = swidth; SourceWidth = swidth;
Size.x = width; Size.x = width;
Size.y = height; Size.y = height;
PicAnim.xofs = 0;
PicAnim.yofs = 0;
} }
//========================================================================== //==========================================================================

View file

@ -42,6 +42,7 @@
#include "imagehelpers.h" #include "imagehelpers.h"
#include "filesystem.h" #include "filesystem.h"
#include "colormatcher.h" #include "colormatcher.h"
#include "buildtiles.h"
#include "fontinternals.h" #include "fontinternals.h"

View file

@ -48,6 +48,7 @@
#include "optionmenuitems.h" #include "optionmenuitems.h"
#include "i_soundfont.h" #include "i_soundfont.h"
#include "zstring.h" #include "zstring.h"
#include "buildtiles.h"
#include <zmusic.h> #include <zmusic.h>
// Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded. // Menu-relevant content that gets filled in by scripts. This will get processed after the game has loaded.

View file

@ -35,7 +35,7 @@
#include "files.h" #include "files.h"
#include "zstring.h" #include "zstring.h"
#include "textures.h" #include "buildtiles.h"
#include "image.h" #include "image.h"
#include "baselayer.h" #include "baselayer.h"
@ -43,6 +43,7 @@
#include "m_crc32.h" #include "m_crc32.h"
#include "build.h" #include "build.h"
#include "gamecontrol.h" #include "gamecontrol.h"
#include "palettecontainer.h"
enum enum
{ {
@ -85,6 +86,7 @@ FBitmap FTileTexture::GetBgraBitmap(const PalEntry* remap, int* ptrans)
TArray<uint8_t> buffer; TArray<uint8_t> buffer;
bmp.Create(Size.x, Size.y); bmp.Create(Size.x, Size.y);
const uint8_t* ppix = Get8BitPixels(); const uint8_t* ppix = Get8BitPixels();
if (!remap) remap = GPalette.BaseColors; // no remap was passed but this code needs a color table, so use the base.
if (!ppix) if (!ppix)
{ {
// This is needed for tiles with a palette remap. // This is needed for tiles with a palette remap.

View file

@ -0,0 +1,346 @@
#pragma once
#include "textures.h"
class FTileTexture : public FTexture
{
public:
FTileTexture()
{
useType = Art;
}
void SetName(const char* name) { Name = name; }
FBitmap GetBgraBitmap(const PalEntry* remap, int* ptrans) override;
void Create8BitPixels(uint8_t* buffer) override;
};
//==========================================================================
//
// A tile coming from an ART file.
//
//==========================================================================
class FArtTile : public FTileTexture
{
const TArray<uint8_t>& RawPixels;
const uint32_t Offset;
public:
FArtTile(const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height, int picanm)
: RawPixels(backingstore), Offset(offset)
{
SetSize(width, height);
PicAnim = tileConvertAnimFormat(picanm);
}
const uint8_t* Get8BitPixels() override
{
return RawPixels.Data() ? RawPixels.Data() + Offset : nullptr;
}
};
//==========================================================================
//
// A tile with its own pixel buffer
//
//==========================================================================
class FLooseTile : public FTileTexture
{
TArray<uint8_t> RawPixels;
public:
FLooseTile(TArray<uint8_t> &store, int width, int height)
{
useType = Art; // Whatever this was before - now it's a tile!
RawPixels = std::move(store);
SetSize(width, height);
}
const uint8_t* Get8BitPixels() override
{
return RawPixels.Data();
}
};
//==========================================================================
//
// A non-existent tile
//
//==========================================================================
class FDummyTile : public FTileTexture
{
public:
FDummyTile(int width, int height)
{
useType = Art;
SetSize(width, height);
}
const uint8_t* Get8BitPixels() override
{
return NULL;
}
};
//==========================================================================
//
// A tile with a writable surface
//
//==========================================================================
class FWritableTile : public FTileTexture
{
protected:
TArray<uint8_t> buffer;
public:
FWritableTile()
{
useType = Writable;
}
const uint8_t* Get8BitPixels() override
{
return buffer.Data();
}
uint8_t* GetWritableBuffer() override
{
// Todo: Invalidate all hardware textures depending on this.
return buffer.Data();
}
bool Resize(int w, int h)
{
if (w <= 0 || h <= 0)
{
buffer.Reset();
return false;
}
else
{
SetSize(w, h);
buffer.Resize(w * h);
return true;
}
}
};
//==========================================================================
//
// A tile with a writable surface
//
//==========================================================================
class FRestorableTile : public FWritableTile
{
FTexture* Base;
public:
FRestorableTile(FTexture* base)
{
useType = Restorable;
Base = base;
CopySize(base);
Resize(GetWidth(), GetHeight());
Reload();
}
void Reload() override
{
Base->Create8BitPixels(buffer.Data());
}
};
//==========================================================================
//
// One ART file.
//
//==========================================================================
struct BuildArtFile
{
FString filename;
TArray<uint8_t> RawData;
BuildArtFile() = default;
BuildArtFile(const BuildArtFile&) = delete;
BuildArtFile& operator=(const BuildArtFile&) = delete;
BuildArtFile(const BuildArtFile&& other)
{
filename = std::move(other.filename);
RawData = std::move(other.RawData);
}
BuildArtFile& operator=(const BuildArtFile&& other)
{
filename = std::move(other.filename);
RawData = std::move(other.RawData);
return *this;
}
};
//==========================================================================
//
// THe tile container
//
//==========================================================================
struct BuildTiles
{
FTexture* Placeholder;
TDeletingArray<BuildArtFile*> ArtFiles;
TDeletingArray<BuildArtFile*> PerMapArtFiles;
TDeletingArray<FTexture*> AllTiles; // This is for deleting tiles when shutting down.
TDeletingArray<FTexture*> AllMapTiles; // Same for map tiles;
FTexture* tiles[MAXTILES];
FTexture* tilesbak[MAXTILES];
TMap<FString, FTexture*> textures;
TArray<FString> addedArt;
BuildTiles()
{
Placeholder = new FDummyTile(0, 0);
for (auto& tile : tiles) tile = Placeholder;
for (auto& tile : tilesbak) tile = Placeholder;
}
~BuildTiles()
{
CloseAll();
}
void CloseAll();
FTexture* GetTexture(const char* path);
void AddTile(int tilenum, FTexture* tex, bool permap = false);
void AddTiles(int firsttile, TArray<uint8_t>& store, bool permap);
void AddFile(BuildArtFile* bfd, bool permap)
{
if (!permap) ArtFiles.Push(bfd);
else PerMapArtFiles.Push(bfd);
}
int FindFile(const FString& filename)
{
return ArtFiles.FindEx([filename](const BuildArtFile* element) { return filename.CompareNoCase(element->filename) == 0; });
}
int LoadArtFile(const char* file, bool mapart = false, int firsttile = -1);
void CloseAllMapArt();
void LoadArtSet(const char* filename);
void AddArt(TArray<FString>& art)
{
addedArt = std::move(art);
}
FTexture* ValidateCustomTile(int tilenum, int type);
int32_t artLoadFiles(const char* filename);
uint8_t* tileMakeWritable(int num);
uint8_t* tileCreate(int tilenum, int width, int height);
void tileSetExternal(int tilenum, int width, int height, uint8_t* data);
int findUnusedTile(void);
int tileCreateRotated(int owner);
void ClearTextureCache(bool artonly = false);
void InvalidateTile(int num);
void MakeCanvas(int tilenum, int width, int height);
};
int tileGetCRC32(int tileNum);
int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istexture);
void tileCopy(int tile, int tempsource, int temppal, int xoffset, int yoffset, int flags);
void tileSetDummy(int tile, int width, int height);
void tileDelete(int tile);
void tileRemoveReplacement(int tile);
bool tileLoad(int tileNum);
void artClearMapArt(void);
void artSetupMapArt(const char* filename);
void tileSetAnim(int tile, const picanm_t& anm);
int tileSetHightileReplacement(int picnum, int palnum, const char *filen, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags);
int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags );
int tileDeleteReplacement(int picnum, int palnum);
void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int tilenum2, int sx2, int sy2);
extern BuildTiles TileFiles;
inline bool tileCheck(int num)
{
auto tex = TileFiles.tiles[num];
return tex->GetWidth() > 0 && tex->GetHeight() > 0;
}
inline const uint8_t* tilePtr(int num)
{
auto tex = TileFiles.tiles[num];
auto p = tex->Get8BitPixels();
if (p) return p;
return tex->CachedPixels.Data();
}
inline uint8_t* tileData(int num)
{
auto tex = TileFiles.tiles[num];
return tex->GetWritableBuffer();
}
// Some hacks to allow accessing the no longer existing arrays as if they still were arrays to avoid changing hundreds of lines of code.
struct TileSiz
{
const vec2_16_t &operator[](size_t index)
{
assert(index < MAXTILES);
return TileFiles.tiles[index]->GetSize();
}
};
extern TileSiz tilesiz;
struct PicAnm
{
picanm_t& operator[](size_t index)
{
assert(index < MAXTILES);
return TileFiles.tiles[index]->GetAnim();
}
};
extern PicAnm picanm;
// Helpers to read the refactored tilesiz array.
inline int tileWidth(int num)
{
return tilesiz[num].x;
}
inline int tileHeight(int num)
{
return tilesiz[num].y;
}
inline int widthBits(int num)
{
int w = tileWidth(num);
int j = 15;
while ((j > 1) && ((1 << j) > w))
j--;
return j;
}
inline int heightBits(int num)
{
int w = tileHeight(num);
int j = 15;
while ((j > 1) && ((1 << j) > w))
j--;
return j;
}
inline rottile_t& RotTile(int tile)
{
assert(tile < MAXTILES);
return TileFiles.tiles[tile]->GetRotTile();
}
inline void tileInvalidate(int16_t tilenume, int32_t, int32_t)
{
TileFiles.InvalidateTile(tilenume);
}

View file

@ -231,7 +231,6 @@ public:
int GetDisplayWidth() const { return Size.x; } int GetDisplayWidth() const { return Size.x; }
int GetDisplayHeight() const { return Size.y; } int GetDisplayHeight() const { return Size.y; }
const vec2_16_t &GetSize() const { return Size; } const vec2_16_t &GetSize() const { return Size; }
const uint8_t& GetPicSize() const { return PicSize; }
int GetLeftOffset() const { return PicAnim.xofs; } int GetLeftOffset() const { return PicAnim.xofs; }
int GetTopOffset() const { return PicAnim.yofs; } int GetTopOffset() const { return PicAnim.yofs; }
picanm_t& GetAnim() { return PicAnim; } // This must be modifiable. There's quite a bit of code messing around with the flags in here. picanm_t& GetAnim() { return PicAnim; } // This must be modifiable. There's quite a bit of code messing around with the flags in here.
@ -273,30 +272,13 @@ protected:
Size.y = BaseTexture->GetHeight(); Size.y = BaseTexture->GetHeight();
PicAnim.xofs = BaseTexture->PicAnim.xofs; PicAnim.xofs = BaseTexture->PicAnim.xofs;
PicAnim.yofs = BaseTexture->PicAnim.yofs; PicAnim.yofs = BaseTexture->PicAnim.yofs;
UpdatePicSize();
} }
void SetSize(int w, int h) void SetSize(int w, int h)
{ {
Size = { int16_t(w), int16_t(h) }; Size = { int16_t(w), int16_t(h) };
UpdatePicSize();
} }
void UpdatePicSize()
{
int j = 15;
while ((j > 1) && ((1 << j) > Size.x))
j--;
PicSize = j;
j = 15;
while ((j > 1) && ((1 << j) > Size.y))
j--;
PicSize |= j << 4;
}
FString Name; FString Name;
union union
{ {
@ -307,7 +289,6 @@ protected:
uint8_t bMasked = true; // Texture (might) have holes uint8_t bMasked = true; // Texture (might) have holes
int8_t bTranslucent = -1; // Does this texture have an active alpha channel? int8_t bTranslucent = -1; // Does this texture have an active alpha channel?
bool skyColorDone = false; bool skyColorDone = false;
uint8_t PicSize = 0; // A special piece of Build weirdness.
UseType useType = Image; UseType useType = Image;
PalEntry FloorSkyColor; PalEntry FloorSkyColor;
PalEntry CeilingSkyColor; PalEntry CeilingSkyColor;
@ -347,348 +328,6 @@ public:
friend struct FCanvasTextureInfo; friend struct FCanvasTextureInfo;
}; };
class FTileTexture : public FTexture
{
public:
FTileTexture()
{
useType = Art;
}
void SetName(const char* name) { Name = name; }
FBitmap GetBgraBitmap(const PalEntry* remap, int* ptrans) override;
void Create8BitPixels(uint8_t* buffer) override;
};
//==========================================================================
//
// A tile coming from an ART file.
//
//==========================================================================
class FArtTile : public FTileTexture
{
const TArray<uint8_t>& RawPixels;
const uint32_t Offset;
public:
FArtTile(const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height, int picanm)
: RawPixels(backingstore), Offset(offset)
{
SetSize(width, height);
PicAnim = tileConvertAnimFormat(picanm);
}
const uint8_t* Get8BitPixels() override
{
return RawPixels.Data() ? RawPixels.Data() + Offset : nullptr;
}
};
//==========================================================================
//
// A tile with its own pixel buffer
//
//==========================================================================
class FLooseTile : public FTileTexture
{
TArray<uint8_t> RawPixels;
public:
FLooseTile(TArray<uint8_t> &store, int width, int height)
{
useType = Art; // Whatever this was before - now it's a tile!
RawPixels = std::move(store);
SetSize(width, height);
}
const uint8_t* Get8BitPixels() override
{
return RawPixels.Data();
}
};
//==========================================================================
//
// A non-existent tile
//
//==========================================================================
class FDummyTile : public FTileTexture
{
public:
FDummyTile(int width, int height)
{
useType = Art;
SetSize(width, height);
}
const uint8_t* Get8BitPixels() override
{
return NULL;
}
};
//==========================================================================
//
// A tile with a writable surface
//
//==========================================================================
class FWritableTile : public FTileTexture
{
protected:
TArray<uint8_t> buffer;
public:
FWritableTile()
{
useType = Writable;
}
const uint8_t* Get8BitPixels() override
{
return buffer.Data();
}
uint8_t* GetWritableBuffer() override
{
// Todo: Invalidate all hardware textures depending on this.
return buffer.Data();
}
bool Resize(int w, int h)
{
if (w <= 0 || h <= 0)
{
buffer.Reset();
return false;
}
else
{
SetSize(w, h);
buffer.Resize(w * h);
return true;
}
}
};
//==========================================================================
//
// A tile with a writable surface
//
//==========================================================================
class FRestorableTile : public FWritableTile
{
FTexture* Base;
public:
FRestorableTile(FTexture* base)
{
useType = Restorable;
Base = base;
CopySize(base);
Resize(GetWidth(), GetHeight());
Reload();
}
void Reload() override
{
Base->Create8BitPixels(buffer.Data());
}
};
//==========================================================================
//
// One ART file.
//
//==========================================================================
struct BuildArtFile
{
FString filename;
TArray<uint8_t> RawData;
BuildArtFile() = default;
BuildArtFile(const BuildArtFile&) = delete;
BuildArtFile& operator=(const BuildArtFile&) = delete;
BuildArtFile(const BuildArtFile&& other)
{
filename = std::move(other.filename);
RawData = std::move(other.RawData);
}
BuildArtFile& operator=(const BuildArtFile&& other)
{
filename = std::move(other.filename);
RawData = std::move(other.RawData);
return *this;
}
};
//==========================================================================
//
// THe tile container
//
//==========================================================================
struct BuildTiles
{
FTexture* Placeholder;
TDeletingArray<BuildArtFile*> ArtFiles;
TDeletingArray<BuildArtFile*> PerMapArtFiles;
TDeletingArray<FTexture*> AllTiles; // This is for deleting tiles when shutting down.
TDeletingArray<FTexture*> AllMapTiles; // Same for map tiles;
FTexture* tiles[MAXTILES];
FTexture* tilesbak[MAXTILES];
TMap<FString, FTexture*> textures;
TArray<FString> addedArt;
BuildTiles()
{
Placeholder = new FDummyTile(0, 0);
for (auto& tile : tiles) tile = Placeholder;
for (auto& tile : tilesbak) tile = Placeholder;
}
~BuildTiles()
{
CloseAll();
}
void CloseAll();
FTexture* GetTexture(const char* path);
void AddTile(int tilenum, FTexture* tex, bool permap = false);
void AddTiles(int firsttile, TArray<uint8_t>& store, bool permap);
void AddFile(BuildArtFile* bfd, bool permap)
{
if (!permap) ArtFiles.Push(bfd);
else PerMapArtFiles.Push(bfd);
}
int FindFile(const FString& filename)
{
return ArtFiles.FindEx([filename](const BuildArtFile* element) { return filename.CompareNoCase(element->filename) == 0; });
}
int LoadArtFile(const char* file, bool mapart = false, int firsttile = -1);
void CloseAllMapArt();
void LoadArtSet(const char* filename);
void AddArt(TArray<FString>& art)
{
addedArt = std::move(art);
}
FTexture* ValidateCustomTile(int tilenum, int type);
int32_t artLoadFiles(const char* filename);
uint8_t* tileMakeWritable(int num);
uint8_t* tileCreate(int tilenum, int width, int height);
void tileSetExternal(int tilenum, int width, int height, uint8_t* data);
int findUnusedTile(void);
int tileCreateRotated(int owner);
void ClearTextureCache(bool artonly = false);
void InvalidateTile(int num);
void MakeCanvas(int tilenum, int width, int height);
};
int tileGetCRC32(int tileNum);
int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istexture);
void tileCopy(int tile, int tempsource, int temppal, int xoffset, int yoffset, int flags);
void tileSetDummy(int tile, int width, int height);
void tileDelete(int tile);
void tileRemoveReplacement(int tile);
bool tileLoad(int tileNum);
void artClearMapArt(void);
void artSetupMapArt(const char* filename);
void tileSetAnim(int tile, const picanm_t& anm);
int tileSetHightileReplacement(int picnum, int palnum, const char *filen, float alphacut, float xscale, float yscale, float specpower, float specfactor, uint8_t flags);
int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags );
int tileDeleteReplacement(int picnum, int palnum);
void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int tilenum2, int sx2, int sy2);
extern BuildTiles TileFiles;
inline bool tileCheck(int num)
{
auto tex = TileFiles.tiles[num];
return tex->GetWidth() > 0 && tex->GetHeight() > 0;
}
inline const uint8_t* tilePtr(int num)
{
auto tex = TileFiles.tiles[num];
auto p = tex->Get8BitPixels();
if (p) return p;
return tex->CachedPixels.Data();
}
inline uint8_t* tileData(int num)
{
auto tex = TileFiles.tiles[num];
return tex->GetWritableBuffer();
}
// Some hacks to allow accessing the no longer existing arrays as if they still were arrays to avoid changing hundreds of lines of code.
struct TileSiz
{
const vec2_16_t &operator[](size_t index)
{
assert(index < MAXTILES);
return TileFiles.tiles[index]->GetSize();
}
};
extern TileSiz tilesiz;
struct PicAnm
{
picanm_t& operator[](size_t index)
{
assert(index < MAXTILES);
return TileFiles.tiles[index]->GetAnim();
}
};
extern PicAnm picanm;
// Helpers to read the refactored tilesiz array.
inline int tileWidth(int num)
{
return tilesiz[num].x;
}
inline int tileHeight(int num)
{
return tilesiz[num].y;
}
inline int widthBits(int num)
{
int w = tileWidth(num);
int j = 15;
while ((j > 1) && ((1 << j) > w))
j--;
return j;
}
inline int heightBits(int num)
{
int w = tileHeight(num);
int j = 15;
while ((j > 1) && ((1 << j) > w))
j--;
return j;
}
inline rottile_t& RotTile(int tile)
{
assert(tile < MAXTILES);
return TileFiles.tiles[tile]->GetRotTile();
}
inline void tileInvalidate(int16_t tilenume, int32_t, int32_t)
{
TileFiles.InvalidateTile(tilenume);
}
#endif #endif

View file

@ -44,7 +44,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "cd.h" #include "cd.h"
#include "map.h" #include "map.h"
#include "sound.h" #include "sound.h"
#include "textures.h" #include "buildtiles.h"
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>