- fixed camera textures breaking in SW when restarting a level.

This was caused by attempting to delete the camera textures when cleaning up the mirror array.
The Build tile manager was not prepared for such a use case and left a broken texture behind.

To allow this to function it now resets the texture replacement type when deleting a tile and to avoid creating new camera textures these will now be stored in a cache and recycled later.
This commit is contained in:
Christoph Oelckers 2021-12-02 21:40:43 +01:00
parent 60630f5b84
commit c2baa68160
4 changed files with 19 additions and 5 deletions

View file

@ -86,11 +86,11 @@ FTextureManager::~FTextureManager ()
void FTextureManager::DeleteAll()
{
FImageSource::ClearImages();
for (unsigned int i = 0; i < Textures.Size(); ++i)
{
delete Textures[i].Texture;
}
FImageSource::ClearImages();
Textures.Clear();
Translation.Clear();
FirstTextureForFile.Clear();

View file

@ -157,8 +157,8 @@ void BuildTiles::Init()
void BuildTiles::AddTile(int tilenum, FGameTexture* tex, bool permap)
{
assert(!tex->GetID().isValid()); // must not be added yet.
TexMan.AddGameTexture(tex);
if (!tex->GetID().isValid())
TexMan.AddGameTexture(tex);
tiledata[tilenum].texture = tex;
if (!permap) tiledata[tilenum].backup = tex;
}
@ -391,10 +391,24 @@ FGameTexture* BuildTiles::ValidateCustomTile(int tilenum, ReplacementType type)
}
else if (type == ReplacementType::Canvas)
{
// necessary fuckery thanks to SW considering camera textures the same as mirrors and deleting them if opportune.
// If we do not remember them this would create new ones over and over again.
auto check = cameratextures.CheckKey(tilenum);
if (check)
{
// if this once was a camera texture but now isn't anymore, grab that camera texture from the cache and reuse it.
AddTile(tilenum, *check);
return *check;
}
replacement = new FCanvasTexture(1, 1);
}
else return nullptr;
auto rep = MakeGameTexture(replacement, tile->GetName(), ETextureType::Override);
if (type == ReplacementType::Canvas)
{
cameratextures.Insert(tilenum, rep);
}
AddTile(tilenum, rep);
return rep;
}
@ -648,6 +662,7 @@ void artSetupMapArt(const char* filename)
void tileDelete(int tile)
{
TileFiles.tiledata[tile].texture = TileFiles.tiledata[tile].backup = TexMan.GameByIndex(0);
TileFiles.tiledata[tile].replacement = ReplacementType::Art; // whatever this was, now it isn't anymore. (SW tries to nuke camera textures with this, :( )
tiletovox[tile] = -1; // clear the link but don't clear the voxel. It may be in use for another tile.
md_undefinetile(tile);
}

View file

@ -293,6 +293,7 @@ struct BuildTiles
TileDesc tiledata[MAXTILES];
TArray<FString> addedArt;
TArray<FString> maptilesadded;
TMap<int, FGameTexture*> cameratextures;
void Init(); // This cannot be a constructor because it needs the texture manager running.
~BuildTiles()

View file

@ -439,8 +439,6 @@ void JS_InitMirrors(void)
void drawroomstotile(int daposx, int daposy, int daposz,
binangle ang, fixedhoriz horiz, short dacursectnum, short tilenume, double smoothratio)
{
TileFiles.MakeCanvas(tilenume, tileWidth(tilenume), tileHeight(tilenume));
auto canvas = renderSetTarget(tilenume);
if (!canvas) return;