From ab3445967dd130bc586b9b54350de63fff5febc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 14 Feb 2024 23:41:16 +0100 Subject: [PATCH 1/2] Fix assertion due to double-free of transparent texture The transparent texture is reused for multiple entity layers and should never be unloaded. --- src/game/client/components/mapimages.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp index 0c05a6102..3f0dffed7 100644 --- a/src/game/client/components/mapimages.cpp +++ b/src/game/client/components/mapimages.cpp @@ -395,8 +395,10 @@ void CMapImages::ChangeEntitiesPath(const char *pPath) { for(int n = 0; n < MAP_IMAGE_ENTITY_LAYER_TYPE_COUNT; ++n) { - if(m_aaEntitiesTextures[i][n].IsValid()) + if(m_aaEntitiesTextures[i][n].IsValid() && m_aaEntitiesTextures[i][n].Id() != m_TransparentTexture.Id()) + { Graphics()->UnloadTexture(&(m_aaEntitiesTextures[i][n])); + } m_aaEntitiesTextures[i][n] = IGraphics::CTextureHandle(); } From fdf427db15f5b93da3bd8043ced23c04934ecc62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Wed, 14 Feb 2024 22:42:08 +0100 Subject: [PATCH 2/2] Fix entities textures not being built for non-DDNet/DDRace types The combined entities texture for all layers except the switch layer was only built when the gametype has a front, speedup, tele or tune layer, which is only the case for servers declaring DDNet or DDRace type in their gameinfo. Now this entities layer is always built, as the game layer is always present. --- src/game/client/components/mapimages.cpp | 39 +----------------------- src/game/client/components/mapimages.h | 6 ---- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/src/game/client/components/mapimages.cpp b/src/game/client/components/mapimages.cpp index 3f0dffed7..f96209fe5 100644 --- a/src/game/client/components/mapimages.cpp +++ b/src/game/client/components/mapimages.cpp @@ -158,31 +158,6 @@ void CMapImages::LoadBackground(class CLayers *pLayers, class IMap *pMap) OnMapLoadImpl(pLayers, pMap); } -bool CMapImages::HasFrontLayer(EMapImageModType ModType) -{ - return ModType == MAP_IMAGE_MOD_TYPE_DDNET || ModType == MAP_IMAGE_MOD_TYPE_DDRACE; -} - -bool CMapImages::HasSpeedupLayer(EMapImageModType ModType) -{ - return ModType == MAP_IMAGE_MOD_TYPE_DDNET || ModType == MAP_IMAGE_MOD_TYPE_DDRACE; -} - -bool CMapImages::HasSwitchLayer(EMapImageModType ModType) -{ - return ModType == MAP_IMAGE_MOD_TYPE_DDNET || ModType == MAP_IMAGE_MOD_TYPE_DDRACE; -} - -bool CMapImages::HasTeleLayer(EMapImageModType ModType) -{ - return ModType == MAP_IMAGE_MOD_TYPE_DDNET || ModType == MAP_IMAGE_MOD_TYPE_DDRACE; -} - -bool CMapImages::HasTuneLayer(EMapImageModType ModType) -{ - return ModType == MAP_IMAGE_MOD_TYPE_DDNET || ModType == MAP_IMAGE_MOD_TYPE_DDRACE; -} - IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType EntityLayerType) { EMapImageModType EntitiesModType = MAP_IMAGE_MOD_TYPE_DDNET; @@ -207,18 +182,9 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit { m_aEntitiesIsLoaded[(EntitiesModType * 2) + (int)EntitiesAreMasked] = true; - // any mod that does not mask, will get all layers unmasked - bool WasUnknown = !EntitiesAreMasked; - char aPath[64]; str_format(aPath, sizeof(aPath), "%s/%s.png", m_aEntitiesPath, gs_apModEntitiesNames[EntitiesModType]); - bool GameTypeHasFrontLayer = HasFrontLayer(EntitiesModType) || WasUnknown; - bool GameTypeHasSpeedupLayer = HasSpeedupLayer(EntitiesModType) || WasUnknown; - bool GameTypeHasSwitchLayer = HasSwitchLayer(EntitiesModType) || WasUnknown; - bool GameTypeHasTeleLayer = HasTeleLayer(EntitiesModType) || WasUnknown; - bool GameTypeHasTuneLayer = HasTuneLayer(EntitiesModType) || WasUnknown; - int TextureLoadFlag = 0; if(Graphics()->HasTextureArraysSupport()) TextureLoadFlag = (Graphics()->Uses2DTextureArrays() ? IGraphics::TEXLOAD_TO_2D_ARRAY_TEXTURE : IGraphics::TEXLOAD_TO_3D_TEXTURE) | IGraphics::TEXLOAD_NO_2D_TEXTURE; @@ -264,10 +230,7 @@ IGraphics::CTextureHandle CMapImages::GetEntities(EMapImageEntityLayerType Entit for(int n = 0; n < MAP_IMAGE_ENTITY_LAYER_TYPE_COUNT; ++n) { bool BuildThisLayer = true; - if(n == MAP_IMAGE_ENTITY_LAYER_TYPE_ALL_EXCEPT_SWITCH && !GameTypeHasFrontLayer && - !GameTypeHasSpeedupLayer && !GameTypeHasTeleLayer && !GameTypeHasTuneLayer) - BuildThisLayer = false; - else if(n == MAP_IMAGE_ENTITY_LAYER_TYPE_SWITCH && !GameTypeHasSwitchLayer) + if(n == MAP_IMAGE_ENTITY_LAYER_TYPE_SWITCH && EntitiesModType != MAP_IMAGE_MOD_TYPE_DDNET && EntitiesModType != MAP_IMAGE_MOD_TYPE_DDRACE) BuildThisLayer = false; dbg_assert(!m_aaEntitiesTextures[(EntitiesModType * 2) + (int)EntitiesAreMasked][n].IsValid(), "entities texture already loaded when it should not be"); diff --git a/src/game/client/components/mapimages.h b/src/game/client/components/mapimages.h index 66bd83df5..3f147b541 100644 --- a/src/game/client/components/mapimages.h +++ b/src/game/client/components/mapimages.h @@ -42,12 +42,6 @@ class CMapImages : public CComponent char m_aEntitiesPath[IO_MAX_PATH_LENGTH]; - bool HasFrontLayer(EMapImageModType ModType); - bool HasSpeedupLayer(EMapImageModType ModType); - bool HasSwitchLayer(EMapImageModType ModType); - bool HasTeleLayer(EMapImageModType ModType); - bool HasTuneLayer(EMapImageModType ModType); - public: CMapImages(); CMapImages(int TextureSize);