- use the texture manager to handle texture data.

This commit is contained in:
Christoph Oelckers 2020-05-24 23:26:47 +02:00
parent 7b50e2bd8a
commit a70b7fa698
8 changed files with 88 additions and 130 deletions

View file

@ -51,10 +51,11 @@ void paletteSetColorTable(int32_t id, uint8_t const* table, bool notransparency,
if (id == 0)
{
GPalette.SetPalette(table, 255);
GPalette.BaseColors[255] = 0;
BuildTransTable(GPalette.BaseColors);
}
FRemapTable remap;
remap.AddColors(0, 256, table);
remap.AddColors(0, 256, table, 255);
if (!notransparency)
{
remap.Palette[255] = 0;
@ -267,7 +268,30 @@ void palettePostLoadLookups(void)
}
}
}
// todo: at this point we should swap colors 0 and 255 so that paletted images being created here have their transparent color at index 0.
#ifdef SWAP_255
// Swap colors 0 and 255 in all tables so that all paletted images have their transparent color at index 0.
// This means:
// - Swap palette and remap entries in all stored remap tables
// - change all remap entries of 255 to 0 and vice versa
auto colorswap = [](FRemapTable* remap)
{
std::swap(remap->Palette[0], remap->Palette[255]);
std::swap(remap->Remap[0], remap->Remap[255]);
for (auto& c : remap->Remap)
{
if (c == 0) c = 255;
else if (c == 255) c = 0;
}
};
for (auto remap : GPalette.uniqueRemaps)
{
colorswap(remap);
}
colorswap(&GPalette.GlobalBrightmap);
std::swap(GPalette.BaseColors[0], GPalette.BaseColors[255]);
#endif
}
//==========================================================================

View file

@ -19,6 +19,7 @@ Ken Silverman's official web site: http://www.advsys.net/ken
#include "v_video.h"
#include "flatvertices.h"
#include "palettecontainer.h"
#include "texturemanager.h"
CVAR(Bool, hw_detailmapping, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, hw_glowmapping, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
@ -210,7 +211,7 @@ void polymost_glreset()
}
else
{
TileFiles.ClearTextureCache();
TexMan.FlushAll();
}
if (polymosttext)
@ -535,7 +536,7 @@ static void polymost_drawpoly(vec2f_t const * const dpxy, int32_t const n, int32
{
float const r = 1.f / dd[i];
if (TileFiles.tiledata[globalpicnum].replacement == ReplacementType::Canvas)
if (tileGetTexture(globalpicnum)->isCanvas())
{
//update texcoords, canvas textures are upside down!
vt->SetTexCoord(

View file

@ -84,9 +84,10 @@ public:
FRemapTable IceMap; // This is used by the texture compositor so it must be globally accessible.
uint8_t GrayMap[256];
TArray<FRemapTable*> uniqueRemaps;
private:
FMemArena remapArena;
TArray<FRemapTable*> uniqueRemaps;
TArray<TAutoGrowArray<FRemapTablePtr, FRemapTable*>> TranslationTables;
public:
void Init(int numslots); // This cannot be a constructor!!!

View file

@ -432,7 +432,7 @@ protected:
uint16_t Width, Height;
int16_t _LeftOffset[2], _TopOffset[2];
FTexture (const char *name = NULL, int lumpnum = -1);
FTexture(const char *name = NULL, int lumpnum = -1);
public:
FTextureBuffer CreateTexBuffer(int translation, int flags = 0);

View file

@ -424,8 +424,8 @@ int GameMain()
C_DeinitConsole();
V_ClearFonts();
vox_deinit();
TileFiles.ClearTextureCache();
TileFiles.CloseAll(); // do this before shutting down graphics.
TexMan.DeleteAll();
TileFiles.CloseAll(); // delete the texture data before shutting down graphics.
GLInterface.Deinit();
I_ShutdownGraphics();
M_DeinitMenus();
@ -714,6 +714,7 @@ int RunGame()
}
TexMan.Init([]() {}, [](BuildInfo &) {});
V_InitFonts();
TileFiles.Init();
C_CON_SetAliases();
sfx_empty = fileSystem.FindFile("engine/dsempty.lmp"); // this must be done outside the sound code because it's initialized late.
I_InitSound();

View file

@ -113,7 +113,7 @@ static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backing
auto tex = new FArtTile(backingstore, offset, width, height);
auto p = &backingstore[offset];
auto siz = width * height;
#if 0
#ifdef SWAP_255
for (int i = 0; i < siz; i++, p++)
{
// move transparent color to index 0 to get in line with the rest of the texture management.
@ -129,6 +129,20 @@ static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backing
return nullptr;
}
void BuildTiles::Init()
{
auto Placeholder = TexMan.ByIndex(0);
for (auto& tile : tiledata)
{
tile.texture = Placeholder;
tile.backup = Placeholder;
tile.picanm = {};
tile.RotTile = { -1,-1 };
tile.replacement = ReplacementType::Art;
}
}
//==========================================================================
//
//
@ -137,11 +151,9 @@ static FTexture* GetTileTexture(const char* name, const TArray<uint8_t>& backing
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);
assert(!tex->GetID().isValid()); // must not be added yet.
TexMan.AddTexture(tex);
tiledata[tilenum].texture = tex;
if (!permap) tiledata[tilenum].backup = tex;
}
@ -279,49 +291,6 @@ int CountTiles (const char *fn, const uint8_t *RawData)
return tileend >= tilestart ? tileend - tilestart + 1 : 0;
}
//===========================================================================
//
// CloseAllMapArt
//
// Closes all per-map ART files
//
//===========================================================================
void BuildTiles::CloseAllMapArt()
{
AllMapTiles.DeleteAndClear();
PerMapArtFiles.DeleteAndClear();
}
//===========================================================================
//
// ClearTextureCache
//
// Deletes all hardware textures
//
//===========================================================================
void BuildTiles::ClearTextureCache(bool artonly)
{
for (auto tex : AllTiles)
{
tex->SystemTextures.Clean(true, true);
}
for (auto tex : AllMapTiles)
{
tex->SystemTextures.Clean(true, true);
}
if (!artonly)
{
decltype(textures)::Iterator it(textures);
decltype(textures)::Pair* pair;
while (it.NextPair(pair))
{
pair->Value->SystemTextures.Clean(true, true);
}
}
}
//===========================================================================
//
// InvalidateTile
@ -390,9 +359,8 @@ int BuildTiles::LoadArtFile(const char *fn, const char *mapname, int firsttile)
// Only load the data if the header is present
if (CountTiles(fn, artptr) > 0)
{
auto& descs = mapname ? PerMapArtFiles : ArtFiles;
auto file = new BuildArtFile;
descs.Push(file);
ArtFiles.Push(file);
file->filename = fn;
file->RawData = std::move(artdata);
AddTiles(firsttile, file->RawData, mapname);
@ -405,13 +373,6 @@ int BuildTiles::LoadArtFile(const char *fn, const char *mapname, int firsttile)
return -1;
}
}
else
{
// Reuse the old one but move it to the top. (better not.)
//auto fd = std::move(ArtFiles[old]);
//ArtFiles.Delete(old);
//ArtFiles.Push(std::move(fd));
}
return 0;
}
@ -448,10 +409,12 @@ void BuildTiles::LoadArtSet(const char* filename)
FTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
{
if (tilenum < 0 || tilenum >= MAXTILES) return nullptr;
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.
auto &td = tiledata[tilenum];
if (td.texture != td.backup) return nullptr; // no mucking around with map tiles.
auto tile = td.texture;
auto reptype = td.replacement;
if (reptype == type) return tile; // already created
if (reptype > ReplacementType::Art) return nullptr; // different custom type - cannot replace again.
FTexture* replacement = nullptr;
if (type == ReplacementType::Writable)
{
@ -546,7 +509,7 @@ int32_t tileGetCRC32(int tileNum)
auto size = tile->GetWidth() * tile->GetHeight();
if (size == 0) return 0;
#if 0
#ifdef SWAP_255
// Temporarily revert the data to its original form with 255 being transparent. Otherwise the CRC won't match.
auto p = pixels;
for (int i = 0; i < size; i++, p++)
@ -666,7 +629,6 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
void artClearMapArt(void)
{
TileFiles.CloseAllMapArt();
for (auto& td : TileFiles.tiledata)
{
td.texture = td.backup;
@ -688,7 +650,28 @@ void artSetupMapArt(const char* filename)
currentMapArt = filename;
artClearMapArt();
FStringf firstname("%s_00.art", filename);
FString lcfilename = filename;
lcfilename.MakeLower();
// Re-get from the texture manager if this map's tiles have already been created.
if (TileFiles.maptilesadded.Find(lcfilename) < TileFiles.maptilesadded.Size())
{
for (int i = 0; i < MAXTILES; i++)
{
FStringf name("maptile_%s_%05d", lcfilename.GetChars(), i);
auto texid = TexMan.CheckForTexture(name, ETextureType::Any);
if (texid.isValid())
{
TileFiles.tiledata[i].texture = TexMan.GetTexture(texid);
}
}
return;
}
TileFiles.maptilesadded.Push(lcfilename);
FStringf firstname("%s_00.art", lcfilename.GetChars());
auto fr = fileSystem.OpenFileReader(firstname);
if (!fr.isOpen()) return;
for (auto& td : TileFiles.tiledata)
@ -696,6 +679,7 @@ void artSetupMapArt(const char* filename)
td.picanmbackup = td.picanm;
}
for (bssize_t i = 0; i < MAXARTFILES_TOTAL - MAXARTFILES_BASE; i++)
{
FStringf fullname("%s_%02d.art", filename, i);
@ -713,7 +697,7 @@ void artSetupMapArt(const char* filename)
void tileDelete(int tile)
{
TileFiles.TextureToTile.Remove(tileGetTexture(tile));
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TileFiles.Placeholder;
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TexMan.ByIndex(0);
vox_undefine(tile);
md_undefinetile(tile);
tileRemoveReplacement(tile);
@ -806,11 +790,6 @@ int BuildTiles::tileCreateRotated(int tileNum)
return index;
}
void tileSetAnim(int tile, const picanm_t& anm)
{
}
//==========================================================================
//
//
@ -819,15 +798,7 @@ void tileSetAnim(int tile, const picanm_t& anm)
void BuildTiles::CloseAll()
{
decltype(textures)::Iterator it(textures);
decltype(textures)::Pair* pair;
while (it.NextPair(pair)) delete pair->Value;
textures.Clear();
CloseAllMapArt();
ArtFiles.DeleteAndClear();
AllTiles.DeleteAndClear();
if (Placeholder) delete Placeholder;
Placeholder = nullptr;
}
//==========================================================================

View file

@ -273,23 +273,11 @@ struct BuildTiles
TDeletingArray<BuildArtFile*> ArtFiles;
TileDesc tiledata[MAXTILES];
TDeletingArray<BuildArtFile*> PerMapArtFiles;
TDeletingArray<FTexture*> AllTiles; // This is for deleting tiles when shutting down.
TDeletingArray<FTexture*> AllMapTiles; // Same for map tiles;
TMap<FString, FTexture*> textures;
TArray<FString> addedArt;
TMap<FTexture*, int> TextureToTile;
TArray<FString> maptilesadded;
BuildTiles()
{
Placeholder = new FImageTexture(new FDummyTile(0, 0));
for (auto& tile : tiledata)
{
tile.backup = tile.texture = Placeholder;
tile.RotTile = { -1,-1 };
tile.picanm = {};
tile.replacement = ReplacementType::Art;
}
}
void Init(); // This cannot be a constructor because it needs the texture manager running.
~BuildTiles()
{
CloseAll();
@ -300,7 +288,7 @@ struct BuildTiles
void AddTile(int tilenum, FTexture* tex, bool permap = false);
void AddTiles(int firsttile, TArray<uint8_t>& store, const char *mapname);
void AddTiles(int firsttile, TArray<uint8_t>& store, const char* mapname);
void AddFile(BuildArtFile* bfd, bool permap)
{
@ -311,7 +299,7 @@ struct BuildTiles
{
return ArtFiles.FindEx([filename](const BuildArtFile* element) { return filename.CompareNoCase(element->filename) == 0; });
}
int LoadArtFile(const char* file, const char *mapname = nullptr, int firsttile = -1);
int LoadArtFile(const char* file, const char* mapname = nullptr, int firsttile = -1);
void CloseAllMapArt();
void LoadArtSet(const char* filename);
void AddArt(TArray<FString>& art)

View file

@ -787,37 +787,9 @@ bool InitGame()
}
LoadDemoRun();
// Save off total heap for later calculations
//TotalMemory = Z_AvailHeap();
//DSPRINTF(ds,"Available Heap before LoadImages = %d", TotalMemory);
//MONO_PRINT(ds);
// Reserve 1.5 megs for normal program use
// Generally, SW is consuming about a total of 11 megs including
// all the cached in graphics, etc. per level, so even on a 16 meg
// system, reserving 1.5 megs is fine.
// Note that on a 16 meg machine, Ken was leaving us about
// 24k for use outside the cache! This was causing out of mem problems
// when songs, etc., greater than the remaining heap were being loaded.
// Even if you pre-cache songs, etc. to help, reserving some heap is
// a very smart idea since the game uses malloc throughout execution.
//ReserveMem = AllocMem(1L<<20);
//if(ReserveMem == 0) MONO_PRINT("Could not allocate 1.5 meg reserve!");
// LoadImages will now proceed to steal all the remaining heap space
//_outtext("\n\n\n\n\n\n\n\n");
//AnimateCacheCursor();
TileFiles.LoadArtSet("tiles%03d.art");
// Now free it up for later use
/*
if(ReserveMem)
{
// Recalc TotalMemory for later reference
ActualHeap = Z_AvailHeap() + 1536000L;
FreeMem(ReserveMem);
}
*/
Connect();
SortBreakInfo();
parallaxtype = 1;