From 9b367eac1f951d819d86b994c552da9fc293a04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ja=C5=82ocha?= Date: Sun, 5 Jan 2025 23:56:55 +0100 Subject: [PATCH 1/2] fix: incorrectly aligned looktypes for 32x32 idle sprites --- src/client/thingtype.cpp | 55 ++++++++-------------------------------- 1 file changed, 10 insertions(+), 45 deletions(-) diff --git a/src/client/thingtype.cpp b/src/client/thingtype.cpp index a73b64ce09..90ac2ec4a6 100644 --- a/src/client/thingtype.cpp +++ b/src/client/thingtype.cpp @@ -333,41 +333,6 @@ void ThingType::unserializeAppearance(const uint16_t clientId, const ThingCatego totalSpritesCount += totalSprites; } - if (sizes.size() > 1) { - // correction for some sprites - for (const auto& s : sizes) { - m_size.setWidth(std::max(m_size.width(), s.width())); - m_size.setHeight(std::max(m_size.height(), s.height())); - } - const size_t expectedSize = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases; - if (expectedSize != m_spritesIndex.size()) { - const std::vector sprites(std::move(m_spritesIndex)); - m_spritesIndex.clear(); - m_spritesIndex.reserve(expectedSize); - for (size_t i = 0, idx = 0; i < sizes.size(); ++i) { - const int totalSprites = total_sprites[i]; - if (m_size == sizes[i]) { - for (int j = 0; j < totalSprites; ++j) { - m_spritesIndex.push_back(sprites[idx++]); - } - continue; - } - const size_t patterns = (totalSprites / sizes[i].area()); - for (size_t p = 0; p < patterns; ++p) { - for (int x = 0; x < m_size.width(); ++x) { - for (int y = 0; y < m_size.height(); ++y) { - if (x < sizes[i].width() && y < sizes[i].height()) { - m_spritesIndex.push_back(sprites[idx++]); - continue; - } - m_spritesIndex.push_back(0); - } - } - } - } - } - } - prepareTextureLoad(sizes, total_sprites); } @@ -596,9 +561,7 @@ void ThingType::prepareTextureLoad(const std::vector& sizes, const std::ve for (int y = 0; y < m_size.height(); ++y) { if (x < sizes[i].width() && y < sizes[i].height()) { m_spritesIndex.push_back(sprites[idx++]); - continue; } - m_spritesIndex.push_back(0); } } } @@ -752,20 +715,22 @@ void ThingType::loadTexture(const int animationPhase) if (protobufSupported) { const uint32_t spriteIndex = getSpriteIndex(-1, -1, spriteMask ? 1 : l, x, y, z, animationPhase); const auto& spriteImage = g_sprites.getSpriteImage(m_spritesIndex[spriteIndex]); - if (!spriteImage) { - continue; - } // verifies that the first block in the lower right corner is transparent. - if (spriteImage->hasTransparentPixel()) { + if (!spriteImage || spriteImage->hasTransparentPixel()) { fullImage->setTransparentPixel(true); } - if (spriteMask) { - spriteImage->overwriteMask(maskColors[(l - 1)]); - } + if (spriteImage) { + if (spriteMask) { + spriteImage->overwriteMask(maskColors[(l - 1)]); + } - fullImage->blit(framePos, spriteImage); + auto spriteSize = spriteImage->getSize() / g_gameConfig.getSpriteSize(); + + const Point& spritePos = Point(m_size.width() - spriteSize.width(), m_size.height() - spriteSize.height()) * g_gameConfig.getSpriteSize(); + fullImage->blit(framePos + spritePos, spriteImage); + } } else { for (int h = 0; h < m_size.height(); ++h) { for (int w = 0; w < m_size.width(); ++w) { From 74beefbf9661f2e2a57e5e170bda31e547da678a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Ja=C5=82ocha?= Date: Mon, 6 Jan 2025 12:00:48 +0100 Subject: [PATCH 2/2] Remove redundant correction algorithm --- src/client/thingtype.cpp | 52 +--------------------------------------- src/client/thingtype.h | 2 -- 2 files changed, 1 insertion(+), 53 deletions(-) diff --git a/src/client/thingtype.cpp b/src/client/thingtype.cpp index 90ac2ec4a6..7dcd376bd4 100644 --- a/src/client/thingtype.cpp +++ b/src/client/thingtype.cpp @@ -285,9 +285,6 @@ void ThingType::unserializeAppearance(const uint16_t clientId, const ThingCatego m_animationPhases = 0; int totalSpritesCount = 0; - std::vector sizes; - std::vector total_sprites; - for (const auto& framegroup : appearance.frame_group()) { const int frameGroupType = framegroup.fixed_frame_group(); const auto& spriteInfo = framegroup.sprite_info(); @@ -305,7 +302,6 @@ void ThingType::unserializeAppearance(const uint16_t clientId, const ThingCatego if (const auto& sheet = g_spriteAppearances.getSheetBySpriteId(spriteInfo.sprite_id(0), false)) { m_size = sheet->getSpriteSize() / g_gameConfig.getSpriteSize(); - sizes.emplace_back(m_size); } // animations @@ -320,7 +316,6 @@ void ThingType::unserializeAppearance(const uint16_t clientId, const ThingCatego } const int totalSprites = m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * std::max(1, spritesPhases.size()); - total_sprites.push_back(totalSprites); if (totalSpritesCount + totalSprites > 4096) throw Exception("a thing type has more than 4096 sprites"); @@ -333,7 +328,7 @@ void ThingType::unserializeAppearance(const uint16_t clientId, const ThingCatego totalSpritesCount += totalSprites; } - prepareTextureLoad(sizes, total_sprites); + m_textureData.resize(m_animationPhases); } void ThingType::unserialize(const uint16_t clientId, const ThingCategory category, const FileStreamPtr& fin) @@ -482,9 +477,6 @@ void ThingType::unserialize(const uint16_t clientId, const ThingCategory categor m_animationPhases = 0; int totalSpritesCount = 0; - std::vector sizes; - std::vector total_sprites; - for (int i = 0; i < groupCount; ++i) { uint8_t frameGroupType = FrameGroupDefault; if (hasFrameGroups) @@ -493,7 +485,6 @@ void ThingType::unserialize(const uint16_t clientId, const ThingCategory categor const uint8_t width = fin->getU8(); const uint8_t height = fin->getU8(); m_size = { width, height }; - sizes.emplace_back(m_size); if (width > 1 || height > 1) { m_realSize = fin->getU8(); } @@ -520,53 +511,12 @@ void ThingType::unserialize(const uint16_t clientId, const ThingCategory categor } const int totalSprites = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * groupAnimationsPhases; - total_sprites.push_back(totalSprites); - if (totalSpritesCount + totalSprites > 4096) throw Exception("a thing type has more than 4096 sprites"); m_spritesIndex.resize(totalSpritesCount + totalSprites); for (int j = totalSpritesCount; j < (totalSpritesCount + totalSprites); ++j) m_spritesIndex[j] = g_game.getFeature(Otc::GameSpritesU32) ? fin->getU32() : fin->getU16(); - - totalSpritesCount += totalSprites; - } - - prepareTextureLoad(sizes, total_sprites); -} - -void ThingType::prepareTextureLoad(const std::vector& sizes, const std::vector& total_sprites) { - if (sizes.size() > 1) { - // correction for some sprites - for (const auto& s : sizes) { - m_size.setWidth(std::max(m_size.width(), s.width())); - m_size.setHeight(std::max(m_size.height(), s.height())); - } - const size_t expectedSize = m_size.area() * m_layers * m_numPatternX * m_numPatternY * m_numPatternZ * m_animationPhases; - if (expectedSize != m_spritesIndex.size()) { - const std::vector sprites(std::move(m_spritesIndex)); - m_spritesIndex.clear(); - m_spritesIndex.reserve(expectedSize); - for (size_t i = 0, idx = 0; i < sizes.size(); ++i) { - const int totalSprites = total_sprites[i]; - if (m_size == sizes[i]) { - for (int j = 0; j < totalSprites; ++j) { - m_spritesIndex.push_back(sprites[idx++]); - } - continue; - } - const size_t patterns = (totalSprites / sizes[i].area()); - for (size_t p = 0; p < patterns; ++p) { - for (int x = 0; x < m_size.width(); ++x) { - for (int y = 0; y < m_size.height(); ++y) { - if (x < sizes[i].width() && y < sizes[i].height()) { - m_spritesIndex.push_back(sprites[idx++]); - } - } - } - } - } - } } m_textureData.resize(m_animationPhases); diff --git a/src/client/thingtype.h b/src/client/thingtype.h index 0fc41ad8cc..c85785d439 100644 --- a/src/client/thingtype.h +++ b/src/client/thingtype.h @@ -476,8 +476,6 @@ class ThingType final : public LuaObject std::vector pos; }; - void prepareTextureLoad(const std::vector& sizes, const std::vector& total_sprites); - uint32_t getSpriteIndex(int w, int h, int l, int x, int y, int z, int a) const; uint32_t getTextureIndex(int l, int x, int y, int z) const;