mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 11:10:47 +00:00
- reworked texture management, not yet active.
This commit is contained in:
parent
bb67a1ba38
commit
a6ba81939a
8 changed files with 379 additions and 334 deletions
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "vfs.h"
|
#include "vfs.h"
|
||||||
#include "cache1d.h"
|
#include "cache1d.h"
|
||||||
|
#include "textures.h"
|
||||||
|
|
||||||
enum rendmode_t {
|
enum rendmode_t {
|
||||||
REND_CLASSIC,
|
REND_CLASSIC,
|
||||||
|
@ -814,38 +815,7 @@ static CONSTEXPR const int32_t pow2long[32] =
|
||||||
268435456, 536870912, 1073741824, 2147483647
|
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];
|
EXTERN picanm_t picanm[MAXTILES];
|
||||||
typedef struct { int16_t newtile; int16_t owner; } rottile_t;
|
|
||||||
EXTERN rottile_t rottile[MAXTILES];
|
EXTERN rottile_t rottile[MAXTILES];
|
||||||
|
|
||||||
EXTERN int32_t windowpos, windowx, windowy;
|
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 artReadHeader(buildvfs_kfd fil, char const *fn, artheader_t *local);
|
||||||
int32_t artReadHeaderFromBuffer(uint8_t const *buf, artheader_t *local);
|
int32_t artReadHeaderFromBuffer(uint8_t const *buf, artheader_t *local);
|
||||||
int32_t artCheckUnitFileHeader(uint8_t const *buf, int32_t length);
|
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 artReadManifest(buildvfs_kfd fil, artheader_t const *local);
|
||||||
void artPreloadFile(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);
|
int32_t artLoadFiles(const char *filename, int32_t askedsize);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
extern int32_t globalx1, globaly2;
|
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)
|
static inline int32_t nsqrtasm(uint32_t a)
|
||||||
|
|
|
@ -396,19 +396,6 @@ int32_t artCheckUnitFileHeader(uint8_t const * const buf, int32_t length)
|
||||||
return 0;
|
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)
|
void artReadManifest(int32_t const fil, artheader_t const* const local)
|
||||||
{
|
{
|
||||||
int16_t* tilesizx = (int16_t*)Xmalloc(local->numtiles * sizeof(int16_t));
|
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));
|
kread(fil, &picanmdisk, sizeof(int32_t));
|
||||||
picanmdisk = B_LITTLE32(picanmdisk);
|
picanmdisk = B_LITTLE32(picanmdisk);
|
||||||
|
|
||||||
tileConvertAnimFormat(i, picanmdisk);
|
picanm[i] = tileConvertAnimFormat(picanmdisk);
|
||||||
}
|
}
|
||||||
|
|
||||||
DO_FREE_AND_NULL(tilesizx);
|
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)
|
int32_t artLoadFiles(const char *filename, int32_t askedsize)
|
||||||
{
|
{
|
||||||
|
TileFiles.LoadArtSet(filename);
|
||||||
|
|
||||||
Bstrncpyz(artfilenameformat, filename, sizeof(artfilenameformat));
|
Bstrncpyz(artfilenameformat, filename, sizeof(artfilenameformat));
|
||||||
|
|
||||||
Bmemset(&tilesizearray[0], 0, sizeof(vec2_16_t) * MAXTILES);
|
Bmemset(&tilesizearray[0], 0, sizeof(vec2_16_t) * MAXTILES);
|
||||||
|
|
|
@ -39,44 +39,63 @@
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "cache1d.h"
|
#include "cache1d.h"
|
||||||
|
|
||||||
struct BuildTileDescriptor
|
enum
|
||||||
{
|
{
|
||||||
int tilenum;
|
MAXARTFILES_BASE = 200,
|
||||||
FTexture *Texture;
|
MAXARTFILES_TOTAL = 220
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BuildFileDescriptor
|
picanm_t tileConvertAnimFormat(int32_t const picanmdisk)
|
||||||
{
|
{
|
||||||
FString filename;
|
// Unpack a 4 byte packed anim descriptor into the internal 5 byte format.
|
||||||
TArray<uint8_t> RawData;
|
picanm_t anm;
|
||||||
TArray<BuildTileDescriptor> Textures;
|
anm.num = picanmdisk & 63;
|
||||||
bool MapArt;
|
anm.xofs = (picanmdisk >> 8) & 255;
|
||||||
bool Active;
|
anm.yofs = (picanmdisk >> 16) & 255;
|
||||||
|
anm.sf = ((picanmdisk >> 24) & 15) | (picanmdisk & 192);
|
||||||
void AddTiles();
|
anm.extra = (picanmdisk >> 28) & 15;
|
||||||
};
|
return anm;
|
||||||
|
|
||||||
struct BuildFiles
|
|
||||||
{
|
|
||||||
TArray<BuildFileDescriptor> FileDescriptors;
|
|
||||||
void AddFile(BuildFileDescriptor &bfd)
|
|
||||||
{
|
|
||||||
FileDescriptors.Push(std::move(bfd));
|
|
||||||
}
|
}
|
||||||
BuildFileDescriptor *FindFile(const FString &filename)
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Base class for Build tile textures
|
||||||
|
// This needs a few subclasses for different use cases.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FBitmap FTileTexture::GetBgraBitmap(PalEntry* remap, int* ptrans)
|
||||||
{
|
{
|
||||||
auto ndx = FileDescriptors.FindEx([filename](const BuildFileDescriptor & element) { return filename.CompareNoCase(element.filename) == 0; });
|
FBitmap bmp;
|
||||||
if (ndx < FileDescriptors.Size()) return &FileDescriptors[ndx];
|
bmp.Create(Size.x, Size.y);
|
||||||
return nullptr;
|
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 LoadArtFile(const char *file, bool mapart);
|
|
||||||
void CloseAllMapArt();
|
|
||||||
int LoadIndexedFile(const char* base, int index);
|
|
||||||
void LoadArtSet(const char* filename);
|
|
||||||
|
|
||||||
};
|
void FTileTexture::Create8BitPixels(uint8_t* buffer)
|
||||||
|
{
|
||||||
|
auto pix = Get8BitPixels();
|
||||||
|
if (pix) memcpy(buffer, pix, Size.x * Size.y);
|
||||||
|
}
|
||||||
|
|
||||||
static BuildFiles alltilefiles;
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Tile textures are owned by their containing file object.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height, int picanm)
|
||||||
|
{
|
||||||
|
auto tex = new FArtTile(backingstore, offset, width, height, picanm);
|
||||||
|
if (tex)
|
||||||
|
{
|
||||||
|
tex->SetName(name);
|
||||||
|
}
|
||||||
|
return tex;
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
|
@ -86,7 +105,7 @@ static BuildFiles alltilefiles;
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
void BuildFileDescriptor::AddTiles ()
|
void BuildArtFile::AddTiles ()
|
||||||
{
|
{
|
||||||
|
|
||||||
const uint8_t *tiles = RawData.Data();
|
const uint8_t *tiles = RawData.Data();
|
||||||
|
@ -104,17 +123,15 @@ void BuildFileDescriptor::AddTiles ()
|
||||||
int width = LittleShort(tilesizx[pic]);
|
int width = LittleShort(tilesizx[pic]);
|
||||||
int height = LittleShort(tilesizy[pic]);
|
int height = LittleShort(tilesizy[pic]);
|
||||||
uint32_t anm = LittleLong(picanm[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;
|
int size = width*height;
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) continue;
|
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.
|
// 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);
|
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);
|
auto tex = GetTileTexture(name, RawData, uint32_t(tiledata - tiles), width, height, anm);
|
||||||
BuildTileDescriptor desc;
|
BuildTileDescriptor desc = { i, tex };
|
||||||
//Textures.Push();
|
Textures.Push(desc);
|
||||||
tiledata += size;
|
tiledata += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,14 +168,7 @@ int CountTiles (const void *RawData)
|
||||||
|
|
||||||
void BuildFiles::CloseAllMapArt()
|
void BuildFiles::CloseAllMapArt()
|
||||||
{
|
{
|
||||||
for (auto& fd : FileDescriptors)
|
PerMapArtFiles.Clear();
|
||||||
{
|
|
||||||
if (fd.MapArt)
|
|
||||||
{
|
|
||||||
fd.Active = false;
|
|
||||||
fd.RawData.Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -177,7 +187,7 @@ void BuildFiles::CloseAllMapArt()
|
||||||
void BuildFiles::LoadArtFile(const char *fn, bool mapart)
|
void BuildFiles::LoadArtFile(const char *fn, bool mapart)
|
||||||
{
|
{
|
||||||
auto old = FindFile(fn);
|
auto old = FindFile(fn);
|
||||||
if (old)
|
if (old >= ArtFiles.Size()) // Do not process if already loaded.
|
||||||
{
|
{
|
||||||
FileReader fr = kopenFileReader(fn, 0);
|
FileReader fr = kopenFileReader(fn, 0);
|
||||||
if (fr.isOpen())
|
if (fr.isOpen())
|
||||||
|
@ -190,136 +200,49 @@ void BuildFiles::LoadArtFile(const char *fn, bool mapart)
|
||||||
// Only load the data if the header is present
|
// Only load the data if the header is present
|
||||||
if (CountTiles(artptr) > 0)
|
if (CountTiles(artptr) > 0)
|
||||||
{
|
{
|
||||||
FileDescriptors.Reserve(1);
|
auto& descs = mapart ? PerMapArtFiles : ArtFiles;
|
||||||
auto &fd = FileDescriptors.Last();
|
descs.Reserve(1);
|
||||||
|
auto& fd = descs.Last();
|
||||||
fd.filename = fn;
|
fd.filename = fn;
|
||||||
fd.MapArt = mapart;
|
|
||||||
fd.Active = true;
|
|
||||||
fd.RawData = std::move(artdata);
|
fd.RawData = std::move(artdata);
|
||||||
fd.AddTiles();
|
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)
|
|
||||||
{
|
|
||||||
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
|
else
|
||||||
artPreloadFile(fil, &local);
|
{
|
||||||
|
// Reuse the old one but move it to the top.
|
||||||
|
auto fd = std::move(ArtFiles[old]);
|
||||||
|
ArtFiles.Delete(old);
|
||||||
|
ArtFiles.Push(std::move(fd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FString artGetIndexedFileName(const char *base, int32_t index)
|
||||||
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
int offscount = ktell(fil);
|
result.Format(base, index);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
for (bssize_t i = local.tilestart; i <= local.tileend; ++i)
|
|
||||||
|
void BuildFiles::LoadArtSet(const char* filename)
|
||||||
{
|
{
|
||||||
int const dasiz = tilesiz[i].x * tilesiz[i].y;
|
for (int index = 0; index < MAXARTFILES_BASE; index++)
|
||||||
|
|
||||||
tilefilenum[i] = tilefilei;
|
|
||||||
tilefileoffs[i] = offscount;
|
|
||||||
|
|
||||||
offscount += dasiz;
|
|
||||||
// artsize += ((dasiz+15)&0xfffffff0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
kclose(fil);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// loadpics
|
|
||||||
//
|
|
||||||
int32_t BuildFiles::LoadArtSet(const char* filename)
|
|
||||||
{
|
{
|
||||||
Bstrncpyz(artfilenameformat, filename, sizeof(artfilenameformat));
|
auto fn = artGetIndexedFileName(filename, index);
|
||||||
|
LoadArtFile(fn, false);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
BuildFiles TileFiles;
|
||||||
|
|
|
@ -55,8 +55,8 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name)
|
||||||
Size.y = img->GetHeight();
|
Size.y = img->GetHeight();
|
||||||
|
|
||||||
auto offsets = img->GetOffsets();
|
auto offsets = img->GetOffsets();
|
||||||
LeftOffset = offsets.first;
|
PicAnim.xofs = offsets.first;
|
||||||
TopOffset = offsets.second;
|
PicAnim.yofs = offsets.second;
|
||||||
|
|
||||||
bMasked = img->bMasked;
|
bMasked = img->bMasked;
|
||||||
bTranslucent = img->bTranslucent;
|
bTranslucent = img->bTranslucent;
|
||||||
|
|
|
@ -432,64 +432,3 @@ FTexture *FTexture::GetTexture(const char *path)
|
||||||
return tex;
|
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<uint8_t> &RawPixels;
|
|
||||||
const uint32_t Offset;
|
|
||||||
public:
|
|
||||||
FArtTile(const TArray<uint8_t>& 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<uint8_t>& 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;
|
|
||||||
}
|
|
|
@ -3,7 +3,7 @@
|
||||||
**
|
**
|
||||||
**---------------------------------------------------------------------------
|
**---------------------------------------------------------------------------
|
||||||
** Copyright 2005-2016 Randy Heit
|
** Copyright 2005-2016 Randy Heit
|
||||||
** Copyright 2005-2016 Christoph Oelckers
|
** Copyright 2005-2019 Christoph Oelckers
|
||||||
** All rights reserved.
|
** All rights reserved.
|
||||||
**
|
**
|
||||||
** Redistribution and use in source and binary forms, with or without
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -37,19 +37,30 @@
|
||||||
|
|
||||||
#include "textureid.h"
|
#include "textureid.h"
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
|
#include "tarray.h"
|
||||||
#include "palentry.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 <vector>
|
|
||||||
|
|
||||||
class FImageSource;
|
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
|
enum ECreateTexBufferFlags
|
||||||
{
|
{
|
||||||
CTF_CheckHires = 1, // use external hires replacement if found
|
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;
|
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;
|
class FBitmap;
|
||||||
struct FRemapTable;
|
struct FRemapTable;
|
||||||
|
@ -78,6 +110,9 @@ class FMultipatchTextureBuilder;
|
||||||
|
|
||||||
extern int r_spriteadjustSW, r_spriteadjustHW;
|
extern int r_spriteadjustSW, r_spriteadjustHW;
|
||||||
|
|
||||||
|
picanm_t tileConvertAnimFormat(int32_t const picanmdisk);
|
||||||
|
|
||||||
|
|
||||||
class FNullTextureID : public FTextureID
|
class FNullTextureID : public FTextureID
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -147,12 +182,18 @@ struct FTextureBuffer
|
||||||
// Base texture class
|
// Base texture class
|
||||||
class FTexture
|
class FTexture
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
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 *CreateTexture(const char *name);
|
||||||
static FTexture* GetTexture(const char* path);
|
static FTexture* GetTexture(const char* path);
|
||||||
static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height, int xofs, int yofs);
|
|
||||||
|
|
||||||
|
|
||||||
virtual ~FTexture ();
|
virtual ~FTexture ();
|
||||||
virtual FImageSource *GetImage() const { return nullptr; }
|
virtual FImageSource *GetImage() const { return nullptr; }
|
||||||
|
@ -171,15 +212,18 @@ public:
|
||||||
static int SmoothEdges(unsigned char * buffer,int w, int h);
|
static int SmoothEdges(unsigned char * buffer,int w, int h);
|
||||||
static PalEntry averageColor(const uint32_t *data, int size, int maxout);
|
static PalEntry averageColor(const uint32_t *data, int size, int maxout);
|
||||||
|
|
||||||
int GetWidth() { return Size.x; }
|
int GetWidth() const { return Size.x; }
|
||||||
int GetHeight() { return Size.y; }
|
int GetHeight() const { return Size.y; }
|
||||||
const size_16_t &GetSize() { return Size; }
|
const size_16_t &GetSize() const { return Size; }
|
||||||
int GetLeftOffset() { return LeftOffset; }
|
const uint8_t& GetPicSize() const { return PicSize; }
|
||||||
int GetTopOffset() { return TopOffset; }
|
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);
|
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
||||||
bool GetTranslucency();
|
bool GetTranslucency();
|
||||||
void CheckTrans(unsigned char * buffer, int size, int trans);
|
void CheckTrans(unsigned char * buffer, int size, int trans);
|
||||||
bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch);
|
bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch);
|
||||||
|
virtual void Reload() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -187,21 +231,42 @@ protected:
|
||||||
{
|
{
|
||||||
Size.x = BaseTexture->GetWidth();
|
Size.x = BaseTexture->GetWidth();
|
||||||
Size.y = BaseTexture->GetHeight();
|
Size.y = BaseTexture->GetHeight();
|
||||||
TopOffset = BaseTexture->TopOffset;
|
PicAnim.xofs = BaseTexture->PicAnim.xofs;
|
||||||
TopOffset = BaseTexture->TopOffset;
|
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;
|
||||||
|
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;
|
FString Name;
|
||||||
size_16_t Size = { 0,0 }; // Keep this in the native format so that we can use it without copying it around.
|
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
|
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; // A special piece of Build weirdness.
|
||||||
|
UseType useType = Image;
|
||||||
PalEntry FloorSkyColor;
|
PalEntry FloorSkyColor;
|
||||||
PalEntry CeilingSkyColor;
|
PalEntry CeilingSkyColor;
|
||||||
|
|
||||||
|
@ -213,11 +278,211 @@ protected:
|
||||||
class FTileTexture : public FTexture
|
class FTileTexture : public FTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
FTileTexture()
|
||||||
|
{
|
||||||
|
useType = Art;
|
||||||
|
}
|
||||||
void SetName(const char* name) { Name = name; }
|
void SetName(const char* name) { Name = name; }
|
||||||
FBitmap GetBgraBitmap(PalEntry* remap, int* ptrans) override;
|
FBitmap GetBgraBitmap(PalEntry* remap, int* ptrans) override;
|
||||||
void Create8BitPixels(uint8_t* buffer) 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<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 a writable surface
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
class FWritableTile : public FTileTexture
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
TArray<uint8_t> 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<uint8_t> RawData;
|
||||||
|
TArray<BuildTileDescriptor> 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<BuildArtFile> ArtFiles;
|
||||||
|
TArray<BuildArtFile> 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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5836,46 +5836,6 @@ SHOWSPRITE:
|
||||||
extern int tilefileoffs[MAXTILES]; //offset into the
|
extern int tilefileoffs[MAXTILES]; //offset into the
|
||||||
extern char tilefilenum[MAXTILES]; //0-11
|
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
|
#if RANDOM_DEBUG
|
||||||
int
|
int
|
||||||
|
|
Loading…
Reference in a new issue