diff --git a/client/render/CanvasImage.cpp b/client/render/CanvasImage.cpp index 131421b3c..d16a30a14 100644 --- a/client/render/CanvasImage.cpp +++ b/client/render/CanvasImage.cpp @@ -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); diff --git a/client/render/IRenderHandler.h b/client/render/IRenderHandler.h index f878d32ae..cefd02890 100644 --- a/client/render/IRenderHandler.h +++ b/client/render/IRenderHandler.h @@ -39,8 +39,8 @@ public: virtual std::shared_ptr loadImage(const ImagePath & path, EImageBlitMode mode) = 0; virtual std::shared_ptr loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode) = 0; - /// Loads single image without scaling support - virtual std::shared_ptr loadSingleImage(const ImageLocator & locator) = 0; + /// Loads single upscaled image without auto-scaling support + virtual std::shared_ptr loadScaledImage(const ImageLocator & locator) = 0; /// Creates image which can be used as target for drawing on virtual std::shared_ptr createImage(const Point & size, CanvasScalingPolicy scalingPolicy) = 0; diff --git a/client/renderSDL/RenderHandler.cpp b/client/renderSDL/RenderHandler.cpp index ec5153d78..cc1c43fba 100644 --- a/client/renderSDL/RenderHandler.cpp +++ b/client/renderSDL/RenderHandler.cpp @@ -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 RenderHandler::loadSingleImage(const ImageLocator & locator) +std::shared_ptr 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 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(imagePathSprites); - - if(CResourceHandler::get()->existsResource(imagePathData)) - return std::make_shared(imagePathData); - - if(CResourceHandler::get()->existsResource(imagePath)) - return std::make_shared(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(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(imagePathSprites); + + if(CResourceHandler::get()->existsResource(imagePathData)) + return std::make_shared(imagePathData); + + if(CResourceHandler::get()->existsResource(imagePath)) + return std::make_shared(imagePath); + return nullptr; } @@ -299,8 +302,11 @@ std::shared_ptr RenderHandler::loadImage(const ImageLocator & locator) std::shared_ptr 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 RenderHandler::loadImage(const ImagePath & path, EImageBlitMode mode) diff --git a/client/renderSDL/RenderHandler.h b/client/renderSDL/RenderHandler.h index dc0635684..4a7e73c6a 100644 --- a/client/renderSDL/RenderHandler.h +++ b/client/renderSDL/RenderHandler.h @@ -40,7 +40,7 @@ class RenderHandler : public IRenderHandler std::shared_ptr 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 loadImage(const ImagePath & path, EImageBlitMode mode) override; std::shared_ptr loadImage(const AnimationPath & path, int frame, int group, EImageBlitMode mode) override; - std::shared_ptr loadSingleImage(const ImageLocator & locator) override; + std::shared_ptr loadScaledImage(const ImageLocator & locator) override; std::shared_ptr loadAnimation(const AnimationPath & path, EImageBlitMode mode) override; diff --git a/client/renderSDL/ScalableImage.cpp b/client/renderSDL/ScalableImage.cpp index c6ac12edf..39fe922b8 100644 --- a/client/renderSDL/ScalableImage.cpp +++ b/client/renderSDL/ScalableImage.cpp @@ -397,7 +397,7 @@ std::shared_ptr 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 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) {