diff --git a/Client/mods/deathmatch/logic/CPlayerMap.cpp b/Client/mods/deathmatch/logic/CPlayerMap.cpp index 66678246bd..0653477e5b 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.cpp +++ b/Client/mods/deathmatch/logic/CPlayerMap.cpp @@ -27,6 +27,8 @@ constexpr std::array MAP_IMAGE_SIZES = {1024, 2048}; CPlayerMap::CPlayerMap(CClientManager* pManager) { + m_failedToLoadTextures = false; + // Setup our managers m_pManager = pManager; m_pRadarMarkerManager = pManager->GetRadarMarkerManager(); @@ -55,16 +57,8 @@ CPlayerMap::CPlayerMap(CClientManager* pManager) m_iHorizontalMovement = 0; m_iVerticalMovement = 0; - // Create the local player blip image - m_playerMarkerTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(CalcMTASAPath("MTA\\cgui\\images\\radarset\\02.png")); - - // Create the map image - m_mapImageTexture = nullptr; - m_playerMapImageIndex = g_pCore->GetCVars()->GetValue("mapimage"); - SetMapImage(m_playerMapImageIndex); - - // Create the marker textures - CreateMarkerTextures(); + // Create all map textures + CreateAllTextures(); // Create the text displays for the help text const SColorRGBA colorWhiteTransparent(255, 255, 255, 200); @@ -120,13 +114,61 @@ CPlayerMap::~CPlayerMap() // Don't need to delete the help texts as those are destroyed by the display manager } -void CPlayerMap::SetMapImage(std::size_t imageIndex) +void CPlayerMap::CreateOrUpdateMapTexture() { - std::uint32_t mapSize = MAP_IMAGE_SIZES[imageIndex]; - SString fileName("MTA\\cgui\\images\\map_%d.png", mapSize); + const std::uint32_t mapSize = MAP_IMAGE_SIZES[m_playerMapImageIndex]; + const SString fileName("MTA\\cgui\\images\\map_%d.png", mapSize); + + auto* newTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(CalcMTASAPath(fileName), nullptr, false, mapSize, mapSize, RFORMAT_DXT1); + if (!newTexture) + throw std::runtime_error("Failed to load map image"); SAFE_RELEASE(m_mapImageTexture); - m_mapImageTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(CalcMTASAPath(fileName), nullptr, false, mapSize, mapSize, RFORMAT_DXT1); + m_mapImageTexture = newTexture; +} + +void CPlayerMap::UpdateOrRevertMapTexture(std::size_t newImageIndex) +{ + const std::size_t oldImageIndex = m_playerMapImageIndex; + try + { + m_playerMapImageIndex = newImageIndex; + CreateOrUpdateMapTexture(); + } + catch (const std::exception& e) + { + m_playerMapImageIndex = oldImageIndex; + g_pCore->GetConsole()->Printf("Problem updating map image: %s", e.what()); + } +} + +void CPlayerMap::CreatePlayerBlipTexture() +{ + m_playerMarkerTexture = g_pCore->GetGraphics()->GetRenderItemManager()->CreateTexture(CalcMTASAPath("MTA\\cgui\\images\\radarset\\02.png")); + if (!m_playerMarkerTexture) + throw std::runtime_error("Failed to load player blip image"); +} + +void CPlayerMap::CreateAllTextures() +{ + try + { + // Create the map texture + m_mapImageTexture = nullptr; + m_playerMapImageIndex = g_pCore->GetCVars()->GetValue("mapimage"); + CreateOrUpdateMapTexture(); + + // Create the player blip texture + CreatePlayerBlipTexture(); + + // Create the other marker textures + CreateMarkerTextures(); + } + catch (const std::exception& e) + { + m_failedToLoadTextures = true; + g_pCore->GetConsole()->Printf("Problem initializing player map: %s", e.what()); + } } void CPlayerMap::DoPulse() @@ -173,7 +215,7 @@ void CPlayerMap::DoPulse() // void CPlayerMap::CreateMarkerTextures() { - assert(m_markerTextureList.empty()); + m_markerTextureList.clear(); SString strRadarSetDirectory = CalcMTASAPath("MTA\\cgui\\images\\radarset\\"); // Load the 3 shapes @@ -184,7 +226,8 @@ void CPlayerMap::CreateMarkerTextures() m_markerTextureList.push_back(pTextureItem); } - assert(m_markerTextureList.size() == MARKER_FIRST_SPRITE_INDEX); + if (m_markerTextureList.size() != MARKER_FIRST_SPRITE_INDEX) + throw std::runtime_error("Failed to load marker textures [1]"); // Load the icons for (uint i = 0; i < RADAR_MARKER_LIMIT; i++) @@ -193,7 +236,8 @@ void CPlayerMap::CreateMarkerTextures() m_markerTextureList.push_back(pTextureItem); } - assert(m_markerTextureList.size() == MARKER_LAST_SPRITE_INDEX + 1); + if (m_markerTextureList.size() != MARKER_LAST_SPRITE_INDEX + 1) + throw std::runtime_error("Failed to load marker textures [2]"); } // @@ -245,8 +289,8 @@ void CPlayerMap::DoRender() { bool isMapShowing = IsPlayerMapShowing(); - // Render if showing - if (isMapShowing) + // Render if showing and textures are all loaded + if (isMapShowing && !m_failedToLoadTextures) { // Get the alpha value from the settings int mapAlpha; @@ -257,8 +301,7 @@ void CPlayerMap::DoRender() auto mapImageIndex = g_pCore->GetCVars()->GetValue("mapimage"); if (mapImageIndex != m_playerMapImageIndex) { - m_playerMapImageIndex = mapImageIndex; - SetMapImage(m_playerMapImageIndex); + UpdateOrRevertMapTexture(mapImageIndex); } g_pCore->GetGraphics()->DrawTexture(m_mapImageTexture, static_cast(m_iMapMinX), static_cast(m_iMapMinY), diff --git a/Client/mods/deathmatch/logic/CPlayerMap.h b/Client/mods/deathmatch/logic/CPlayerMap.h index 6db038b927..0d6edebb6f 100644 --- a/Client/mods/deathmatch/logic/CPlayerMap.h +++ b/Client/mods/deathmatch/logic/CPlayerMap.h @@ -42,6 +42,10 @@ class CPlayerMap void CreateMarkerTextures(); CTextureItem* GetMarkerTexture(CClientRadarMarker* pMarker, float fLocalZ, float* pfScale, SColor* pColor); + void CreatePlayerBlipTexture(); + void CreateOrUpdateMapTexture(); + void UpdateOrRevertMapTexture(std::size_t imageIndex); + void CreateAllTextures(); public: bool IsAttachedToLocalPlayer() const { return m_bIsAttachedToLocal; }; @@ -62,8 +66,6 @@ class CPlayerMap void ZoomIn(); void ZoomOut(); - void SetMapImage(std::size_t imageIndex); - SString GetBoundKeyName(const SString& strCommand); private: @@ -81,6 +83,8 @@ class CPlayerMap class CClientRadarMarkerManager* m_pRadarMarkerManager; class CClientRadarAreaManager* m_pRadarAreaManager; + bool m_failedToLoadTextures; + std::size_t m_playerMapImageIndex; CTextureItem* m_mapImageTexture;