- reorganized how BuildTiles stores its data.

Arrays of struct are better than struct of arrays.
This commit is contained in:
Christoph Oelckers 2020-05-24 15:02:20 +02:00
parent 2c5737795f
commit e6b94d35ff
8 changed files with 71 additions and 73 deletions

View file

@ -5079,7 +5079,7 @@ void renderSetTarget(int16_t tilenume, int32_t xsiz, int32_t ysiz)
return;
OpenGLRenderer::GLRenderer->StartOffscreen();
OpenGLRenderer::GLRenderer->BindToFrameBuffer(TileFiles.tiles[tilenume]);
OpenGLRenderer::GLRenderer->BindToFrameBuffer(tileGetTexture(tilenume));
//DRAWROOMS TO TILE BACKUP&SET CODE
bakxsiz = xdim; bakysiz = ydim;

View file

@ -50,6 +50,7 @@ void paletteSetColorTable(int32_t id, uint8_t const* table, bool notransparency,
if (id == 0)
{
GPalette.SetPalette(table, 255);
BuildTransTable(GPalette.BaseColors);
}
FRemapTable remap;
remap.AddColors(0, 256, table);

View file

@ -311,7 +311,7 @@ int32_t polymost_maskWallHasTranslucency(uwalltype const * const wall)
if (wall->cstat & CSTAT_WALL_TRANSLUCENT)
return true;
auto tex = TileFiles.tiles[wall->picnum];
auto tex = tileGetTexture(wall->picnum);
auto si = TileFiles.FindReplacement(wall->picnum, wall->pal);
if (si && hw_hightile) tex = si->faces[0];
if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
@ -324,7 +324,7 @@ int32_t polymost_spriteHasTranslucency(tspritetype const * const tspr)
((unsigned)tspr->owner < MAXSPRITES && spriteext[tspr->owner].alpha))
return true;
auto tex = TileFiles.tiles[tspr->picnum];
auto tex = tileGetTexture(tspr->picnum);
auto si = TileFiles.FindReplacement(tspr->picnum, tspr->shade, 0);
if (si && hw_hightile) tex = si->faces[0];
if (tex->GetTexelWidth() == 0 || tex->GetTexelHeight() == 0) return false;
@ -480,7 +480,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
else if (drawpoly_trepeat) sampleroverride = SamplerClampX;
else sampleroverride = SamplerClampXY;
bool success = GLInterface.SetTexture(globalpicnum, TileFiles.tiles[globalpicnum], globalpal, method, sampleroverride);
bool success = GLInterface.SetTexture(globalpicnum, tileGetTexture(globalpicnum), globalpal, method, sampleroverride);
if (!success)
{
tsiz.x = tsiz.y = 1;
@ -535,7 +535,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
{
float const r = 1.f / dd[i];
if (TileFiles.tiles[globalpicnum]->GetUseType() == FTexture::Canvas)
if (TileFiles.tiledata[globalpicnum].replacement == ReplacementType::Canvas)
{
//update texcoords, canvas textures are upside down!
vt->SetTexCoord(
@ -4605,7 +4605,7 @@ static void polymost_precache(int32_t dapicnum, int32_t dapalnum, int32_t datype
//Printf("precached %d %d type %d\n", dapicnum, dapalnum, datype);
hicprecaching = 1;
GLInterface.SetTexture(dapicnum, TileFiles.tiles[dapicnum], dapalnum, 0, -1);
GLInterface.SetTexture(dapicnum, tileGetTexture(dapicnum), dapalnum, 0, -1);
hicprecaching = 0;
if (datype == 0 || !hw_models) return;

View file

@ -658,7 +658,7 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
}
PalEntry p = 0xffffffff;
dg.mTexture = pic? pic : TileFiles.tiles[picnum];
dg.mTexture = pic? pic : tileGetTexture(picnum);
dg.mRemapIndex = dapalnum | (basepal << 8) | (dashade << 16);
dg.mVertCount = 4;
dg.mVertIndex = (int)mVertices.Reserve(4);
@ -835,7 +835,7 @@ void F2DDrawer::FillPolygon(int *rx1, int *ry1, int *xb1, int32_t npoints, int p
}
}
AddPoly(TileFiles.tiles[picnum], points.Data(), points.Size(), indices.data(), indices.size(), palette, shade, (props >> 7)& DAMETH_MASKPROPS, clipx1, clipy1, clipx2, clipy2);
AddPoly(tileGetTexture(picnum), points.Data(), points.Size(), indices.data(), indices.size(), palette, shade, (props >> 7)& DAMETH_MASKPROPS, clipx1, clipy1, clipx2, clipy2);
}
void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p)

View file

@ -120,11 +120,11 @@ bool SetTextureParms(DrawParms *parms, FTexture *img, double xx, double yy)
parms->texheight = img->GetDisplayHeight();
if (parms->top == INT_MAX || parms->fortext)
{
parms->top = img->GetTopOffset();
parms->top = img->GetDisplayTopOffset();
}
if (parms->left == INT_MAX || parms->fortext)
{
parms->left = img->GetLeftOffset();
parms->left = img->GetDisplayLeftOffset();
}
if (parms->destwidth == INT_MAX || parms->fortext)
{

View file

@ -134,9 +134,9 @@ void BuildTiles::AddTile(int tilenum, FTexture* tex, bool permap)
assert(AllTiles.Find(tex) == AllTiles.Size() && AllMapTiles.Find(tex) == AllMapTiles.Size());
auto& array = permap ? AllMapTiles : AllTiles;
array.Push(tex);
tiles[tilenum] = tex;
tiledata[tilenum].texture = tex;
if (!permap) tilesbak[tilenum] = tex;
if (!permap) tiledata[tilenum].backup = tex;
}
//===========================================================================
@ -323,7 +323,7 @@ void BuildTiles::InvalidateTile(int num)
{
if ((unsigned) num < MAXTILES)
{
auto tex = tiles[num];
auto tex = tiledata[num].texture;
tex->DeleteHardwareTextures();
for (auto &rep : tiledata[num].Hightiles)
{
@ -345,7 +345,7 @@ void BuildTiles::InvalidateTile(int num)
void BuildTiles::MakeCanvas(int tilenum, int width, int height)
{
auto canvas = ValidateCustomTile(tilenum, FTexture::Canvas);
auto canvas = ValidateCustomTile(tilenum, ReplacementType::Canvas);
canvas->Size.x = width;
canvas->Size.y = height;
}
@ -436,15 +436,15 @@ void BuildTiles::LoadArtSet(const char* filename)
//
//==========================================================================
FTexture* BuildTiles::ValidateCustomTile(int tilenum, int type)
FTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
{
if (tilenum < 0 || tilenum >= MAXTILES) return nullptr;
if (tiles[tilenum] != tilesbak[tilenum]) return nullptr; // no mucking around with map tiles.
auto tile = tiles[tilenum];
if (tile && tile->GetUseType() == type) return tile; // already created
if (tile->GetUseType() > FTexture::Art) return nullptr; // different custom type - cannot replace again.
if (tiledata[tilenum].texture != tiledata[tilenum].backup) return nullptr; // no mucking around with map tiles.
auto tile = tiledata[tilenum].texture;
if (tiledata[tilenum].replacement == type) return tile; // already created
if (tiledata[tilenum].replacement > ReplacementType::Art) return nullptr; // different custom type - cannot replace again.
FTexture* replacement = nullptr;
if (type == FTexture::Writable)
if (type == ReplacementType::Writable)
{
// Creates an empty writable tile.
// Current use cases are:
@ -455,7 +455,7 @@ FTexture* BuildTiles::ValidateCustomTile(int tilenum, int type)
// Blood's 'lens' effect (apparently MP only) - combination of a camera texture with a distortion map - should be made a shader effect to be applied to the camera texture.
replacement = new FWritableTile;
}
else if (type == FTexture::Restorable)
else if (type == ReplacementType::Restorable)
{
// This is for modifying an existing tile.
// It only gets used for the crosshair and a few specific effects:
@ -467,7 +467,7 @@ FTexture* BuildTiles::ValidateCustomTile(int tilenum, int type)
// todo: invalidate hardware textures for tile.
replacement = new FRestorableTile(tile);
}
else if (type == FTexture::Canvas)
else if (type == ReplacementType::Canvas)
{
replacement = new FCanvasTexture("camera", 0, 0);
}
@ -498,7 +498,7 @@ int32_t BuildTiles::artLoadFiles(const char* filename)
uint8_t* BuildTiles::tileCreate(int tilenum, int width, int height)
{
if (width <= 0 || height <= 0) return nullptr;
auto tex = ValidateCustomTile(tilenum, FTexture::Writable);
auto tex = ValidateCustomTile(tilenum, ReplacementType::Writable);
if (tex == nullptr) return nullptr;
auto wtex = static_cast<FWritableTile*>(tex);
if (!wtex->Resize(width, height)) return nullptr;
@ -514,7 +514,7 @@ uint8_t* BuildTiles::tileCreate(int tilenum, int width, int height)
uint8_t * BuildTiles::tileMakeWritable(int num)
{
auto tex = ValidateCustomTile(num, FTexture::Restorable);
auto tex = ValidateCustomTile(num, ReplacementType::Restorable);
return tex ? tex->GetWritableBuffer() : nullptr;
}
@ -543,8 +543,8 @@ void BuildTiles::tileSetExternal(int tilenum, int width, int height, uint8_t* da
int32_t tileGetCRC32(int tileNum)
{
if ((unsigned)tileNum >= (unsigned)MAXTILES) return 0;
auto tile = TileFiles.tiles[tileNum];
if (!tile ||tile->GetUseType() != FTexture::Art) return 0; // only consider original ART tiles.
auto tile = tileGetTexture(tileNum);
if (!tile || TileFiles.tiledata[tileNum].replacement != ReplacementType::Art) return 0; // only consider original ART tiles.
auto pixels = tile->Get8BitPixels();
if (!pixels) return 0;
int size = tile->GetWidth() * tile->GetHeight();
@ -571,10 +571,10 @@ int tileImportFromTexture(const char* fn, int tilenum, int alphacut, int istextu
if (xsiz <= 0 || ysiz <= 0)
return -2;
TileFiles.tiles[tilenum] = tex;
TileFiles.tiledata[tilenum].texture = tex;
#pragma message("tileImportFromTexture needs rework!") // Reminder so that this place isn't forgotten.
//#if 0
// Does this make any difference when the texture gets *properly* inserted into the tile array?
// Does this make any difference when the texture gets *properly* inserted into the tile array? Answer: Yes, it affects how translations affect it.
//if (istexture)
tileSetHightileReplacement(tilenum, 0, fn, (float)(255 - alphacut) * (1.f / 255.f), 1.0f, 1.0f, 1.0, 1.0, 0); // At the moment this is the only way to load the texture. The texture creation code is not ready yet for downconverting an image.
//#endif
@ -600,7 +600,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
if (pal == -1 && tile == source)
{
// Only modify the picanm info.
tex = TileFiles.tiles[tile];
tex = tileGetTexture(tile);
if (!tex) return;
picanm = &TileFiles.tiledata[tile].picanm;
sourceanm = picanm;
@ -610,7 +610,7 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
else
{
if (source == -1) source = tile;
tex = TileFiles.tiles[source];
tex = tileGetTexture(source);
if (!tex) return;
sourceanm = &TileFiles.tiledata[source].picanm;
srcxo = tex->GetLeftOffset();
@ -647,7 +647,11 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
void artClearMapArt(void)
{
TileFiles.CloseAllMapArt();
memcpy(TileFiles.tiles, TileFiles.tilesbak, sizeof(TileFiles.tiles));
for (auto& td : TileFiles.tiledata)
{
td.texture = td.backup;
td.picanm = td.picanmbackup;
}
TileFiles.SetupReverseTileMap();
}
@ -667,6 +671,10 @@ void artSetupMapArt(const char* filename)
FStringf firstname("%s_00.art", filename);
auto fr = fileSystem.OpenFileReader(firstname);
if (!fr.isOpen()) return;
for (auto& td : TileFiles.tiledata)
{
td.picanmbackup = td.picanm;
}
for (bssize_t i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++)
{
@ -684,7 +692,8 @@ void artSetupMapArt(const char* filename)
void tileDelete(int tile)
{
TileFiles.tiles[tile] = TileFiles.tilesbak[tile] = TileFiles.Placeholder;
TileFiles.TextureToTile.Remove(tileGetTexture(tile));
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TileFiles.Placeholder;
vox_undefine(tile);
md_undefinetile(tile);
tileRemoveReplacement(tile);
@ -698,7 +707,6 @@ void tileDelete(int tile)
void tileRemoveReplacement(int tile)
{
FTexture *tex = TileFiles.tiles[tile];
TileFiles.DeleteReplacements(tile);
}
@ -730,8 +738,8 @@ void tileSetDummy(int tile, int width, int height)
bool tileLoad(int tileNum)
{
if ((unsigned)tileNum >= MAXTILES) return false;
auto tex = TileFiles.tiles[tileNum];
if (!tex || tex->GetWidth() <= 0 || tex->GetHeight() <= 0) return false;
auto tex = tileGetTexture(tileNum);
if (!tex || tex->GetTexelWidth() <= 0 || tex->GetTexelHeight() <= 0) return false;
if (tex->Get8BitPixels()) return true;
if (!tex->CachedPixels.Size())
@ -756,7 +764,7 @@ int BuildTiles::findUnusedTile(void)
for (; lastUnusedTile >= 0; --lastUnusedTile)
{
auto tex = TileFiles.tiles[lastUnusedTile];
auto tex = tileGetTexture(lastUnusedTile);
if (!tex || tex->GetWidth() <= 0 || tex->GetHeight() <= 0) return lastUnusedTile;
}
return -1;
@ -765,7 +773,7 @@ int BuildTiles::findUnusedTile(void)
int BuildTiles::tileCreateRotated(int tileNum)
{
if ((unsigned)tileNum >= MAXTILES) return tileNum;
auto tex = TileFiles.tiles[tileNum];
auto tex = tileGetTexture(tileNum);
if (!tex || tex->GetWidth() <= 0 || tex->GetHeight() <= 0) return tileNum;
TArray<uint8_t> buffer(tex->GetWidth() * tex->GetHeight(), true);
tex->Create8BitPixels(buffer.Data());
@ -786,7 +794,7 @@ int BuildTiles::tileCreateRotated(int tileNum)
auto dtex = new FLooseTile(dbuffer, tex->GetHeight(), tex->GetWidth());
int index = findUnusedTile();
bool mapart = TileFiles.tiles[tileNum] != TileFiles.tilesbak[tileNum];
bool mapart = TileFiles.tiledata[tileNum].texture != TileFiles.tiledata[tileNum].backup;
TileFiles.AddTile(index, dtex, mapart);
return index;
}
@ -841,7 +849,7 @@ int tileSetHightileReplacement(int picnum, int palnum, const char *filename, flo
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
auto tex = TileFiles.tiles[picnum];
auto tex = tileGetTexture(picnum);
if (tex->GetWidth() <= 0 || tex->GetHeight() <= 0)
{
Printf("Warning: defined hightile replacement for empty tile %d.", picnum);
@ -877,7 +885,7 @@ int tileSetSkybox(int picnum, int palnum, const char **facenames, int flags )
if ((uint32_t)picnum >= (uint32_t)MAXTILES) return -1;
if ((uint32_t)palnum >= (uint32_t)MAXPALOOKUPS) return -1;
auto tex = TileFiles.tiles[picnum];
auto tex = tileGetTexture(picnum);
if (tex->GetWidth() <= 0 || tex->GetHeight() <= 0)
{
Printf("Warning: defined skybox replacement for empty tile %d.", picnum);

View file

@ -69,10 +69,7 @@ struct HightileReplacement
class FTileTexture : public FTexture
{
public:
FTileTexture()
{
useType = Art;
}
FTileTexture() = default;
void SetName(const char* name) { Name = name; }
FBitmap GetBgraBitmap(const PalEntry* remap, int* ptrans) override;
void Create8BitPixels(uint8_t* buffer) override;
@ -113,7 +110,6 @@ class FLooseTile : public FTileTexture
public:
FLooseTile(TArray<uint8_t> &store, int width, int height)
{
useType = Art; // Whatever this was before - now it's a tile!
RawPixels = std::move(store);
SetSize(width, height);
}
@ -135,7 +131,6 @@ class FDummyTile : public FTileTexture
public:
FDummyTile(int width, int height)
{
useType = Art;
SetSize(width, height);
}
@ -157,11 +152,6 @@ protected:
TArray<uint8_t> buffer;
public:
FWritableTile()
{
useType = Writable;
}
const uint8_t* Get8BitPixels() override
{
return buffer.Data();
@ -203,7 +193,6 @@ class FRestorableTile : public FWritableTile
public:
FRestorableTile(FTexture* base)
{
useType = Restorable;
Base = base;
CopySize(base);
Resize(GetWidth(), GetHeight());
@ -276,8 +265,6 @@ struct BuildTiles
TDeletingArray<BuildArtFile*> PerMapArtFiles;
TDeletingArray<FTexture*> AllTiles; // This is for deleting tiles when shutting down.
TDeletingArray<FTexture*> AllMapTiles; // Same for map tiles;
FTexture* tiles[MAXTILES];
FTexture* tilesbak[MAXTILES];
TMap<FString, FTexture*> textures;
TArray<FString> addedArt;
TMap<FTexture*, int> TextureToTile;
@ -285,8 +272,13 @@ struct BuildTiles
BuildTiles()
{
Placeholder = new FDummyTile(0, 0);
for (auto& tile : tiles) tile = Placeholder;
for (auto& tile : tilesbak) tile = Placeholder;
for (auto& tile : tiledata)
{
tile.backup = tile.texture = Placeholder;
tile.RotTile = { -1,-1 };
tile.picanm = {};
tile.replacement = ReplacementType::Art;
}
}
~BuildTiles()
{
@ -327,11 +319,11 @@ struct BuildTiles
TextureToTile.Clear();
for (int i = 0; i < MAXTILES; i++)
{
if (tiles[i] != nullptr) TextureToTile.Insert(tiles[i], i);
if (tiledata[i].texture != nullptr && tiledata[i].texture != Placeholder) TextureToTile.Insert(tiledata[i].texture, i);
}
}
FTexture* ValidateCustomTile(int tilenum, int type);
FTexture* ValidateCustomTile(int tilenum, ReplacementType type);
int32_t artLoadFiles(const char* filename);
uint8_t* tileMakeWritable(int num);
uint8_t* tileCreate(int tilenum, int width, int height);
@ -371,13 +363,13 @@ void tileCopySection(int tilenum1, int sx1, int sy1, int xsiz, int ysiz, int til
extern BuildTiles TileFiles;
inline bool tileCheck(int num)
{
auto tex = TileFiles.tiles[num];
auto tex = TileFiles.tiledata[num].texture;
return tex->GetWidth() > 0 && tex->GetHeight() > 0;
}
inline const uint8_t* tilePtr(int num)
{
auto tex = TileFiles.tiles[num];
auto tex = TileFiles.tiledata[num].texture;
auto p = tex->Get8BitPixels();
if (p) return p;
return tex->CachedPixels.Data();
@ -385,17 +377,18 @@ inline const uint8_t* tilePtr(int num)
inline uint8_t* tileData(int num)
{
auto tex = TileFiles.tiles[num];
auto tex = TileFiles.tiledata[num].texture;
return tex->GetWritableBuffer();
}
// Some hacks to allow accessing the no longer existing arrays as if they still were arrays to avoid changing hundreds of lines of code.
struct TileSiz
{
const vec2_16_t &operator[](size_t index)
const vec2_16_t operator[](size_t index)
{
assert(index < MAXTILES);
return TileFiles.tiles[index]->GetSize();
vec2_16_t v = { (int16_t)TileFiles.tiledata[index].texture->GetDisplayWidth(), (int16_t)TileFiles.tiledata[index].texture->GetDisplayHeight() };
return v;
}
};
extern TileSiz tilesiz;
@ -414,25 +407,25 @@ extern PicAnm picanm;
inline int tileWidth(int num)
{
assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayWidth();
return TileFiles.tiledata[num].texture->GetDisplayWidth();
}
inline int tileHeight(int num)
{
assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayHeight();
return TileFiles.tiledata[num].texture->GetDisplayHeight();
}
inline int tileLeftOffset(int num)
{
assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayLeftOffset();
return TileFiles.tiledata[num].texture->GetDisplayLeftOffset();
}
inline int tileTopOffset(int num)
{
assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayTopOffset();
return TileFiles.tiledata[num].texture->GetDisplayTopOffset();
}
inline int widthBits(int num)
@ -470,5 +463,5 @@ inline void tileInvalidate(int tilenume, int32_t, int32_t)
inline FTexture* tileGetTexture(int tile)
{
assert(tile < MAXTILES);
return TileFiles.tiles[tile];
return TileFiles.tiledata[tile].texture;
}

View file

@ -206,10 +206,6 @@ 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
Canvas, // camera texture
User // A texture with user-provided image content
};
@ -290,7 +286,7 @@ protected:
uint8_t bMasked = true; // Texture (might) have holes
int8_t bTranslucent = -1; // Does this texture have an active alpha channel?
bool skyColorDone = false;
UseType useType = Image;
UseType useType = User;
PalEntry FloorSkyColor;
PalEntry CeilingSkyColor;
TArray<uint8_t> CachedPixels;