1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-11 11:31:52 +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)
{
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);
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 AnimationPath & path, int frame, int group, EImageBlitMode mode) = 0;
/// Loads single image without scaling support
virtual std::shared_ptr<SDLImageShared> loadSingleImage(const ImageLocator & locator) = 0;
/// Loads single upscaled image without auto-scaling support
virtual std::shared_ptr<SDLImageShared> loadScaledImage(const ImageLocator & locator) = 0;
/// Creates image which can be used as target for drawing on
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();
}
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))
return ImageLocator(ImagePath::builtin("DEFAULT"), mode);
return ImageLocator();
if (frame >= layout.at(group).size())
return ImageLocator(ImagePath::builtin("DEFAULT"), mode);
return ImageLocator();
const auto & locator = layout.at(group).at(frame);
if (locator.image || locator.defFile)
@ -216,9 +216,9 @@ void RenderHandler::storeCachedImage(const ImageLocator & locator, std::shared_p
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 = {
"", // 0x
@ -236,40 +236,43 @@ std::shared_ptr<SDLImageShared> RenderHandler::loadSingleImage(const ImageLocato
"SPRITES4X/",
};
if(locator.image)
{
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);
}
ImagePath pathToLoad;
if(locator.defFile)
{
AnimationPath defFilePath = locator.defFile->addPrefix(scaledSpritesPath.at(locator.scalingFactor));
auto defFile = getAnimationFile(defFilePath);
auto remappedLocator = getLocatorForAnimationFrame(*locator.defFile, locator.defFrame, locator.defGroup, locator.scalingFactor, locator.layer);
// 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))
{
return std::make_shared<SDLImageShared>(defFile.get(), locator.defFrame, locator.defGroup);
}
pathToLoad = *remappedLocator.image;
}
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;
}
@ -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)
{
ImageLocator locator = getLocatorForAnimationFrame(path, frame, group, mode);
return loadImage(locator);
ImageLocator locator = getLocatorForAnimationFrame(path, frame, group, 1, mode);
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)

View File

@ -40,7 +40,7 @@ class RenderHandler : public IRenderHandler
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;
@ -53,7 +53,7 @@ public:
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<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;

View File

@ -397,7 +397,7 @@ std::shared_ptr<const ISharedImage> ScalableImageShared::loadOrGenerateImage(EIm
loadingLocator.playerColored = color;
// best case - requested image is already available in filesystem
auto loadedImage = GH.renderHandler().loadSingleImage(loadingLocator);
auto loadedImage = GH.renderHandler().loadScaledImage(loadingLocator);
if (loadedImage)
return loadedImage;
@ -406,7 +406,7 @@ std::shared_ptr<const ISharedImage> ScalableImageShared::loadOrGenerateImage(EIm
for (int8_t scaling = 4; scaling > 1; --scaling)
{
loadingLocator.scalingFactor = scaling;
auto loadedImage = GH.renderHandler().loadSingleImage(loadingLocator);
auto loadedImage = GH.renderHandler().loadScaledImage(loadingLocator);
if (loadedImage)
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)
{