From a6ba81939aecabf622ad687a6084f6334a7e8d98 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 12 Oct 2019 22:49:46 +0200 Subject: [PATCH] - reworked texture management, not yet active. --- source/build/include/build.h | 33 +-- source/build/src/engine_priv.h | 2 +- source/build/src/tiles.cpp | 17 +- source/common/textures/buildtiles.cpp | 249 +++++++------------ source/common/textures/imagetexture.cpp | 4 +- source/common/textures/texture.cpp | 61 ----- source/common/textures/textures.h | 307 ++++++++++++++++++++++-- source/sw/src/game.cpp | 40 --- 8 files changed, 379 insertions(+), 334 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index bdad4d241..e0d821178 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -27,6 +27,7 @@ #include "vfs.h" #include "cache1d.h" +#include "textures.h" enum rendmode_t { REND_CLASSIC, @@ -814,38 +815,7 @@ static CONSTEXPR const int32_t pow2long[32] = 268435456, 536870912, 1073741824, 2147483647 }; -// picanm[].sf: -// |bit(1<<7) -// |animtype|animtype|texhitscan|nofullbright|speed|speed|speed|speed| -enum { - PICANM_ANIMTYPE_NONE = 0, - PICANM_ANIMTYPE_OSC = (1<<6), - PICANM_ANIMTYPE_FWD = (2<<6), - PICANM_ANIMTYPE_BACK = (3<<6), - - PICANM_ANIMTYPE_SHIFT = 6, - PICANM_ANIMTYPE_MASK = (3<<6), // must be 192 - PICANM_MISC_MASK = (3<<4), - PICANM_TEXHITSCAN_BIT = (2<<4), - PICANM_NOFULLBRIGHT_BIT = (1<<4), - PICANM_ANIMSPEED_MASK = 15, // must be 15 -}; - -// NOTE: If the layout of this struct is changed, loadpics() must be modified -// accordingly. -typedef struct { - uint8_t num; // animate number - int8_t xofs, yofs; - uint8_t sf; // anim. speed and flags - uint8_t extra; - - void Clear() - { - extra = sf = yofs = xofs = num = 0; - } -} picanm_t; EXTERN picanm_t picanm[MAXTILES]; -typedef struct { int16_t newtile; int16_t owner; } rottile_t; EXTERN rottile_t rottile[MAXTILES]; EXTERN int32_t windowpos, windowx, windowy; @@ -1079,7 +1049,6 @@ void tileSetSize(int32_t picnum, int16_t dasizx, int16_t dasizy); int32_t artReadHeader(buildvfs_kfd fil, char const *fn, artheader_t *local); int32_t artReadHeaderFromBuffer(uint8_t const *buf, artheader_t *local); int32_t artCheckUnitFileHeader(uint8_t const *buf, int32_t length); -void tileConvertAnimFormat(int32_t const picnum, int32_t const picanmdisk); void artReadManifest(buildvfs_kfd fil, artheader_t const *local); void artPreloadFile(buildvfs_kfd fil, artheader_t const *local); int32_t artLoadFiles(const char *filename, int32_t askedsize); diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index 4db7c1e2d..ab798e3a7 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -28,7 +28,7 @@ extern int32_t globalx1, globaly2; -extern uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[4096+256], ATTRIBUTE((used)) sqrtable_old[2048]; +extern uint16_t sqrtable[4096], shlookup[4096+256],sqrtable_old[2048]; static inline int32_t nsqrtasm(uint32_t a) diff --git a/source/build/src/tiles.cpp b/source/build/src/tiles.cpp index 8946bc0ff..660900864 100644 --- a/source/build/src/tiles.cpp +++ b/source/build/src/tiles.cpp @@ -396,19 +396,6 @@ int32_t artCheckUnitFileHeader(uint8_t const * const buf, int32_t length) return 0; } -void tileConvertAnimFormat(int32_t const picnum, int32_t const picanmdisk) -{ - EDUKE32_STATIC_ASSERT(PICANM_ANIMTYPE_MASK == 192); - - // Unpack a 4 byte packed anim descriptor into the internal 5 byte format. - picanm_t* const thispicanm = &picanm[picnum]; - thispicanm->num = picanmdisk & 63; - thispicanm->xofs = (picanmdisk >> 8) & 255; - thispicanm->yofs = (picanmdisk >> 16) & 255; - thispicanm->sf = ((picanmdisk >> 24) & 15) | (picanmdisk & 192); - thispicanm->extra = (picanmdisk >> 28) & 15; -} - void artReadManifest(int32_t const fil, artheader_t const* const local) { int16_t* tilesizx = (int16_t*)Xmalloc(local->numtiles * sizeof(int16_t)); @@ -426,7 +413,7 @@ void artReadManifest(int32_t const fil, artheader_t const* const local) kread(fil, &picanmdisk, sizeof(int32_t)); picanmdisk = B_LITTLE32(picanmdisk); - tileConvertAnimFormat(i, picanmdisk); + picanm[i] = tileConvertAnimFormat(picanmdisk); } DO_FREE_AND_NULL(tilesizx); @@ -582,6 +569,8 @@ static int32_t artReadIndexedFile(int32_t tilefilei) // int32_t artLoadFiles(const char *filename, int32_t askedsize) { + TileFiles.LoadArtSet(filename); + Bstrncpyz(artfilenameformat, filename, sizeof(artfilenameformat)); Bmemset(&tilesizearray[0], 0, sizeof(vec2_16_t) * MAXTILES); diff --git a/source/common/textures/buildtiles.cpp b/source/common/textures/buildtiles.cpp index f37af634f..d9a0ccf0b 100644 --- a/source/common/textures/buildtiles.cpp +++ b/source/common/textures/buildtiles.cpp @@ -39,44 +39,63 @@ #include "image.h" #include "cache1d.h" -struct BuildTileDescriptor +enum { - int tilenum; - FTexture *Texture; + MAXARTFILES_BASE = 200, + MAXARTFILES_TOTAL = 220 }; -struct BuildFileDescriptor +picanm_t tileConvertAnimFormat(int32_t const picanmdisk) { - FString filename; - TArray RawData; - TArray Textures; - bool MapArt; - bool Active; + // Unpack a 4 byte packed anim descriptor into the internal 5 byte format. + picanm_t anm; + anm.num = picanmdisk & 63; + anm.xofs = (picanmdisk >> 8) & 255; + anm.yofs = (picanmdisk >> 16) & 255; + anm.sf = ((picanmdisk >> 24) & 15) | (picanmdisk & 192); + anm.extra = (picanmdisk >> 28) & 15; + return anm; +} - void AddTiles(); -}; -struct BuildFiles +//========================================================================== +// +// Base class for Build tile textures +// This needs a few subclasses for different use cases. +// +//========================================================================== + +FBitmap FTileTexture::GetBgraBitmap(PalEntry* remap, int* ptrans) { - TArray FileDescriptors; - void AddFile(BuildFileDescriptor &bfd) + FBitmap bmp; + bmp.Create(Size.x, Size.y); + const uint8_t* ppix = Get8BitPixels(); // any properly implemented tile MUST return something valid here. + if (ppix) bmp.CopyPixelData(0, 0, ppix, Size.x, Size.y, Size.y, 1, 0, remap); + return bmp; +} + +void FTileTexture::Create8BitPixels(uint8_t* buffer) +{ + auto pix = Get8BitPixels(); + if (pix) memcpy(buffer, pix, Size.x * Size.y); +} + + +//========================================================================== +// +// Tile textures are owned by their containing file object. +// +//========================================================================== + +FTexture* GetTileTexture(const char* name, const TArray& backingstore, uint32_t offset, int width, int height, int picanm) +{ + auto tex = new FArtTile(backingstore, offset, width, height, picanm); + if (tex) { - FileDescriptors.Push(std::move(bfd)); + tex->SetName(name); } - BuildFileDescriptor *FindFile(const FString &filename) - { - auto ndx = FileDescriptors.FindEx([filename](const BuildFileDescriptor & element) { return filename.CompareNoCase(element.filename) == 0; }); - if (ndx < FileDescriptors.Size()) return &FileDescriptors[ndx]; - return nullptr; - } - void LoadArtFile(const char *file, bool mapart); - void CloseAllMapArt(); - int LoadIndexedFile(const char* base, int index); - void LoadArtSet(const char* filename); - -}; - -static BuildFiles alltilefiles; + return tex; +} //=========================================================================== // @@ -86,7 +105,7 @@ static BuildFiles alltilefiles; // //=========================================================================== -void BuildFileDescriptor::AddTiles () +void BuildArtFile::AddTiles () { const uint8_t *tiles = RawData.Data(); @@ -104,17 +123,15 @@ void BuildFileDescriptor::AddTiles () int width = LittleShort(tilesizx[pic]); int height = LittleShort(tilesizy[pic]); uint32_t anm = LittleLong(picanm[pic]); - int xoffs = (int8_t)((anm >> 8) & 255) + width/2; - int yoffs = (int8_t)((anm >> 16) & 255) + height/2; int size = width*height; if (width <= 0 || height <= 0) continue; // This name is mainly for debugging so that there is something more to go by than the mere index. FStringf name("TILE_%s_%05d_%08x_%04x_%04x", filename, uint32_t(tiledata - tiles), width, height); - auto tex = FTexture::GetTileTexture(name, RawData, uint32_t(tiledata - tiles), width, height, xoffs, yoffs); - BuildTileDescriptor desc; - //Textures.Push(); + auto tex = GetTileTexture(name, RawData, uint32_t(tiledata - tiles), width, height, anm); + BuildTileDescriptor desc = { i, tex }; + Textures.Push(desc); tiledata += size; } } @@ -151,14 +168,7 @@ int CountTiles (const void *RawData) void BuildFiles::CloseAllMapArt() { - for (auto& fd : FileDescriptors) - { - if (fd.MapArt) - { - fd.Active = false; - fd.RawData.Reset(); - } - } + PerMapArtFiles.Clear(); } //=========================================================================== @@ -177,7 +187,7 @@ void BuildFiles::CloseAllMapArt() void BuildFiles::LoadArtFile(const char *fn, bool mapart) { auto old = FindFile(fn); - if (old) + if (old >= ArtFiles.Size()) // Do not process if already loaded. { FileReader fr = kopenFileReader(fn, 0); if (fr.isOpen()) @@ -190,136 +200,49 @@ void BuildFiles::LoadArtFile(const char *fn, bool mapart) // Only load the data if the header is present if (CountTiles(artptr) > 0) { - FileDescriptors.Reserve(1); - auto &fd = FileDescriptors.Last(); + auto& descs = mapart ? PerMapArtFiles : ArtFiles; + descs.Reserve(1); + auto& fd = descs.Last(); fd.filename = fn; - fd.MapArt = mapart; - fd.Active = true; fd.RawData = std::move(artdata); fd.AddTiles(); } } } } -} - -#if 0 - -//=========================================================================== -// -// Returns: -// 0: successfully read ART file -// >0: error with the ART file -// -1: ART file does not exist -//<-1: per-map ART issue -// -//=========================================================================== - -int BuildFiles::LoadIndexedFile(const char *base, int index) -{ - FStringf name(base, index); - - const char* fn = artGetIndexedFileName(tilefilei); - const int32_t permap = (tilefilei >= MAXARTFILES_BASE); // is it a per-map ART file? - buildvfs_kfd fil; - - if ((fil = kopen4loadfrommod(fn, 0)) != buildvfs_kfd_invalid) + else { - artheader_t local; - int const headerval = artReadHeader(fil, fn, &local); - if (headerval != 0) - { - kclose(fil); - return headerval; - } - - if (permap) - { - // Check whether we can evict existing tiles to make place for - // per-map ART ones. - for (int i = local.tilestart; i <= local.tileend; i++) - { - // Tiles having dummytile replacements or those that are - // cache1d-locked can't be replaced. - if (faketile[i >> 3] & pow2char[i & 7] || walock[i] >= 200) - { - initprintf("loadpics: per-map ART file \"%s\": " - "tile %d has dummytile or is locked\n", fn, i); - kclose(fil); - return -3; - } - } - - // Free existing tiles from the cache1d. CACHE1D_FREE - Bmemset(&tileptr[local.tilestart], 0, local.numtiles * sizeof(uint8_t*)); - Bmemset(&tiledata[local.tilestart], 0, local.numtiles * sizeof(uint8_t*)); - Bmemset(&walock[local.tilestart], 1, local.numtiles * sizeof(walock[0])); - } - - artReadManifest(fil, &local); - - if (cache1d_file_fromzip(fil)) - { - if (permap) - artPreloadFileSafe(fil, &local); - else - artPreloadFile(fil, &local); - } - else - { - int offscount = ktell(fil); - - for (bssize_t i = local.tilestart; i <= local.tileend; ++i) - { - int const dasiz = tilesiz[i].x * tilesiz[i].y; - - tilefilenum[i] = tilefilei; - tilefileoffs[i] = offscount; - - offscount += dasiz; - // artsize += ((dasiz+15)&0xfffffff0); - } - } - - kclose(fil); - return 0; + // Reuse the old one but move it to the top. + auto fd = std::move(ArtFiles[old]); + ArtFiles.Delete(old); + ArtFiles.Push(std::move(fd)); } - - return -1; } -// -// loadpics -// -int32_t BuildFiles::LoadArtSet(const char* filename) +static FString artGetIndexedFileName(const char *base, int32_t index) { - Bstrncpyz(artfilenameformat, filename, sizeof(artfilenameformat)); - - Bmemset(&tilesizearray[0], 0, sizeof(vec2_16_t) * MAXTILES); - Bmemset(picanm, 0, sizeof(picanm)); - - for (auto& rot : rottile) - rot = { -1, -1 }; - - // artsize = 0; - - for (int tilefilei = 0; tilefilei < MAXARTFILES_BASE; tilefilei++) - artReadIndexedFile(tilefilei); - - Bmemset(gotpic, 0, sizeof(gotpic)); - - //cachesize = min((int32_t)((Bgetsysmemsize()/100)*60),max(artsize,askedsize)); - cachesize = (Bgetsysmemsize() <= (uint32_t)askedsize) ? (int32_t)((Bgetsysmemsize() / 100) * 60) : askedsize; - pic = Xaligned_alloc(Bgetpagesize(), cachesize); - cacheInitBuffer((intptr_t)pic, cachesize); - - artUpdateManifest(); - - artfil = buildvfs_kfd_invalid; - artfilnum = -1; - artfilplc = 0L; - - return 0; + FString result; + if (index >= MAXARTFILES_BASE) + { + char XX[3] = { char('0' + (index / 10) % 10), char('0' + index % 10), 0 }; + result = base; + result.Substitute("XX", XX); + } + else + { + result.Format(base, index); + } + return result; } -#endif \ No newline at end of file + +void BuildFiles::LoadArtSet(const char* filename) +{ + for (int index = 0; index < MAXARTFILES_BASE; index++) + { + auto fn = artGetIndexedFileName(filename, index); + LoadArtFile(fn, false); + } +} + +BuildFiles TileFiles; diff --git a/source/common/textures/imagetexture.cpp b/source/common/textures/imagetexture.cpp index 5d27d58e1..28fc4b598 100644 --- a/source/common/textures/imagetexture.cpp +++ b/source/common/textures/imagetexture.cpp @@ -55,8 +55,8 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name) Size.y = img->GetHeight(); auto offsets = img->GetOffsets(); - LeftOffset = offsets.first; - TopOffset = offsets.second; + PicAnim.xofs = offsets.first; + PicAnim.yofs = offsets.second; bMasked = img->bMasked; bTranslucent = img->bTranslucent; diff --git a/source/common/textures/texture.cpp b/source/common/textures/texture.cpp index 52c25f813..61cb443ad 100644 --- a/source/common/textures/texture.cpp +++ b/source/common/textures/texture.cpp @@ -432,64 +432,3 @@ FTexture *FTexture::GetTexture(const char *path) return tex; } -//========================================================================== -// -// Base class for Build tile textures -// This needs a few subclasses for different use cases. -// -//========================================================================== - -FBitmap FTileTexture::GetBgraBitmap(PalEntry* remap, int* ptrans) -{ - FBitmap bmp; - bmp.Create(Size.x, Size.y); - const uint8_t* ppix = Get8BitPixels(); // any properly implemented tile MUST return something valid here. - if (ppix) bmp.CopyPixelData(0, 0, ppix, Size.x, Size.y, Size.y, 1, 0, remap); - return bmp; -} - -void FTileTexture::Create8BitPixels(uint8_t* buffer) -{ - auto pix = Get8BitPixels(); - if (pix) memcpy(buffer, pix, Size.x * Size.y); -} - - -//========================================================================== -// -// A tile coming from an ART file. -// -//========================================================================== - -class FArtTile : public FTileTexture -{ - const TArray &RawPixels; - const uint32_t Offset; -public: - FArtTile(const TArray& backingstore, uint32_t offset, int width, int height, int left, int top) - : RawPixels(backingstore), Offset(offset) - { - Size.x = (int16_t)width; - Size.y = (int16_t)height; - LeftOffset = left; - TopOffset = top; - } - - const uint8_t* Get8BitPixels() override - { - return RawPixels.Data() ? RawPixels.Data() + Offset : nullptr; - } -}; - -FTexture* FTexture::GetTileTexture(const char* name, const TArray& backingstore, uint32_t offset, int width, int height, int xofs, int yofs) -{ - auto res = textures.CheckKey(name); - if (res) return *res; - auto tex = new FArtTile(backingstore, offset, width, height, xofs, yofs); - if (tex) - { - tex->SetName(name); - textures.Insert(name, tex); - } - return tex; -} \ No newline at end of file diff --git a/source/common/textures/textures.h b/source/common/textures/textures.h index 9fe0d7f93..139b6ffcf 100644 --- a/source/common/textures/textures.h +++ b/source/common/textures/textures.h @@ -3,7 +3,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 2005-2016 Randy Heit -** Copyright 2005-2016 Christoph Oelckers +** Copyright 2005-2019 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -37,19 +37,30 @@ #include "textureid.h" #include "zstring.h" +#include "tarray.h" #include "palentry.h" -/* -#include "v_palette.h" -#include "r_data/v_colortables.h" -#include "colormatcher.h" -#include "r_data/renderstyle.h" -#include "r_data/r_translate.h" -#include "hwrenderer/textures/hw_texcontainer.h" -*/ -#include class FImageSource; +// picanm[].sf: +// |bit(1<<7) +// |animtype|animtype|texhitscan|nofullbright|speed|speed|speed|speed| +enum AnimFlags +{ + PICANM_ANIMTYPE_NONE = 0, + PICANM_ANIMTYPE_OSC = (1 << 6), + PICANM_ANIMTYPE_FWD = (2 << 6), + PICANM_ANIMTYPE_BACK = (3 << 6), + + PICANM_ANIMTYPE_SHIFT = 6, + PICANM_ANIMTYPE_MASK = (3 << 6), // must be 192 + PICANM_MISC_MASK = (3 << 4), + PICANM_TEXHITSCAN_BIT = (2 << 4), + PICANM_NOFULLBRIGHT_BIT = (1 << 4), + PICANM_ANIMSPEED_MASK = 15, // must be 15 +}; + + enum ECreateTexBufferFlags { CTF_CheckHires = 1, // use external hires replacement if found @@ -63,6 +74,27 @@ struct size_16_t // must be the same format as vec2_16_t, we cannot include a di int16_t x, y; }; +// NOTE: If the layout of this struct is changed, loadpics() must be modified +// accordingly. +struct picanm_t +{ + uint8_t num; // animate number + int8_t xofs, yofs; + uint8_t sf; // anim. speed and flags + uint8_t extra; + + void Clear() + { + extra = sf = yofs = xofs = num = 0; + } +}; + +struct rottile_t +{ + int16_t newtile; + int16_t owner; +}; + class FBitmap; struct FRemapTable; @@ -78,6 +110,9 @@ class FMultipatchTextureBuilder; extern int r_spriteadjustSW, r_spriteadjustHW; +picanm_t tileConvertAnimFormat(int32_t const picanmdisk); + + class FNullTextureID : public FTextureID { public: @@ -147,12 +182,18 @@ struct FTextureBuffer // Base texture class class FTexture { - public: + enum UseType : uint8_t + { + Image, // anything that is not a regular tile. + Art, // from an ART file, readonly + Writable, // A writable texture + Restorable, // a writable copy of something else + User // A texture with user-provided image content + }; + static FTexture *CreateTexture(const char *name); static FTexture* GetTexture(const char* path); - static FTexture* GetTileTexture(const char* name, const TArray& backingstore, uint32_t offset, int width, int height, int xofs, int yofs); - virtual ~FTexture (); virtual FImageSource *GetImage() const { return nullptr; } @@ -171,15 +212,18 @@ public: static int SmoothEdges(unsigned char * buffer,int w, int h); static PalEntry averageColor(const uint32_t *data, int size, int maxout); - int GetWidth() { return Size.x; } - int GetHeight() { return Size.y; } - const size_16_t &GetSize() { return Size; } - int GetLeftOffset() { return LeftOffset; } - int GetTopOffset() { return TopOffset; } + int GetWidth() const { return Size.x; } + int GetHeight() const { return Size.y; } + const size_16_t &GetSize() const { return Size; } + const uint8_t& GetPicSize() const { return PicSize; } + int GetLeftOffset() const { return PicAnim.xofs; } + 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. FTextureBuffer CreateTexBuffer(int translation, int flags = 0); bool GetTranslucency(); void CheckTrans(unsigned char * buffer, int size, int trans); bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch); + virtual void Reload() {} protected: @@ -187,21 +231,42 @@ protected: { Size.x = BaseTexture->GetWidth(); Size.y = BaseTexture->GetHeight(); - TopOffset = BaseTexture->TopOffset; - TopOffset = BaseTexture->TopOffset; + PicAnim.xofs = BaseTexture->PicAnim.xofs; + PicAnim.yofs = BaseTexture->PicAnim.yofs; + UpdatePicSize(); } void SetSize(int w, int h) { Size = { int16_t(w), int16_t(h) }; + UpdatePicSize(); } + void UpdatePicSize() + { + int j = 15; + int size; + + while ((j > 1) && ((1 << j) > Size.x)) + j--; + size = j; + + j = 15; + while ((j > 1) && ((1 << j) > Size.y)) + j--; + PicSize |= j << 4; + } + + FString Name; size_16_t Size = { 0,0 }; // Keep this in the native format so that we can use it without copying it around. - int LeftOffset = 0, TopOffset = 0; + picanm_t PicAnim = {}; + rottile_t RotTile = { -1,-1 }; uint8_t bMasked = true; // Texture (might) have holes int8_t bTranslucent = -1; // Does this texture have an active alpha channel? bool skyColorDone = false; + uint8_t PicSize; // A special piece of Build weirdness. + UseType useType = Image; PalEntry FloorSkyColor; PalEntry CeilingSkyColor; @@ -213,11 +278,211 @@ protected: class FTileTexture : public FTexture { public: + FTileTexture() + { + useType = Art; + } void SetName(const char* name) { Name = name; } FBitmap GetBgraBitmap(PalEntry* remap, int* ptrans) override; void Create8BitPixels(uint8_t* buffer) override; + virtual bool Resize(int w, int h) { return false; } // Regular tiles cannot be resized. }; +//========================================================================== +// +// A tile coming from an ART file. +// +//========================================================================== + +class FArtTile : public FTileTexture +{ + const TArray& RawPixels; + const uint32_t Offset; +public: + FArtTile(const TArray& 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 a writable surface +// +//========================================================================== + +class FWritableTile : public FTileTexture +{ +protected: + TArray buffer; + + FWritableTile() {} +public: + FWritableTile(int width, int height) + { + useType = Writable; + SetSize(width, height); + buffer.Resize(width * height); + } + + const uint8_t* Get8BitPixels() override + { + return buffer.Data(); + } + + bool Resize(int w, int h) override + { + if (w * h == 0) + { + buffer.Reset(); + } + else + { + SetSize(w, h); + buffer.Resize(w * h); + } + } + +}; + +//========================================================================== +// +// A tile with a writable surface +// +//========================================================================== + +class FRestorableTile : public FWritableTile +{ + FTexture* Base; + +public: + FRestorableTile(FTexture* base) + { + useType = Restorable; + Base = base; + CopySize(base); + Reload(); + } + + void Reload() override + { + Base->Create8BitPixels(buffer.Data()); + } + + bool Resize(int w, int h) override + { + return false; + } +}; + +//========================================================================== +// +// A tile with a user provided buffer +// +//========================================================================== + +class FUserTile : public FTileTexture +{ + const uint8_t* RawPixels; +public: + FUserTile(const uint8_t* data, int width, int height) + : RawPixels(data) + { + useType = User; + SetSize(width, height); + } + + const uint8_t* Get8BitPixels() override + { + return RawPixels; + } +}; + +//========================================================================== +// +// A tile with a user provided buffer +// +//========================================================================== + +struct BuildTileDescriptor +{ + int tilenum; + FTexture* Texture; +}; + +//========================================================================== +// +// One ART file. +// +//========================================================================== + +struct BuildArtFile +{ + FString filename; + TArray RawData; + TArray Textures; + + void AddTiles(); + ~BuildArtFile() + { + for (auto& desc : Textures) + { + delete desc.Texture; + } + } + + 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); + Textures = std::move(other.Textures); + } + + BuildArtFile& operator=(const BuildArtFile&& other) + { + filename = std::move(other.filename); + RawData = std::move(other.RawData); + Textures = std::move(other.Textures); + } +}; + +//========================================================================== +// +// THe tile container +// +//========================================================================== + +struct BuildFiles +{ + TArray ArtFiles; + TArray PerMapArtFiles; + void AddFile(BuildArtFile& bfd, bool permap) + { + if (!permap) ArtFiles.Push(std::move(bfd)); + else PerMapArtFiles.Push(std::move(bfd)); + } + int FindFile(const FString& filename) + { + return ArtFiles.FindEx([filename](const BuildArtFile& element) { return filename.CompareNoCase(element.filename) == 0; }); + } + void LoadArtFile(const char* file, bool mapart); + void CloseAllMapArt(); + void LoadArtSet(const char* filename); + +}; + +extern BuildFiles TileFiles; + #endif diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 543806fb0..62311e6f3 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -5836,46 +5836,6 @@ SHOWSPRITE: extern int tilefileoffs[MAXTILES]; //offset into the extern char tilefilenum[MAXTILES]; //0-11 -#if 0 -loadtile(short tilenume) -{ - char *ptr; - int i; - char zerochar = 0; - - if (walsiz[tilenume] <= 0) - return; - - i = tilefilenum[tilenume]; - if (i != artfilnum) - { - if (artfil != -1) - kclose(artfil); - artfilnum = i; - artfilplc = 0L; - - artfilename[7] = (i%10)+48; - artfilename[6] = ((i/10)%10)+48; - artfilename[5] = ((i/100)%10)+48; - artfil = kopen4load(artfilename); - faketimerhandler(); - } - - if (waloff[tilenume] == 0) - allocache(&waloff[tilenume],walsiz[tilenume],&zerochar); - - if (artfilplc != tilefileoffs[tilenume]) - { - klseek(artfil,tilefileoffs[tilenume]-artfilplc,SEEK_CUR); - faketimerhandler(); - } - - ptr = (char *)waloff[tilenume]; - kread(artfil,ptr,walsiz[tilenume]); - faketimerhandler(); - artfilplc = tilefileoffs[tilenume]+walsiz[tilenume]; -} -#endif #if RANDOM_DEBUG int