Explorar o código

Fix loading of pre-scaled assets

Ivan Savenko hai 9 meses
pai
achega
c9dd3dab5d

+ 1 - 1
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);

+ 2 - 2
client/render/IRenderHandler.h

@@ -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;

+ 39 - 33
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<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,39 +236,42 @@ std::shared_ptr<SDLImageShared> RenderHandler::loadSingleImage(const ImageLocato
 		"SPRITES4X/",
 	};
 
-	if(locator.image)
+	ImagePath pathToLoad;
+
+	if(locator.defFile)
 	{
-		std::string imagePathString = locator.image->getName();
+		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(locator.layer == EImageBlitMode::ONLY_OVERLAY)
-			imagePathString += "-OVERLAY";
-		if(locator.layer == EImageBlitMode::ONLY_SHADOW)
-			imagePathString += "-SHADOW";
+		pathToLoad = *remappedLocator.image;
+	}
 
-		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(!locator.image)
+		return nullptr;
 
-		if(CResourceHandler::get()->existsResource(imagePathSprites))
-			return std::make_shared<SDLImageShared>(imagePathSprites);
+	pathToLoad = *locator.image;
 
-		if(CResourceHandler::get()->existsResource(imagePathData))
-			return std::make_shared<SDLImageShared>(imagePathData);
+	std::string imagePathString = pathToLoad.getName();
 
-		if(CResourceHandler::get()->existsResource(imagePath))
-			return std::make_shared<SDLImageShared>(imagePath);
-	}
+	if(locator.layer == EImageBlitMode::ONLY_OVERLAY)
+		imagePathString += "-OVERLAY";
+	if(locator.layer == EImageBlitMode::ONLY_SHADOW)
+		imagePathString += "-SHADOW";
 
-	if(locator.defFile)
-	{
-		AnimationPath defFilePath = locator.defFile->addPrefix(scaledSpritesPath.at(locator.scalingFactor));
-		auto defFile = getAnimationFile(defFilePath);
+	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(defFile && defFile->hasFrame(locator.defFrame, locator.defGroup))
-		{
-			return std::make_shared<SDLImageShared>(defFile.get(), locator.defFrame, locator.defGroup);
-		}
-	}
+	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)

+ 2 - 2
client/renderSDL/RenderHandler.h

@@ -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;
 

+ 3 - 3
client/renderSDL/ScalableImage.cpp

@@ -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)
 		{