1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-13 01:20:34 +02:00

Fixed loading of flipped and duplicate images in animations

This commit is contained in:
Ivan Savenko
2024-07-16 19:51:00 +00:00
parent 73e052b1d0
commit 81c7c0ce24
5 changed files with 34 additions and 25 deletions

View File

@ -28,7 +28,7 @@ bool CAnimation::loadFrame(size_t frame, size_t group)
if(auto image = getImageImpl(frame, group, false)) if(auto image = getImageImpl(frame, group, false))
return true; return true;
std::shared_ptr<IImage> image = GH.renderHandler().loadImage(source[group][frame], mode); std::shared_ptr<IImage> image = GH.renderHandler().loadImage(getImageLocator(frame, group), mode);
if(image) if(image)
{ {
@ -109,19 +109,7 @@ CAnimation::~CAnimation() = default;
void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup) void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup)
{ {
if(!source.count(sourceGroup)) ImageLocator clone(getImageLocator(sourceFrame, sourceGroup));
{
logAnim->error("Group %d missing in %s", sourceGroup, name.getName());
return;
}
if(source[sourceGroup].size() <= sourceFrame)
{
logAnim->error("Frame [%d %d] missing in %s", sourceGroup, sourceFrame, name.getName());
return;
}
ImageLocator clone(source[sourceGroup][sourceFrame]);
source[targetGroup].push_back(clone); source[targetGroup].push_back(clone);
} }
@ -179,8 +167,9 @@ void CAnimation::horizontalFlip(size_t frame, size_t group)
// ignore - image not loaded // ignore - image not loaded
} }
ImageLocator & locator = source.at(group).at(frame); auto locator = getImageLocator(frame, group);
locator.horizontalFlip = !locator.horizontalFlip; locator.horizontalFlip = !locator.horizontalFlip;
source[group][frame] = locator;
} }
void CAnimation::verticalFlip(size_t frame, size_t group) void CAnimation::verticalFlip(size_t frame, size_t group)
@ -194,8 +183,9 @@ void CAnimation::verticalFlip(size_t frame, size_t group)
// ignore - image not loaded // ignore - image not loaded
} }
ImageLocator & locator = source.at(group).at(frame); auto locator = getImageLocator(frame, group);
locator.verticalFlip = !locator.verticalFlip; locator.verticalFlip = !locator.verticalFlip;
source[group][frame] = locator;
} }
void CAnimation::playerColored(PlayerColor player) void CAnimation::playerColored(PlayerColor player)
@ -213,3 +203,13 @@ void CAnimation::createFlippedGroup(const size_t sourceGroup, const size_t targe
verticalFlip(frame, targetGroup); verticalFlip(frame, targetGroup);
} }
} }
ImageLocator CAnimation::getImageLocator(size_t frame, size_t group) const
{
const ImageLocator & locator = source.at(group).at(frame);
if (!locator.empty())
return locator;
return ImageLocator(name, frame, group);
}

View File

@ -50,6 +50,8 @@ private:
void printError(size_t frame, size_t group, std::string type) const; void printError(size_t frame, size_t group, std::string type) const;
std::shared_ptr<IImage> getImageImpl(size_t frame, size_t group=0, bool verbose=true); std::shared_ptr<IImage> getImageImpl(size_t frame, size_t group=0, bool verbose=true);
ImageLocator getImageLocator(size_t frame, size_t group) const;
public: public:
CAnimation(const AnimationPath & Name, std::map<size_t, std::vector <ImageLocator> > layout, EImageBlitMode mode); CAnimation(const AnimationPath & Name, std::map<size_t, std::vector <ImageLocator> > layout, EImageBlitMode mode);
~CAnimation(); ~CAnimation();

View File

@ -49,3 +49,8 @@ bool ImageLocator::operator<(const ImageLocator & other) const
return verticalFlip < other.verticalFlip; return verticalFlip < other.verticalFlip;
return horizontalFlip < other.horizontalFlip; return horizontalFlip < other.horizontalFlip;
} }
bool ImageLocator::empty() const
{
return !image.has_value() && !defFile.has_value();
}

View File

@ -22,8 +22,10 @@ struct ImageLocator
bool horizontalFlip = false; bool horizontalFlip = false;
ImageLocator() = default; ImageLocator() = default;
ImageLocator(const JsonNode & config);
ImageLocator(const ImagePath & path);
ImageLocator(const AnimationPath & path, int frame, int group); ImageLocator(const AnimationPath & path, int frame, int group);
explicit ImageLocator(const JsonNode & config);
explicit ImageLocator(const ImagePath & path);
bool operator < (const ImageLocator & other) const; bool operator < (const ImageLocator & other) const;
bool empty() const;
}; };

View File

@ -68,7 +68,7 @@ void RenderHandler::initFromJson(AnimationLayoutMap & source, const JsonNode & c
JsonNode toAdd; JsonNode toAdd;
JsonUtils::inherit(toAdd, base); JsonUtils::inherit(toAdd, base);
toAdd["file"].String() = basepath + frame.String(); toAdd["file"].String() = basepath + frame.String();
source[groupID].push_back(toAdd); source[groupID].push_back(ImageLocator(toAdd));
} }
} }
@ -83,7 +83,7 @@ void RenderHandler::initFromJson(AnimationLayoutMap & source, const JsonNode & c
JsonNode toAdd; JsonNode toAdd;
JsonUtils::inherit(toAdd, base); JsonUtils::inherit(toAdd, base);
toAdd["file"].String() = basepath + node["file"].String(); toAdd["file"].String() = basepath + node["file"].String();
source[group][frame] = toAdd; source[group][frame] = ImageLocator(toAdd);
} }
} }
@ -141,10 +141,10 @@ std::shared_ptr<IConstImage> RenderHandler::loadImageFromAnimationFileUncached(c
if (frame >= layout.at(group).size()) if (frame >= layout.at(group).size())
return loadImageFromSingleFile(ImagePath::builtin("DEFAULT")); return loadImageFromSingleFile(ImagePath::builtin("DEFAULT"));
const auto & config = layout.at(group).at(frame); const auto & locator = layout.at(group).at(frame);
if (config.image) if (locator.image)
{ {
return loadImageImpl(ImageLocator(config)); return loadImageImpl(locator);
} }
else else
{ {
@ -168,7 +168,7 @@ std::shared_ptr<IConstImage> RenderHandler::loadImageImpl(const ImageLocator & l
std::shared_ptr<IConstImage> result; std::shared_ptr<IConstImage> result;
if (!locator.image) if (locator.image)
result = loadImageFromSingleFile(*locator.image); result = loadImageFromSingleFile(*locator.image);
else if (locator.defFile) else if (locator.defFile)
result = loadImageFromAnimationFile(*locator.defFile, locator.defFrame, locator.defGroup); result = loadImageFromAnimationFile(*locator.defFile, locator.defFrame, locator.defGroup);
@ -228,7 +228,7 @@ void RenderHandler::addImageListEntries(const EntityService * service)
if (index >= layout[group].size()) if (index >= layout[group].size())
layout[group].resize(index + 1); layout[group].resize(index + 1);
layout[group][index] = entry; layout[group][index] = ImageLocator(entry);
}); });
}); });
} }