1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-13 11:40:38 +02:00

Fix loading of pre-scaled assets

This commit is contained in:
Ivan Savenko 2025-01-17 12:17:29 +00:00
parent 668bf63fc0
commit c9dd3dab5d
5 changed files with 50 additions and 44 deletions

View File

@ -33,7 +33,7 @@ void CanvasImage::draw(SDL_Surface * where, const Point & pos, const Rect * src,
void CanvasImage::scaleTo(const Point & size, EScalingAlgorithm algorithm) void CanvasImage::scaleTo(const Point & size, EScalingAlgorithm algorithm)
{ {
Point scaledSize = scalingPolicy == CanvasScalingPolicy::IGNORE ? size : (size * GH.screenHandler().getScalingFactor()); Point scaledSize = size * GH.screenHandler().getScalingFactor();
auto newSurface = CSDL_Ext::scaleSurface(surface, scaledSize.x, scaledSize.y, algorithm); auto newSurface = CSDL_Ext::scaleSurface(surface, scaledSize.x, scaledSize.y, algorithm);
SDL_FreeSurface(surface); SDL_FreeSurface(surface);

View File

@ -39,8 +39,8 @@ public:
virtual std::shared_ptr<IImage> loadImage(const ImagePath & path, EImageBlitMode mode) = 0; virtual std::shared_ptr<IImage> loadImage(const ImagePath & path, EImageBlitMode mode) = 0;
virtual std::shared_ptr<IImage> loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode) = 0; virtual std::shared_ptr<IImage> loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode) = 0;
/// Loads single image without scaling support /// Loads single upscaled image without auto-scaling support
virtual std::shared_ptr<SDLImageShared> loadSingleImage(const ImageLocator & locator) = 0; virtual std::shared_ptr<SDLImageShared> loadScaledImage(const ImageLocator & locator) = 0;
/// Creates image which can be used as target for drawing on /// Creates image which can be used as target for drawing on
virtual std::shared_ptr<CanvasImage> createImage(const Point & size, CanvasScalingPolicy scalingPolicy) = 0; virtual std::shared_ptr<CanvasImage> createImage(const Point & size, CanvasScalingPolicy scalingPolicy) = 0;

View File

@ -158,14 +158,14 @@ int RenderHandler::getScalingFactor() const
return GH.screenHandler().getScalingFactor(); return GH.screenHandler().getScalingFactor();
} }
ImageLocator RenderHandler::getLocatorForAnimationFrame(const AnimationPath & path, int frame, int group, EImageBlitMode mode) ImageLocator RenderHandler::getLocatorForAnimationFrame(const AnimationPath & path, int frame, int group, int scaling, EImageBlitMode mode)
{ {
const auto & layout = getAnimationLayout(path, 1, mode); const auto & layout = getAnimationLayout(path, scaling, mode);
if (!layout.count(group)) if (!layout.count(group))
return ImageLocator(ImagePath::builtin("DEFAULT"), mode); return ImageLocator();
if (frame >= layout.at(group).size()) if (frame >= layout.at(group).size())
return ImageLocator(ImagePath::builtin("DEFAULT"), mode); return ImageLocator();
const auto & locator = layout.at(group).at(frame); const auto & locator = layout.at(group).at(frame);
if (locator.image || locator.defFile) if (locator.image || locator.defFile)
@ -216,9 +216,9 @@ void RenderHandler::storeCachedImage(const ImageLocator & locator, std::shared_p
imageFiles[locator] = image; imageFiles[locator] = image;
} }
std::shared_ptr<SDLImageShared> RenderHandler::loadSingleImage(const ImageLocator & locator) std::shared_ptr<SDLImageShared> RenderHandler::loadScaledImage(const ImageLocator & locator)
{ {
assert(locator.scalingFactor != 0); assert(locator.scalingFactor > 1);
static constexpr std::array scaledDataPath = { static constexpr std::array scaledDataPath = {
"", // 0x "", // 0x
@ -236,40 +236,43 @@ std::shared_ptr<SDLImageShared> RenderHandler::loadSingleImage(const ImageLocato
"SPRITES4X/", "SPRITES4X/",
}; };
if(locator.image) ImagePath pathToLoad;
{
std::string imagePathString = locator.image->getName();
if(locator.layer == EImageBlitMode::ONLY_OVERLAY)
imagePathString += "-OVERLAY";
if(locator.layer == EImageBlitMode::ONLY_SHADOW)
imagePathString += "-SHADOW";
auto imagePath = ImagePath::builtin(imagePathString);
auto imagePathSprites = ImagePath::builtin(imagePathString).addPrefix(scaledSpritesPath.at(locator.scalingFactor));
auto imagePathData = ImagePath::builtin(imagePathString).addPrefix(scaledDataPath.at(locator.scalingFactor));
if(CResourceHandler::get()->existsResource(imagePathSprites))
return std::make_shared<SDLImageShared>(imagePathSprites);
if(CResourceHandler::get()->existsResource(imagePathData))
return std::make_shared<SDLImageShared>(imagePathData);
if(CResourceHandler::get()->existsResource(imagePath))
return std::make_shared<SDLImageShared>(imagePath);
}
if(locator.defFile) if(locator.defFile)
{ {
AnimationPath defFilePath = locator.defFile->addPrefix(scaledSpritesPath.at(locator.scalingFactor)); auto remappedLocator = getLocatorForAnimationFrame(*locator.defFile, locator.defFrame, locator.defGroup, locator.scalingFactor, locator.layer);
auto defFile = getAnimationFile(defFilePath); // we expect that .def's are only used for 1x data, upscaled assets should use standalone images
if (!remappedLocator.image)
return nullptr;
if(defFile && defFile->hasFrame(locator.defFrame, locator.defGroup)) pathToLoad = *remappedLocator.image;
{
return std::make_shared<SDLImageShared>(defFile.get(), locator.defFrame, locator.defGroup);
}
} }
if(!locator.image)
return nullptr;
pathToLoad = *locator.image;
std::string imagePathString = pathToLoad.getName();
if(locator.layer == EImageBlitMode::ONLY_OVERLAY)
imagePathString += "-OVERLAY";
if(locator.layer == EImageBlitMode::ONLY_SHADOW)
imagePathString += "-SHADOW";
auto imagePath = ImagePath::builtin(imagePathString);
auto imagePathSprites = ImagePath::builtin(imagePathString).addPrefix(scaledSpritesPath.at(locator.scalingFactor));
auto imagePathData = ImagePath::builtin(imagePathString).addPrefix(scaledDataPath.at(locator.scalingFactor));
if(CResourceHandler::get()->existsResource(imagePathSprites))
return std::make_shared<SDLImageShared>(imagePathSprites);
if(CResourceHandler::get()->existsResource(imagePathData))
return std::make_shared<SDLImageShared>(imagePathData);
if(CResourceHandler::get()->existsResource(imagePath))
return std::make_shared<SDLImageShared>(imagePath);
return nullptr; return nullptr;
} }
@ -299,8 +302,11 @@ std::shared_ptr<IImage> RenderHandler::loadImage(const ImageLocator & locator)
std::shared_ptr<IImage> RenderHandler::loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode) std::shared_ptr<IImage> RenderHandler::loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode)
{ {
ImageLocator locator = getLocatorForAnimationFrame(path, frame, group, mode); ImageLocator locator = getLocatorForAnimationFrame(path, frame, group, 1, mode);
return loadImage(locator); if (!locator.empty())
return loadImage(locator);
else
return loadImage(ImageLocator(ImagePath::builtin("DEFAULT"), mode));
} }
std::shared_ptr<IImage> RenderHandler::loadImage(const ImagePath & path, EImageBlitMode mode) std::shared_ptr<IImage> RenderHandler::loadImage(const ImagePath & path, EImageBlitMode mode)

View File

@ -40,7 +40,7 @@ class RenderHandler : public IRenderHandler
std::shared_ptr<SDLImageShared> loadImageFromFileUncached(const ImageLocator & locator); std::shared_ptr<SDLImageShared> loadImageFromFileUncached(const ImageLocator & locator);
ImageLocator getLocatorForAnimationFrame(const AnimationPath & path, int frame, int group, EImageBlitMode mode); ImageLocator getLocatorForAnimationFrame(const AnimationPath & path, int frame, int group, int scaling, EImageBlitMode mode);
int getScalingFactor() const; int getScalingFactor() const;
@ -53,7 +53,7 @@ public:
std::shared_ptr<IImage> loadImage(const ImagePath & path, EImageBlitMode mode) override; std::shared_ptr<IImage> loadImage(const ImagePath & path, EImageBlitMode mode) override;
std::shared_ptr<IImage> loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode) override; std::shared_ptr<IImage> loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode) override;
std::shared_ptr<SDLImageShared> loadSingleImage(const ImageLocator & locator) override; std::shared_ptr<SDLImageShared> loadScaledImage(const ImageLocator & locator) override;
std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path, EImageBlitMode mode) override; std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path, EImageBlitMode mode) override;

View File

@ -397,7 +397,7 @@ std::shared_ptr<const ISharedImage> ScalableImageShared::loadOrGenerateImage(EIm
loadingLocator.playerColored = color; loadingLocator.playerColored = color;
// best case - requested image is already available in filesystem // best case - requested image is already available in filesystem
auto loadedImage = GH.renderHandler().loadSingleImage(loadingLocator); auto loadedImage = GH.renderHandler().loadScaledImage(loadingLocator);
if (loadedImage) if (loadedImage)
return loadedImage; return loadedImage;
@ -406,7 +406,7 @@ std::shared_ptr<const ISharedImage> ScalableImageShared::loadOrGenerateImage(EIm
for (int8_t scaling = 4; scaling > 1; --scaling) for (int8_t scaling = 4; scaling > 1; --scaling)
{ {
loadingLocator.scalingFactor = scaling; loadingLocator.scalingFactor = scaling;
auto loadedImage = GH.renderHandler().loadSingleImage(loadingLocator); auto loadedImage = GH.renderHandler().loadScaledImage(loadingLocator);
if (loadedImage) if (loadedImage)
return loadedImage->scaleTo(targetSize, nullptr); return loadedImage->scaleTo(targetSize, nullptr);
} }
@ -445,7 +445,7 @@ void ScalableImageShared::loadScaledImages(int8_t scalingFactor, PlayerColor col
} }
} }
if (color != PlayerColor::CANNOT_DETERMINE && scaled[scalingFactor].playerColored[color.getNum()] == nullptr) if (color.isValidPlayer() && scaled[scalingFactor].playerColored[color.getNum()] == nullptr)
{ {
switch(locator.layer) switch(locator.layer)
{ {