mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
- some reworking of the texture code to make integration of Build tiles easier.
This commit is contained in:
parent
fbc22e0125
commit
bb67a1ba38
9 changed files with 403 additions and 120 deletions
|
@ -1052,6 +1052,7 @@ set (PCH_SOURCES
|
||||||
common/utility/memarena.cpp
|
common/utility/memarena.cpp
|
||||||
|
|
||||||
common/textures/bitmap.cpp
|
common/textures/bitmap.cpp
|
||||||
|
common/textures/buildtiles.cpp
|
||||||
common/textures/texture.cpp
|
common/textures/texture.cpp
|
||||||
common/textures/image.cpp
|
common/textures/image.cpp
|
||||||
common/textures/imagetexture.cpp
|
common/textures/imagetexture.cpp
|
||||||
|
|
325
source/common/textures/buildtiles.cpp
Normal file
325
source/common/textures/buildtiles.cpp
Normal file
|
@ -0,0 +1,325 @@
|
||||||
|
/*
|
||||||
|
** buildtexture.cpp
|
||||||
|
** Handling Build textures
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2019 Christoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "files.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
#include "textures.h"
|
||||||
|
#include "image.h"
|
||||||
|
#include "cache1d.h"
|
||||||
|
|
||||||
|
struct BuildTileDescriptor
|
||||||
|
{
|
||||||
|
int tilenum;
|
||||||
|
FTexture *Texture;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuildFileDescriptor
|
||||||
|
{
|
||||||
|
FString filename;
|
||||||
|
TArray<uint8_t> RawData;
|
||||||
|
TArray<BuildTileDescriptor> Textures;
|
||||||
|
bool MapArt;
|
||||||
|
bool Active;
|
||||||
|
|
||||||
|
void AddTiles();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuildFiles
|
||||||
|
{
|
||||||
|
TArray<BuildFileDescriptor> FileDescriptors;
|
||||||
|
void AddFile(BuildFileDescriptor &bfd)
|
||||||
|
{
|
||||||
|
FileDescriptors.Push(std::move(bfd));
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// AddTiles
|
||||||
|
//
|
||||||
|
// Adds all the tiles in an artfile to the texture manager.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void BuildFileDescriptor::AddTiles ()
|
||||||
|
{
|
||||||
|
|
||||||
|
const uint8_t *tiles = RawData.Data();
|
||||||
|
// int numtiles = LittleLong(((uint32_t *)tiles)[1]); // This value is not reliable
|
||||||
|
int tilestart = LittleLong(((uint32_t *)tiles)[2]);
|
||||||
|
int tileend = LittleLong(((uint32_t *)tiles)[3]);
|
||||||
|
const uint16_t *tilesizx = &((const uint16_t *)tiles)[8];
|
||||||
|
const uint16_t *tilesizy = &tilesizx[tileend - tilestart + 1];
|
||||||
|
const uint32_t *picanm = (const uint32_t *)&tilesizy[tileend - tilestart + 1];
|
||||||
|
const uint8_t *tiledata = (const uint8_t *)&picanm[tileend - tilestart + 1];
|
||||||
|
|
||||||
|
for (int i = tilestart; i <= tileend; ++i)
|
||||||
|
{
|
||||||
|
int pic = i - tilestart;
|
||||||
|
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();
|
||||||
|
tiledata += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// CountTiles
|
||||||
|
//
|
||||||
|
// Returns the number of tiles provided by an artfile
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
int CountTiles (const void *RawData)
|
||||||
|
{
|
||||||
|
int version = LittleLong(*(uint32_t *)RawData);
|
||||||
|
if (version != 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tilestart = LittleLong(((uint32_t *)RawData)[2]);
|
||||||
|
int tileend = LittleLong(((uint32_t *)RawData)[3]);
|
||||||
|
|
||||||
|
return tileend >= tilestart ? tileend - tilestart + 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// CloseAllMapArt
|
||||||
|
//
|
||||||
|
// Closes all per-map ART files
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void BuildFiles::CloseAllMapArt()
|
||||||
|
{
|
||||||
|
for (auto& fd : FileDescriptors)
|
||||||
|
{
|
||||||
|
if (fd.MapArt)
|
||||||
|
{
|
||||||
|
fd.Active = false;
|
||||||
|
fd.RawData.Reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// LoadArtFile
|
||||||
|
//
|
||||||
|
// Returns the number of tiles found. Also loads all the data for
|
||||||
|
// R_InitBuildTiles() to process later.
|
||||||
|
//
|
||||||
|
// let's load everything into memory on startup.
|
||||||
|
// Even for Ion Fury this will merely add 60 MB, because the engine already needs to cache the data, albeit in a compressed-per-lump form,
|
||||||
|
// so its 100MB art file will only have a partial impact on memory.
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
void BuildFiles::LoadArtFile(const char *fn, bool mapart)
|
||||||
|
{
|
||||||
|
auto old = FindFile(fn);
|
||||||
|
if (old)
|
||||||
|
{
|
||||||
|
FileReader fr = kopenFileReader(fn, 0);
|
||||||
|
if (fr.isOpen())
|
||||||
|
{
|
||||||
|
auto artdata = fr.Read();
|
||||||
|
const uint8_t *artptr = artdata.Data();
|
||||||
|
if (artdata.Size() > 16)
|
||||||
|
{
|
||||||
|
if (memcmp(artptr, "BUILDART", 8) == 0) artptr += 8;
|
||||||
|
// Only load the data if the header is present
|
||||||
|
if (CountTiles(artptr) > 0)
|
||||||
|
{
|
||||||
|
FileDescriptors.Reserve(1);
|
||||||
|
auto &fd = FileDescriptors.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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// loadpics
|
||||||
|
//
|
||||||
|
int32_t BuildFiles::LoadArtSet(const char* filename)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -43,54 +43,6 @@
|
||||||
|
|
||||||
int FImageSource::NextID;
|
int FImageSource::NextID;
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// the default just returns an empty texture.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
void FImageSource::CreatePalettedPixels(uint8_t *buffer)
|
|
||||||
{
|
|
||||||
memset(buffer, 0, Width * Height);
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t* FImageSource::GetPalettedPixels()
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// FImageSource::CopyPixels
|
|
||||||
//
|
|
||||||
// this is the generic case that can handle
|
|
||||||
// any properly implemented texture for software rendering.
|
|
||||||
// Its drawback is that it is limited to the base palette which is
|
|
||||||
// why all classes that handle different palettes should subclass this
|
|
||||||
// method
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
int FImageSource::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap)
|
|
||||||
{
|
|
||||||
TArray<uint8_t> buffer;
|
|
||||||
const uint8_t* ppix = GetPalettedPixels();
|
|
||||||
if (ppix == nullptr)
|
|
||||||
{
|
|
||||||
buffer.Resize(Width * Height);
|
|
||||||
CreatePalettedPixels(buffer.Data());
|
|
||||||
ppix = buffer.Data();
|
|
||||||
}
|
|
||||||
bmp->CopyPixelData(0, 0, ppix, Width, Height, Height, 1, 0, remap);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FImageSource::CopyPixels(FBitmap* bmp, int conversion)
|
|
||||||
{
|
|
||||||
return CopyTranslatedPixels(bmp, ImageHelpers::BaseColors); // This should never get called for ART tiles.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -61,10 +61,8 @@ public:
|
||||||
// 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture.
|
// 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture.
|
||||||
static FImageSource * GetImage(const char *name);
|
static FImageSource * GetImage(const char *name);
|
||||||
|
|
||||||
virtual void CreatePalettedPixels(uint8_t *destbuffer);
|
virtual void CreatePalettedPixels(uint8_t *destbuffer) = 0;
|
||||||
virtual const uint8_t* GetPalettedPixels();
|
virtual int CopyPixels(FBitmap* bmp, int conversion) = 0; // This will always ignore 'luminance'.
|
||||||
virtual int CopyPixels(FBitmap* bmp, int conversion); // This will always ignore 'luminance'.
|
|
||||||
int CopyTranslatedPixels(FBitmap* bmp, PalEntry* remap);
|
|
||||||
|
|
||||||
|
|
||||||
// Conversion option
|
// Conversion option
|
||||||
|
@ -126,7 +124,6 @@ class FImageTexture : public FTexture
|
||||||
public:
|
public:
|
||||||
FImageTexture (FImageSource *image, const char *name = nullptr);
|
FImageTexture (FImageSource *image, const char *name = nullptr);
|
||||||
void Create8BitPixels(uint8_t* buffer) override;
|
void Create8BitPixels(uint8_t* buffer) override;
|
||||||
const uint8_t* Get8BitPixels() override;
|
|
||||||
|
|
||||||
void SetImage(FImageSource *img) // This is only for the multipatch texture builder!
|
void SetImage(FImageSource *img) // This is only for the multipatch texture builder!
|
||||||
{
|
{
|
||||||
|
|
|
@ -51,8 +51,8 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name)
|
||||||
mImage = img;
|
mImage = img;
|
||||||
if (img != nullptr)
|
if (img != nullptr)
|
||||||
{
|
{
|
||||||
Width = img->GetWidth();
|
Size.x = img->GetWidth();
|
||||||
Height = img->GetHeight();
|
Size.y = img->GetHeight();
|
||||||
|
|
||||||
auto offsets = img->GetOffsets();
|
auto offsets = img->GetOffsets();
|
||||||
LeftOffset = offsets.first;
|
LeftOffset = offsets.first;
|
||||||
|
@ -72,7 +72,7 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name)
|
||||||
FBitmap FImageTexture::GetBgraBitmap(PalEntry *p, int *trans)
|
FBitmap FImageTexture::GetBgraBitmap(PalEntry *p, int *trans)
|
||||||
{
|
{
|
||||||
FBitmap bmp;
|
FBitmap bmp;
|
||||||
bmp.Create(Width, Height);
|
bmp.Create(Size.x, Size.y);
|
||||||
mImage->CopyPixels(&bmp, 0); // Todo: Handle translations.
|
mImage->CopyPixels(&bmp, 0); // Todo: Handle translations.
|
||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
@ -83,11 +83,6 @@ FBitmap FImageTexture::GetBgraBitmap(PalEntry *p, int *trans)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
const uint8_t *FImageTexture::Get8BitPixels()
|
|
||||||
{
|
|
||||||
return mImage->GetPalettedPixels();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FImageTexture::Create8BitPixels(uint8_t* buffer)
|
void FImageTexture::Create8BitPixels(uint8_t* buffer)
|
||||||
{
|
{
|
||||||
return mImage->CreatePalettedPixels(buffer);
|
return mImage->CreatePalettedPixels(buffer);
|
||||||
|
|
|
@ -93,7 +93,7 @@ FTexture::~FTexture ()
|
||||||
FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans)
|
FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans)
|
||||||
{
|
{
|
||||||
FBitmap bmp;
|
FBitmap bmp;
|
||||||
bmp.Create(Width, Height);
|
bmp.Create(Size.x, Size.y);
|
||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -434,35 +434,62 @@ FTexture *FTexture::GetTexture(const char *path)
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// A minimalistic wrapper around a Build ART file.
|
// Base class for Build tile textures
|
||||||
// The data in here is already the format we need.
|
// This needs a few subclasses for different use cases.
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
class FBuildTexture : public FImageSource
|
FBitmap FTileTexture::GetBgraBitmap(PalEntry* remap, int* ptrans)
|
||||||
{
|
{
|
||||||
const uint8_t* RawPixels;
|
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:
|
public:
|
||||||
FBuildTexture(const uint8_t* raw, int width, int height, int left, int top)
|
FArtTile(const TArray<uint8_t>& backingstore, uint32_t offset, int width, int height, int left, int top)
|
||||||
: RawPixels(raw)
|
: RawPixels(backingstore), Offset(offset)
|
||||||
{
|
{
|
||||||
Width = width;
|
Size.x = (int16_t)width;
|
||||||
Height = height;
|
Size.y = (int16_t)height;
|
||||||
LeftOffset = left;
|
LeftOffset = left;
|
||||||
TopOffset = top;
|
TopOffset = top;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t* GetPalettedPixels() override
|
const uint8_t* Get8BitPixels() override
|
||||||
{
|
{
|
||||||
return RawPixels;
|
return RawPixels.Data() ? RawPixels.Data() + Offset : nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
FTexture* FTexture::GetTileTexture(const char* name, const uint8_t* data, int width, int height, int xofs, int yofs)
|
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);
|
auto res = textures.CheckKey(name);
|
||||||
if (res) return *res;
|
if (res) return *res;
|
||||||
auto tex = new FImageTexture(new FBuildTexture(data, width, height, xofs, yofs), name);
|
auto tex = new FArtTile(backingstore, offset, width, height, xofs, yofs);
|
||||||
if (tex) textures.Insert(name, tex);
|
if (tex)
|
||||||
|
{
|
||||||
|
tex->SetName(name);
|
||||||
|
textures.Insert(name, tex);
|
||||||
|
}
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
|
@ -58,6 +58,10 @@ enum ECreateTexBufferFlags
|
||||||
CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures.
|
CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct size_16_t // must be the same format as vec2_16_t, we cannot include a dirty header like compat.h here.
|
||||||
|
{
|
||||||
|
int16_t x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class FBitmap;
|
class FBitmap;
|
||||||
|
@ -147,7 +151,8 @@ class FTexture
|
||||||
public:
|
public:
|
||||||
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 uint8_t* data, int width, int height, int xofs, int yofs);
|
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; }
|
||||||
|
@ -160,13 +165,15 @@ public:
|
||||||
// Returns the whole texture, stored in column-major order
|
// Returns the whole texture, stored in column-major order
|
||||||
virtual void Create8BitPixels(uint8_t* buffer);
|
virtual void Create8BitPixels(uint8_t* buffer);
|
||||||
virtual const uint8_t* Get8BitPixels();
|
virtual const uint8_t* Get8BitPixels();
|
||||||
|
virtual uint8_t* GetWritableBuffer() { return nullptr; } // For dynamic tiles. Requesting this must also invalidate the texture.
|
||||||
virtual FBitmap GetBgraBitmap(PalEntry *remap, int *trans = nullptr);
|
virtual FBitmap GetBgraBitmap(PalEntry *remap, int *trans = nullptr);
|
||||||
|
|
||||||
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 Width; }
|
int GetWidth() { return Size.x; }
|
||||||
int GetHeight() { return Height; }
|
int GetHeight() { return Size.y; }
|
||||||
|
const size_16_t &GetSize() { return Size; }
|
||||||
int GetLeftOffset() { return LeftOffset; }
|
int GetLeftOffset() { return LeftOffset; }
|
||||||
int GetTopOffset() { return TopOffset; }
|
int GetTopOffset() { return TopOffset; }
|
||||||
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);
|
||||||
|
@ -178,15 +185,20 @@ protected:
|
||||||
|
|
||||||
void CopySize(FTexture *BaseTexture)
|
void CopySize(FTexture *BaseTexture)
|
||||||
{
|
{
|
||||||
Width = BaseTexture->GetWidth();
|
Size.x = BaseTexture->GetWidth();
|
||||||
Height = BaseTexture->GetHeight();
|
Size.y = BaseTexture->GetHeight();
|
||||||
TopOffset = BaseTexture->TopOffset;
|
TopOffset = BaseTexture->TopOffset;
|
||||||
TopOffset = BaseTexture->TopOffset;
|
TopOffset = BaseTexture->TopOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Width = 0, Height = 0;
|
void SetSize(int w, int h)
|
||||||
int LeftOffset = 0, TopOffset = 0;
|
{
|
||||||
|
Size = { int16_t(w), int16_t(h) };
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
||||||
|
int LeftOffset = 0, TopOffset = 0;
|
||||||
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;
|
||||||
|
@ -197,6 +209,15 @@ protected:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FTileTexture : public FTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void SetName(const char* name) { Name = name; }
|
||||||
|
FBitmap GetBgraBitmap(PalEntry* remap, int* ptrans) override;
|
||||||
|
void Create8BitPixels(uint8_t* buffer) override;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6129,23 +6129,7 @@ static void G_Startup(void)
|
||||||
if (numplayers > 1)
|
if (numplayers > 1)
|
||||||
initprintf("Multiplayer initialized.\n");
|
initprintf("Multiplayer initialized.\n");
|
||||||
|
|
||||||
char *cwd;
|
if (artLoadFiles("tiles%03i.art",MAXCACHE1DSIZE) < 0)
|
||||||
|
|
||||||
if (g_modDir[0] != '/' && (cwd = buildvfs_getcwd(NULL, 0)))
|
|
||||||
{
|
|
||||||
buildvfs_chdir(g_modDir);
|
|
||||||
if (artLoadFiles("tiles%03i.art", MAXCACHE1DSIZE) < 0)
|
|
||||||
{
|
|
||||||
buildvfs_chdir(cwd);
|
|
||||||
if (artLoadFiles("tiles%03i.art", MAXCACHE1DSIZE) < 0)
|
|
||||||
G_GameExit("Failed loading art.");
|
|
||||||
}
|
|
||||||
buildvfs_chdir(cwd);
|
|
||||||
#ifndef __ANDROID__ //This crashes on *some* Android devices. Small onetime memory leak. TODO fix above function
|
|
||||||
Xfree(cwd);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else if (artLoadFiles("tiles%03i.art",MAXCACHE1DSIZE) < 0)
|
|
||||||
G_GameExit("Failed loading art.");
|
G_GameExit("Failed loading art.");
|
||||||
|
|
||||||
cacheAllSounds();
|
cacheAllSounds();
|
||||||
|
|
|
@ -7532,27 +7532,8 @@ static void G_Startup(void)
|
||||||
if (numplayers > 1)
|
if (numplayers > 1)
|
||||||
initprintf("Multiplayer initialized.\n");
|
initprintf("Multiplayer initialized.\n");
|
||||||
|
|
||||||
{
|
if (artLoadFiles("tiles%03i.art",MAXCACHE1DSIZE) < 0)
|
||||||
char *cwd;
|
G_GameExit("Failed loading art.");
|
||||||
|
|
||||||
if (g_modDir[0] != '/' && (cwd = getcwd(NULL, 0)))
|
|
||||||
{
|
|
||||||
Bchdir(g_modDir);
|
|
||||||
if (artLoadFiles("tiles%03i.art",MAXCACHE1DSIZE) < 0)
|
|
||||||
{
|
|
||||||
Bchdir(cwd);
|
|
||||||
if (artLoadFiles("tiles%03i.art",MAXCACHE1DSIZE) < 0)
|
|
||||||
G_GameExit("Failed loading art.");
|
|
||||||
}
|
|
||||||
Bchdir(cwd);
|
|
||||||
#ifndef __ANDROID__ //This crashes on *some* Android devices. Small onetime memory leak. TODO fix above function
|
|
||||||
Bfree(cwd);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (artLoadFiles("tiles%03i.art",MAXCACHE1DSIZE) < 0)
|
|
||||||
G_GameExit("Failed loading art.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make the fullscreen nuke logo background non-fullbright. Has to be
|
// Make the fullscreen nuke logo background non-fullbright. Has to be
|
||||||
// after dynamic tile remapping (from C_Compile) and loading tiles.
|
// after dynamic tile remapping (from C_Compile) and loading tiles.
|
||||||
|
|
Loading…
Reference in a new issue