From 38b60b1d5115e16790225fb32dba221174d6ff6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20M=C3=BCller?= Date: Sat, 10 Aug 2024 17:35:18 +0200 Subject: [PATCH] Various refactoring of 0.7 skin loading - Only log successful log messages when `debug` is enabled, consistent with logging for regular skins. - Use `IsImageFormatRgba` to check for RGBA image format, so this also shows a warning popup. - Remove redundant logic for non-RGBA image data. - Use `CheckImageDivisibility` instead of enforcing exact size of xmas hat and bot decoration images to allow higher resolution images. - Fix image data not being freed if it has the wrong format or ratio. - Fix potential integer overflow when calculating skin part blood color (same as for regular skins). - Extract `LoadXmasHat` and `LoadBotDecoration` functions for readability. --- src/game/client/components/skins.cpp | 2 +- src/game/client/components/skins7.cpp | 92 +++++++++++++++------------ src/game/client/components/skins7.h | 3 + 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp index efb2f7ac1..e774ad94d 100644 --- a/src/game/client/components/skins.cpp +++ b/src/game/client/components/skins.cpp @@ -298,7 +298,7 @@ const CSkin *CSkins::LoadSkin(const char *pName, CImageInfo &Info) if(g_Config.m_Debug) { - log_trace("skins", "Loaded skin %s", Skin.GetName()); + log_trace("skins", "Loaded skin '%s'", Skin.GetName()); } auto &&pSkin = std::make_unique(std::move(Skin)); diff --git a/src/game/client/components/skins7.cpp b/src/game/client/components/skins7.cpp index 2b19f52ad..a1cae75fb 100644 --- a/src/game/client/components/skins7.cpp +++ b/src/game/client/components/skins7.cpp @@ -57,16 +57,17 @@ int CSkins7::SkinPartScan(const char *pName, int IsDir, int DirType, void *pUser log_error("skins7", "Failed to load skin part '%s'", pName); return 0; } - if(Info.m_Format != CImageInfo::FORMAT_RGBA) + if(!pSelf->Graphics()->IsImageFormatRgba(aFilename, Info)) { log_error("skins7", "Failed to load skin part '%s': must be RGBA format", pName); + Info.Free(); return 0; } Part.m_OrgTexture = pSelf->Graphics()->LoadTextureRaw(Info, 0, aFilename); Part.m_BloodColor = ColorRGBA(1.0f, 1.0f, 1.0f); - int Step = Info.m_Format == CImageInfo::FORMAT_RGBA ? 4 : 3; + const int Step = 4; unsigned char *pData = (unsigned char *)Info.m_pData; // dig out blood color @@ -78,7 +79,7 @@ int CSkins7::SkinPartScan(const char *pName, int IsDir, int DirType, void *pUser int PartWidth = Info.m_Width / 2; int PartHeight = Info.m_Height / 2; - int aColors[3] = {0}; + int64_t aColors[3] = {0}; for(int y = PartY; y < PartY + PartHeight; y++) for(int x = PartX; x < PartX + PartWidth; x++) if(pData[y * Pitch + x * Step + 3] > 128) @@ -105,7 +106,11 @@ int CSkins7::SkinPartScan(const char *pName, int IsDir, int DirType, void *pUser Part.m_Flags |= SKINFLAG_SPECIAL; if(DirType != IStorage::TYPE_SAVE) Part.m_Flags |= SKINFLAG_STANDARD; - log_debug("skins7", "load skin part %s", Part.m_aName); + + if(pSelf->Config()->m_Debug) + { + log_trace("skins7", "Loaded skin part '%s'", Part.m_aName); + } pSelf->m_avSkinParts[pSelf->m_ScanningPart].emplace_back(Part); return 0; @@ -206,9 +211,10 @@ int CSkins7::SkinScan(const char *pName, int IsDir, int DirType, void *pUser) Skin.m_Flags = SpecialSkin ? SKINFLAG_SPECIAL : 0; if(DirType != IStorage::TYPE_SAVE) Skin.m_Flags |= SKINFLAG_STANDARD; + if(pSelf->Config()->m_Debug) { - log_debug("skins7", "load skin %s", Skin.m_aName); + log_trace("skins7", "Loaded skin '%s'", Skin.m_aName); } pSelf->m_vSkins.insert(std::lower_bound(pSelf->m_vSkins.begin(), pSelf->m_vSkins.end(), Skin), Skin); @@ -322,45 +328,51 @@ void CSkins7::OnInit() if(m_vSkins.empty()) m_vSkins.emplace_back(m_DummySkin); - { - // add xmas hat - const char *pFileName = SKINS_DIR "/xmas_hat.png"; - CImageInfo Info; - if(!Graphics()->LoadPng(Info, pFileName, IStorage::TYPE_ALL) || Info.m_Width != 128 || Info.m_Height != 512) - { - char aBuf[128]; - str_format(aBuf, sizeof(aBuf), "failed to load xmas hat '%s'", pFileName); - Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "skins7", aBuf); - } - else - { - char aBuf[128]; - str_format(aBuf, sizeof(aBuf), "loaded xmas hat '%s'", pFileName); - Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "skins7", aBuf); - m_XmasHatTexture = Graphics()->LoadTextureRawMove(Info, 0, pFileName); - } - } + LoadXmasHat(); + LoadBotDecoration(); GameClient()->m_Menus.RenderLoading(Localize("Loading DDNet Client"), Localize("Loading skin files"), 0); +} +void CSkins7::LoadXmasHat() +{ + const char *pFilename = SKINS_DIR "/xmas_hat.png"; + CImageInfo Info; + if(!Graphics()->LoadPng(Info, pFilename, IStorage::TYPE_ALL) || + !Graphics()->IsImageFormatRgba(pFilename, Info) || + !Graphics()->CheckImageDivisibility(pFilename, Info, 1, 4, false)) { - // add bot decoration - const char *pFileName = SKINS_DIR "/bot.png"; - CImageInfo Info; - if(!Graphics()->LoadPng(Info, pFileName, IStorage::TYPE_ALL) || Info.m_Width != 384 || Info.m_Height != 160) - { - char aBuf[128]; - str_format(aBuf, sizeof(aBuf), "failed to load bot '%s'", pFileName); - Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "skins7", aBuf); - } - else - { - char aBuf[128]; - str_format(aBuf, sizeof(aBuf), "loaded bot '%s'", pFileName); - Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "skins7", aBuf); - m_BotTexture = Graphics()->LoadTextureRawMove(Info, 0, pFileName); - } + log_error("skins7", "Failed to xmas hat '%s'", pFilename); + Info.Free(); + } + else + { + if(Config()->m_Debug) + { + log_trace("skins7", "Loaded xmas hat '%s'", pFilename); + } + m_XmasHatTexture = Graphics()->LoadTextureRawMove(Info, 0, pFilename); + } +} + +void CSkins7::LoadBotDecoration() +{ + const char *pFilename = SKINS_DIR "/bot.png"; + CImageInfo Info; + if(!Graphics()->LoadPng(Info, pFilename, IStorage::TYPE_ALL) || + !Graphics()->IsImageFormatRgba(pFilename, Info) || + !Graphics()->CheckImageDivisibility(pFilename, Info, 12, 5, false)) + { + log_error("skins7", "Failed to load bot '%s'", pFilename); + Info.Free(); + } + else + { + if(Config()->m_Debug) + { + log_trace("skins7", "Loaded bot '%s'", pFilename); + } + m_BotTexture = Graphics()->LoadTextureRawMove(Info, 0, pFilename); } - GameClient()->m_Menus.RenderLoading(Localize("Loading DDNet Client"), Localize("Loading skin files"), 0); } void CSkins7::AddSkin(const char *pSkinName, int Dummy) diff --git a/src/game/client/components/skins7.h b/src/game/client/components/skins7.h index 4809a76e4..49c06ad82 100644 --- a/src/game/client/components/skins7.h +++ b/src/game/client/components/skins7.h @@ -92,6 +92,9 @@ private: static int SkinPartScan(const char *pName, int IsDir, int DirType, void *pUser); static int SkinScan(const char *pName, int IsDir, int DirType, void *pUser); + + void LoadXmasHat(); + void LoadBotDecoration(); }; #endif