Selaa lähdekoodia

Added RenderHandler that acts as factory for images and animations

Ivan Savenko 2 vuotta sitten
vanhempi
sitoutus
1d0e696db6
38 muutettua tiedostoa jossa 246 lisäystä ja 126 poistoa
  1. 3 0
      client/CMakeLists.txt
  2. 2 1
      client/ClientCommandManager.cpp
  3. 3 2
      client/adventureMap/AdventureMapWidget.cpp
  4. 2 1
      client/battle/BattleAnimationClasses.cpp
  5. 10 9
      client/battle/BattleFieldController.cpp
  6. 9 8
      client/battle/BattleInterfaceClasses.cpp
  7. 5 4
      client/battle/BattleObstacleController.cpp
  8. 2 1
      client/battle/BattleProjectileController.cpp
  9. 5 3
      client/battle/BattleSiegeController.cpp
  10. 5 4
      client/battle/BattleStacksController.cpp
  11. 2 1
      client/battle/BattleWindow.cpp
  12. 4 2
      client/battle/CreatureAnimation.cpp
  13. 7 0
      client/gui/CGuiHandler.cpp
  14. 3 1
      client/gui/CGuiHandler.h
  15. 8 7
      client/gui/CursorHandler.cpp
  16. 1 1
      client/gui/CursorHandler.h
  17. 2 1
      client/lobby/CBonusSelection.cpp
  18. 2 1
      client/lobby/CSelectionBase.cpp
  19. 6 5
      client/lobby/SelectionTab.cpp
  20. 13 11
      client/mapView/MapRenderer.cpp
  21. 6 6
      client/mapView/MapRenderer.h
  22. 4 1
      client/mapView/MapViewCache.cpp
  23. 1 1
      client/mapView/MapViewCache.h
  24. 1 0
      client/render/CAnimation.h
  25. 3 1
      client/render/Graphics.cpp
  26. 3 11
      client/render/IImage.h
  27. 36 0
      client/render/IRenderHandler.h
  28. 40 0
      client/renderSDL/RenderHandler.cpp
  29. 25 0
      client/renderSDL/RenderHandler.h
  30. 0 18
      client/renderSDL/SDLImage.cpp
  31. 2 1
      client/widgets/Buttons.cpp
  32. 5 4
      client/widgets/Images.cpp
  33. 3 2
      client/windows/CCastleInterface.cpp
  34. 3 2
      client/windows/CHeroWindow.cpp
  35. 4 3
      client/windows/CMessage.cpp
  36. 6 5
      client/windows/CSpellWindow.cpp
  37. 4 3
      client/windows/CWindowObject.cpp
  38. 6 5
      client/windows/GUIClasses.cpp

+ 3 - 0
client/CMakeLists.txt

@@ -84,6 +84,7 @@ set(client_SRCS
 	renderSDL/CTrueTypeFont.cpp
 	renderSDL/CursorHardware.cpp
 	renderSDL/CursorSoftware.cpp
+	renderSDL/RenderHandler.cpp
 	renderSDL/SDLImage.cpp
 	renderSDL/SDLImageLoader.cpp
 	renderSDL/SDLRWwrapper.cpp
@@ -235,6 +236,7 @@ set(client_HEADERS
 	render/IFont.h
 	render/IImage.h
 	render/IImageLoader.h
+	render/IRenderHandler.h
 	render/IScreenHandler.h
 
 	renderSDL/CBitmapFont.h
@@ -242,6 +244,7 @@ set(client_HEADERS
 	renderSDL/CTrueTypeFont.h
 	renderSDL/CursorHardware.h
 	renderSDL/CursorSoftware.h
+	renderSDL/RenderHandler.h
 	renderSDL/SDLImage.h
 	renderSDL/SDLImageLoader.h
 	renderSDL/SDLRWwrapper.h

+ 2 - 1
client/ClientCommandManager.cpp

@@ -17,6 +17,7 @@
 #include "CServerHandler.h"
 #include "gui/CGuiHandler.h"
 #include "gui/WindowHandler.h"
+#include "render/IRenderHandler.h"
 #include "../lib/NetPacks.h"
 #include "ClientNetPackVisitors.h"
 #include "../lib/CConfigHandler.h"
@@ -317,7 +318,7 @@ void ClientCommandManager::handleDef2bmpCommand(std::istringstream& singleWordBu
 {
 	std::string URI;
 	singleWordBuffer >> URI;
-	std::unique_ptr<CAnimation> anim = std::make_unique<CAnimation>(AnimationPath::builtin(URI));
+	auto anim = GH.renderHandler().loadAnimation(AnimationPath::builtin(URI));
 	anim->preload();
 	anim->exportBitmaps(VCMIDirs::get().userExtractedPath());
 }

+ 3 - 2
client/adventureMap/AdventureMapWidget.cpp

@@ -22,6 +22,7 @@
 #include "../mapView/MapView.h"
 #include "../render/CAnimation.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/Images.h"
 #include "../widgets/TextControls.h"
@@ -129,7 +130,7 @@ std::shared_ptr<IImage> AdventureMapWidget::loadImage(const JsonNode & name)
 	ImagePath resource = ImagePath::fromJson(name);
 
 	if(images.count(resource) == 0)
-		images[resource] = IImage::createFromFile(resource);
+		images[resource] = GH.renderHandler().loadImage(resource);
 
 	return images[resource];
 }
@@ -139,7 +140,7 @@ std::shared_ptr<CAnimation> AdventureMapWidget::loadAnimation(const JsonNode & n
 	AnimationPath resource = AnimationPath::fromJson(name);
 
 	if(animations.count(resource) == 0)
-		animations[resource] = std::make_shared<CAnimation>(resource);
+		animations[resource] = GH.renderHandler().loadAnimation(resource);
 
 	return animations[resource];
 }

+ 2 - 1
client/battle/BattleAnimationClasses.cpp

@@ -24,6 +24,7 @@
 #include "../CPlayerInterface.h"
 #include "../gui/CursorHandler.h"
 #include "../gui/CGuiHandler.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../CCallback.h"
 #include "../../lib/CStack.h"
@@ -881,7 +882,7 @@ uint32_t CastAnimation::getAttackClimaxFrame() const
 
 EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects, bool reversed):
 	BattleAnimation(owner),
-	animation(std::make_shared<CAnimation>(animationName)),
+	animation(GH.renderHandler().loadAnimation(animationName)),
 	effectFlags(effects),
 	effectFinished(false),
 	reversed(reversed)

+ 10 - 9
client/battle/BattleFieldController.cpp

@@ -26,6 +26,7 @@
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
 #include "../renderSDL/SDL_Extensions.h"
+#include "../render/IRenderHandler.h"
 #include "../gui/CGuiHandler.h"
 #include "../gui/CursorHandler.h"
 #include "../adventureMap/CInGameConsole.h"
@@ -120,20 +121,20 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
 
 	//preparing cells and hexes
-	cellBorder = IImage::createFromFile(ImagePath::builtin("CCELLGRD.BMP"), EImageBlitMode::COLORKEY);
-	cellShade = IImage::createFromFile(ImagePath::builtin("CCELLSHD.BMP"));
-	cellUnitMovementHighlight = IImage::createFromFile(ImagePath::builtin("UnitMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
-	cellUnitMaxMovementHighlight = IImage::createFromFile(ImagePath::builtin("UnitMaxMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
+	cellBorder = GH.renderHandler().loadImage(ImagePath::builtin("CCELLGRD.BMP"), EImageBlitMode::COLORKEY);
+	cellShade = GH.renderHandler().loadImage(ImagePath::builtin("CCELLSHD.BMP"));
+	cellUnitMovementHighlight = GH.renderHandler().loadImage(ImagePath::builtin("UnitMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
+	cellUnitMaxMovementHighlight = GH.renderHandler().loadImage(ImagePath::builtin("UnitMaxMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
 
-	attackCursors = std::make_shared<CAnimation>(AnimationPath::builtin("CRCOMBAT"));
+	attackCursors = GH.renderHandler().loadAnimation(AnimationPath::builtin("CRCOMBAT"));
 	attackCursors->preload();
 
 	initializeHexEdgeMaskToFrameIndex();
 
-	rangedFullDamageLimitImages = std::make_shared<CAnimation>(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsGreen.json"));
+	rangedFullDamageLimitImages = GH.renderHandler().loadAnimation(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsGreen.json"));
 	rangedFullDamageLimitImages->preload();
 
-	shootingRangeLimitImages = std::make_shared<CAnimation>(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsRed.json"));
+	shootingRangeLimitImages = GH.renderHandler().loadAnimation(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsRed.json"));
 	shootingRangeLimitImages->preload();
 
 	flipRangeLimitImagesIntoPositions(rangedFullDamageLimitImages);
@@ -146,12 +147,12 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
 		if(bfieldType == BattleField::NONE)
 			logGlobal->error("Invalid battlefield returned for current battle");
 		else
-			background = IImage::createFromFile(bfieldType.getInfo()->graphics, EImageBlitMode::OPAQUE);
+			background = GH.renderHandler().loadImage(bfieldType.getInfo()->graphics, EImageBlitMode::OPAQUE);
 	}
 	else
 	{
 		auto backgroundName = owner.siegeController->getBattleBackgroundName();
-		background = IImage::createFromFile(backgroundName, EImageBlitMode::OPAQUE);
+		background = GH.renderHandler().loadImage(backgroundName, EImageBlitMode::OPAQUE);
 	}
 
 	pos.w = background->width();

+ 9 - 8
client/battle/BattleInterfaceClasses.cpp

@@ -37,6 +37,7 @@
 #include "../windows/CMessage.h"
 #include "../windows/CSpellWindow.h"
 #include "../render/CAnimation.h"
+#include "../render/IRenderHandler.h"
 #include "../adventureMap/CInGameConsole.h"
 
 #include "../../CCallback.h"
@@ -352,7 +353,7 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
 	else
 		animationPath = hero->type->heroClass->imageBattleMale;
 
-	animation = std::make_shared<CAnimation>(animationPath);
+	animation = GH.renderHandler().loadAnimation(animationPath);
 	animation->preload();
 
 	pos.w = 64;
@@ -364,9 +365,9 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
 		animation->verticalFlip();
 
 	if(defender)
-		flagAnimation = std::make_shared<CAnimation>(AnimationPath::builtin("CMFLAGR"));
+		flagAnimation = GH.renderHandler().loadAnimation(AnimationPath::builtin("CMFLAGR"));
 	else
-		flagAnimation = std::make_shared<CAnimation>(AnimationPath::builtin("CMFLAGL"));
+		flagAnimation = GH.renderHandler().loadAnimation(AnimationPath::builtin("CMFLAGL"));
 
 	flagAnimation->preload();
 	flagAnimation->playerColored(hero->tempOwner);
@@ -676,8 +677,8 @@ StackQueue::StackQueue(bool Embedded, BattleInterface & owner)
 		pos.x += parent->pos.w/2 - pos.w/2;
 		pos.y += 10;
 
-		icons = std::make_shared<CAnimation>(AnimationPath::builtin("CPRSMALL"));
-		stateIcons = std::make_shared<CAnimation>(AnimationPath::builtin("VCMI/BATTLEQUEUE/STATESSMALL"));
+		icons = GH.renderHandler().loadAnimation(AnimationPath::builtin("CPRSMALL"));
+		stateIcons = GH.renderHandler().loadAnimation(AnimationPath::builtin("VCMI/BATTLEQUEUE/STATESSMALL"));
 	}
 	else
 	{
@@ -688,10 +689,10 @@ StackQueue::StackQueue(bool Embedded, BattleInterface & owner)
 
 		background = std::make_shared<CFilledTexture>(ImagePath::builtin("DIBOXBCK"), Rect(0, 0, pos.w, pos.h));
 
-		icons = std::make_shared<CAnimation>(AnimationPath::builtin("TWCRPORT"));
-		stateIcons = std::make_shared<CAnimation>(AnimationPath::builtin("VCMI/BATTLEQUEUE/STATESSMALL"));
+		icons = GH.renderHandler().loadAnimation(AnimationPath::builtin("TWCRPORT"));
+		stateIcons = GH.renderHandler().loadAnimation(AnimationPath::builtin("VCMI/BATTLEQUEUE/STATESSMALL"));
 		//TODO: where use big icons?
-		//stateIcons = std::make_shared<CAnimation>("VCMI/BATTLEQUEUE/STATESBIG");
+		//stateIcons = GH.renderHandler().loadAnimation("VCMI/BATTLEQUEUE/STATESBIG");
 	}
 	stateIcons->preload();
 

+ 5 - 4
client/battle/BattleObstacleController.cpp

@@ -22,6 +22,7 @@
 #include "../CPlayerInterface.h"
 #include "../gui/CGuiHandler.h"
 #include "../render/Canvas.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../CCallback.h"
 #include "../../lib/battle/CObstacleInstance.h"
@@ -49,14 +50,14 @@ void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi)
 		if (oi.obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
 		{
 			// obstacle uses single bitmap image for animations
-			auto animation = std::make_shared<CAnimation>();
+			auto animation = GH.renderHandler().createAnimation();
 			animation->setCustom(animationName.getName(), 0, 0);
 			animationsCache[animationName] = animation;
 			animation->preload();
 		}
 		else
 		{
-			auto animation = std::make_shared<CAnimation>(animationName);
+			auto animation = GH.renderHandler().loadAnimation(animationName);
 			animationsCache[animationName] = animation;
 			animation->preload();
 		}
@@ -76,7 +77,7 @@ void BattleObstacleController::obstacleRemoved(const std::vector<ObstacleChanges
 			continue;
 		}
 
-		auto animation = std::make_shared<CAnimation>(AnimationPath::fromJson(obstacle["appearAnimation"]));
+		auto animation = GH.renderHandler().loadAnimation(AnimationPath::fromJson(obstacle["appearAnimation"]));
 		animation->preload();
 
 		auto first = animation->getImage(0, 0);
@@ -104,7 +105,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 		if(!oi->visibleForSide(side.value(), owner.curInt->cb->battleHasNativeStack(side.value())))
 			continue;
 
-		auto animation = std::make_shared<CAnimation>(oi->getAppearAnimation());
+		auto animation = GH.renderHandler().loadAnimation(oi->getAppearAnimation());
 		animation->preload();
 
 		auto first = animation->getImage(0, 0);

+ 2 - 1
client/battle/BattleProjectileController.cpp

@@ -16,6 +16,7 @@
 #include "CreatureAnimation.h"
 
 #include "../render/Canvas.h"
+#include "../render/IRenderHandler.h"
 #include "../gui/CGuiHandler.h"
 #include "../CGameInfo.h"
 
@@ -190,7 +191,7 @@ void BattleProjectileController::initStackProjectile(const CStack * stack)
 
 std::shared_ptr<CAnimation> BattleProjectileController::createProjectileImage(const AnimationPath & path )
 {
-	std::shared_ptr<CAnimation> projectile = std::make_shared<CAnimation>(path);
+	std::shared_ptr<CAnimation> projectile = GH.renderHandler().loadAnimation(path);
 	projectile->preload();
 
 	if(projectile->size(1) != 0)

+ 5 - 3
client/battle/BattleSiegeController.cpp

@@ -20,8 +20,10 @@
 #include "../CMusicHandler.h"
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
+#include "../gui/CGuiHandler.h"
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../CCallback.h"
 #include "../../lib/NetPacks.h"
@@ -180,7 +182,7 @@ BattleSiegeController::BattleSiegeController(BattleInterface & owner, const CGTo
 		if ( !getWallPieceExistance(EWallVisual::EWallVisual(g)) )
 			continue;
 
-		wallPieceImages[g] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::REINFORCED));
+		wallPieceImages[g] = GH.renderHandler().loadImage(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::REINFORCED));
 	}
 }
 
@@ -246,7 +248,7 @@ void BattleSiegeController::gateStateChanged(const EGateState state)
 		wallPieceImages[EWallVisual::GATE] = nullptr;
 
 	if (stateId != EWallState::NONE)
-		wallPieceImages[EWallVisual::GATE] = IImage::createFromFile(getWallPieceImageName(EWallVisual::GATE,  stateId));
+		wallPieceImages[EWallVisual::GATE] = GH.renderHandler().loadImage(getWallPieceImageName(EWallVisual::GATE,  stateId));
 
 	if (playSound)
 		CCS->soundh->playSound(soundBase::DRAWBRG);
@@ -355,7 +357,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
 
 		auto wallState = EWallState(owner.curInt->cb->battleGetWallState(attackInfo.attackedPart));
 
-		wallPieceImages[wallId] = IImage::createFromFile(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState));
+		wallPieceImages[wallId] = GH.renderHandler().loadImage(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState));
 	}
 }
 

+ 5 - 4
client/battle/BattleStacksController.cpp

@@ -28,6 +28,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../render/Colors.h"
 #include "../render/Canvas.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../CCallback.h"
 #include "../../lib/spells/ISpellMechanics.h"
@@ -76,10 +77,10 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
 	animIDhelper(0)
 {
 	//preparing graphics for displaying amounts of creatures
-	amountNormal     = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
-	amountPositive   = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
-	amountNegative   = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
-	amountEffNeutral = IImage::createFromFile(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
+	amountNormal     = GH.renderHandler().loadImage(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
+	amountPositive   = GH.renderHandler().loadImage(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
+	amountNegative   = GH.renderHandler().loadImage(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
+	amountEffNeutral = GH.renderHandler().loadImage(ImagePath::builtin("CMNUMWIN.BMP"), EImageBlitMode::COLORKEY);
 
 	static const auto shifterNormal   = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 0.6f, 0.2f, 1.0f );
 	static const auto shifterPositive = ColorFilter::genRangeShifter( 0.f, 0.f, 0.f, 0.2f, 1.0f, 0.2f );

+ 2 - 1
client/battle/BattleWindow.cpp

@@ -29,6 +29,7 @@
 #include "../windows/CMessage.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
+#include "../render/IRenderHandler.h"
 #include "../adventureMap/CInGameConsole.h"
 
 #include "../../CCallback.h"
@@ -469,7 +470,7 @@ void BattleWindow::showAlternativeActionIcon(PossiblePlayerBattleAction action)
 			break;
 	}
 		
-	auto anim = std::make_shared<CAnimation>(iconName);
+	auto anim = GH.renderHandler().loadAnimation(iconName);
 	w->setImage(anim);
 	w->redraw();
 }

+ 4 - 2
client/battle/CreatureAnimation.cpp

@@ -13,8 +13,10 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/CCreatureHandler.h"
 
+#include "../gui/CGuiHandler.h"
 #include "../render/Canvas.h"
 #include "../render/ColorFilter.h"
+#include "../render/IRenderHandler.h"
 
 static const ColorRGBA creatureBlueBorder = { 0, 255, 255, 255 };
 static const ColorRGBA creatureGoldBorder = { 255, 255, 0, 255 };
@@ -196,8 +198,8 @@ CreatureAnimation::CreatureAnimation(const AnimationPath & name_, TSpeedControll
 	  speedController(controller),
 	  once(false)
 {
-	forward = std::make_shared<CAnimation>(name_);
-	reverse = std::make_shared<CAnimation>(name_);
+	forward = GH.renderHandler().loadAnimation(name_);
+	reverse = GH.renderHandler().loadAnimation(name_);
 
 	//todo: optimize
 	forward->preload();

+ 7 - 0
client/gui/CGuiHandler.cpp

@@ -25,6 +25,7 @@
 #include "../render/IFont.h"
 #include "../render/EFont.h"
 #include "../renderSDL/ScreenHandler.h"
+#include "../renderSDL/RenderHandler.h"
 #include "../CMT.h"
 #include "../CPlayerInterface.h"
 #include "../battle/BattleInterface.h"
@@ -75,6 +76,7 @@ void CGuiHandler::init()
 	eventDispatcherInstance = std::make_unique<EventDispatcher>();
 	windowHandlerInstance = std::make_unique<WindowHandler>();
 	screenHandlerInstance = std::make_unique<ScreenHandler>();
+	renderHandlerInstance = std::make_unique<RenderHandler>();
 	shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
 	framerateManagerInstance = std::make_unique<FramerateManager>(settings["video"]["targetfps"].Integer());
 }
@@ -206,6 +208,11 @@ IScreenHandler & CGuiHandler::screenHandler()
 	return *screenHandlerInstance;
 }
 
+IRenderHandler & CGuiHandler::renderHandler()
+{
+	return *renderHandlerInstance;
+}
+
 EventDispatcher & CGuiHandler::events()
 {
 	return *eventDispatcherInstance;

+ 3 - 1
client/gui/CGuiHandler.h

@@ -22,6 +22,7 @@ class IStatusBar;
 class CIntObject;
 class IUpdateable;
 class IShowActivatable;
+class IRenderHandler;
 class IScreenHandler;
 class WindowHandler;
 class EventDispatcher;
@@ -41,6 +42,7 @@ private:
 	std::unique_ptr<WindowHandler> windowHandlerInstance;
 
 	std::unique_ptr<IScreenHandler> screenHandlerInstance;
+	std::unique_ptr<IRenderHandler> renderHandlerInstance;
 	std::unique_ptr<FramerateManager> framerateManagerInstance;
 	std::unique_ptr<EventDispatcher> eventDispatcherInstance;
 	std::unique_ptr<InputHandler> inputHandlerInstance;
@@ -67,7 +69,7 @@ public:
 	void stopTextInput();
 
 	IScreenHandler & screenHandler();
-
+	IRenderHandler & renderHandler();
 	WindowHandler & windows();
 
 	/// Returns currently active status bar. Guaranteed to be non-null

+ 8 - 7
client/gui/CursorHandler.cpp

@@ -17,6 +17,7 @@
 #include "../renderSDL/CursorHardware.h"
 #include "../render/CAnimation.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../lib/CConfigHandler.h"
 
@@ -46,10 +47,10 @@ CursorHandler::CursorHandler()
 
 	cursors =
 	{
-		std::make_unique<CAnimation>(AnimationPath::builtin("CRADVNTR")),
-		std::make_unique<CAnimation>(AnimationPath::builtin("CRCOMBAT")),
-		std::make_unique<CAnimation>(AnimationPath::builtin("CRDEFLT")),
-		std::make_unique<CAnimation>(AnimationPath::builtin("CRSPELL"))
+		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRADVNTR")),
+		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRCOMBAT")),
+		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRDEFLT")),
+		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRSPELL"))
 	};
 
 	for (auto & cursor : cursors)
@@ -102,9 +103,9 @@ void CursorHandler::dragAndDropCursor(std::shared_ptr<IImage> image)
 
 void CursorHandler::dragAndDropCursor (const AnimationPath & path, size_t index)
 {
-	CAnimation anim(path);
-	anim.load(index);
-	dragAndDropCursor(anim.getImage(index));
+	auto anim = GH.renderHandler().loadAnimation(path);
+	anim->load(index);
+	dragAndDropCursor(anim->getImage(index));
 }
 
 void CursorHandler::cursorMove(const int & x, const int & y)

+ 1 - 1
client/gui/CursorHandler.h

@@ -114,7 +114,7 @@ class CursorHandler final
 {
 	std::shared_ptr<IImage> dndObject; //if set, overrides currentCursor
 
-	std::array<std::unique_ptr<CAnimation>, 4> cursors;
+	std::array<std::shared_ptr<CAnimation>, 4> cursors;
 
 	bool showing;
 

+ 2 - 1
client/lobby/CBonusSelection.cpp

@@ -31,6 +31,7 @@
 #include "../windows/GUIClasses.h"
 #include "../windows/InfoWindows.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 #include "../render/CAnimation.h"
 #include "../render/Graphics.h"
 #include "../gui/CGuiHandler.h"
@@ -306,7 +307,7 @@ void CBonusSelection::createBonusesIcons()
 		if(picNumber != -1)
 			picName += ":" + std::to_string(picNumber);
 
-		auto anim = std::make_shared<CAnimation>();
+		auto anim = GH.renderHandler().createAnimation();
 		anim->setCustom(picName, 0);
 		bonusButton->setImage(anim);
 		if(CSH->campaignBonus == i)

+ 2 - 1
client/lobby/CSelectionBase.cpp

@@ -39,6 +39,7 @@
 #include "../render/CAnimation.h"
 #include "../render/Graphics.h"
 #include "../render/IFont.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../lib/NetPacksLobby.h"
 #include "../../lib/CGeneralTextHandler.h"
@@ -356,7 +357,7 @@ CFlagBox::CFlagBox(const Rect & rect)
 	labelAllies = std::make_shared<CLabel>(0, 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":");
 	labelEnemies = std::make_shared<CLabel>(133, 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":");
 
-	iconsTeamFlags = std::make_shared<CAnimation>(AnimationPath::builtin("ITGFLAGS.DEF"));
+	iconsTeamFlags = GH.renderHandler().loadAnimation(AnimationPath::builtin("ITGFLAGS.DEF"));
 	iconsTeamFlags->preload();
 }
 

+ 6 - 5
client/lobby/SelectionTab.cpp

@@ -30,6 +30,7 @@
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 #include "../render/Graphics.h"
 
 #include "../../CCallback.h"
@@ -211,9 +212,9 @@ SelectionTab::SelectionTab(ESelectionScreen Type)
 		break;
 	}
 
-	iconsMapFormats = std::make_shared<CAnimation>(AnimationPath::builtin("SCSELC.DEF"));
-	iconsVictoryCondition = std::make_shared<CAnimation>(AnimationPath::builtin("SCNRVICT.DEF"));
-	iconsLossCondition = std::make_shared<CAnimation>(AnimationPath::builtin("SCNRLOSS.DEF"));
+	iconsMapFormats = GH.renderHandler().loadAnimation(AnimationPath::builtin("SCSELC.DEF"));
+	iconsVictoryCondition = GH.renderHandler().loadAnimation(AnimationPath::builtin("SCNRVICT.DEF"));
+	iconsLossCondition = GH.renderHandler().loadAnimation(AnimationPath::builtin("SCNRLOSS.DEF"));
 	for(int i = 0; i < positionsToShow; i++)
 		listItems.push_back(std::make_shared<ListItem>(Point(30, 129 + i * 25), iconsMapFormats, iconsVictoryCondition, iconsLossCondition));
 
@@ -923,7 +924,7 @@ std::vector<std::shared_ptr<IImage>> SelectionTab::CMapInfoTooltipBox::createMin
 		Canvas canvas = createMinimapForLayer(map, i);
 		Canvas canvasScaled = Canvas(Point(size, size));
 		canvasScaled.drawScaled(canvas, Point(0, 0), Point(size, size));
-		std::shared_ptr<IImage> img = IImage::createFromSurface(canvasScaled.getInternalSurface());
+		std::shared_ptr<IImage> img = GH.renderHandler().createImage(canvasScaled.getInternalSurface());
 		
 		ret.push_back(img);
 	}
@@ -935,7 +936,7 @@ SelectionTab::ListItem::ListItem(Point position, std::shared_ptr<CAnimation> ico
 	: CIntObject(LCLICK, position)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
-	pictureEmptyLine = std::make_shared<CPicture>(IImage::createFromFile(ImagePath::builtin("camcust")), Rect(25, 121, 349, 26), -8, -14);
+	pictureEmptyLine = std::make_shared<CPicture>(GH.renderHandler().loadImage(ImagePath::builtin("camcust")), Rect(25, 121, 349, 26), -8, -14);
 	labelName = std::make_shared<CLabel>(184, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
 	labelName->setAutoRedraw(false);
 	labelAmountOfPlayers = std::make_shared<CLabel>(8, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);

+ 13 - 11
client/mapView/MapRenderer.cpp

@@ -15,9 +15,11 @@
 #include "mapHandler.h"
 
 #include "../CGameInfo.h"
+#include "../gui/CGuiHandler.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../CCallback.h"
 
@@ -102,11 +104,11 @@ void MapTileStorage::load(size_t index, const AnimationPath & filename, EImageBl
 	{
 		if (!filename.empty())
 		{
-			entry = std::make_unique<CAnimation>(filename);
+			entry = GH.renderHandler().loadAnimation(filename);
 			entry->preload();
 		}
 		else
-			entry = std::make_unique<CAnimation>();
+			entry = GH.renderHandler().createAnimation();
 
 		for(size_t i = 0; i < entry->size(); ++i)
 			entry->getImage(i)->setBlitMode(blitMode);
@@ -247,7 +249,7 @@ uint8_t MapRendererRoad::checksum(IMapRendererContext & context, const int3 & co
 MapRendererBorder::MapRendererBorder()
 {
 	emptyFill = std::make_unique<Canvas>(Point(32,32));
-	animation = std::make_unique<CAnimation>(AnimationPath::builtin("EDG"));
+	animation = GH.renderHandler().loadAnimation(AnimationPath::builtin("EDG"));
 	animation->preload();
 }
 
@@ -309,9 +311,9 @@ uint8_t MapRendererBorder::checksum(IMapRendererContext & context, const int3 &
 
 MapRendererFow::MapRendererFow()
 {
-	fogOfWarFullHide = std::make_unique<CAnimation>(AnimationPath::builtin("TSHRC"));
+	fogOfWarFullHide = GH.renderHandler().loadAnimation(AnimationPath::builtin("TSHRC"));
 	fogOfWarFullHide->preload();
-	fogOfWarPartialHide = std::make_unique<CAnimation>(AnimationPath::builtin("TSHRE"));
+	fogOfWarPartialHide = GH.renderHandler().loadAnimation(AnimationPath::builtin("TSHRE"));
 	fogOfWarPartialHide->preload();
 
 	for(size_t i = 0; i < fogOfWarFullHide->size(); ++i)
@@ -394,7 +396,7 @@ std::shared_ptr<CAnimation> MapRendererObjects::getAnimation(const AnimationPath
 	if(it != animations.end())
 		return it->second;
 
-	auto ret = std::make_shared<CAnimation>(filename);
+	auto ret = GH.renderHandler().loadAnimation(filename);
 	animations[filename] = ret;
 	ret->preload();
 
@@ -557,10 +559,10 @@ uint8_t MapRendererObjects::checksum(IMapRendererContext & context, const int3 &
 }
 
 MapRendererOverlay::MapRendererOverlay()
-	: imageGrid(IImage::createFromFile(ImagePath::builtin("debug/grid"), EImageBlitMode::ALPHA))
-	, imageBlocked(IImage::createFromFile(ImagePath::builtin("debug/blocked"), EImageBlitMode::ALPHA))
-	, imageVisitable(IImage::createFromFile(ImagePath::builtin("debug/visitable"), EImageBlitMode::ALPHA))
-	, imageSpellRange(IImage::createFromFile(ImagePath::builtin("debug/spellRange"), EImageBlitMode::ALPHA))
+	: imageGrid(GH.renderHandler().loadImage(ImagePath::builtin("debug/grid"), EImageBlitMode::ALPHA))
+	, imageBlocked(GH.renderHandler().loadImage(ImagePath::builtin("debug/blocked"), EImageBlitMode::ALPHA))
+	, imageVisitable(GH.renderHandler().loadImage(ImagePath::builtin("debug/visitable"), EImageBlitMode::ALPHA))
+	, imageSpellRange(GH.renderHandler().loadImage(ImagePath::builtin("debug/spellRange"), EImageBlitMode::ALPHA))
 {
 
 }
@@ -616,7 +618,7 @@ uint8_t MapRendererOverlay::checksum(IMapRendererContext & context, const int3 &
 }
 
 MapRendererPath::MapRendererPath()
-	: pathNodes(new CAnimation(AnimationPath::builtin("ADAG")))
+	: pathNodes(GH.renderHandler().loadAnimation(AnimationPath::builtin("ADAG")))
 {
 	pathNodes->preload();
 }

+ 6 - 6
client/mapView/MapRenderer.h

@@ -23,11 +23,11 @@ class CAnimation;
 class IImage;
 class Canvas;
 class IMapRendererContext;
-enum class EImageBlitMode : uint8_t;
+enum class EImageBlitMode;
 
 class MapTileStorage
 {
-	using TerrainAnimation = std::array<std::unique_ptr<CAnimation>, 4>;
+	using TerrainAnimation = std::array<std::shared_ptr<CAnimation>, 4>;
 	std::vector<TerrainAnimation> animations;
 
 public:
@@ -91,7 +91,7 @@ public:
 
 class MapRendererBorder
 {
-	std::unique_ptr<CAnimation> animation;
+	std::shared_ptr<CAnimation> animation;
 	std::unique_ptr<Canvas> emptyFill;
 
 	size_t getIndexForTile(IMapRendererContext & context, const int3 & coordinates);
@@ -105,8 +105,8 @@ public:
 
 class MapRendererFow
 {
-	std::unique_ptr<CAnimation> fogOfWarFullHide;
-	std::unique_ptr<CAnimation> fogOfWarPartialHide;
+	std::shared_ptr<CAnimation> fogOfWarFullHide;
+	std::shared_ptr<CAnimation> fogOfWarPartialHide;
 
 public:
 	MapRendererFow();
@@ -117,7 +117,7 @@ public:
 
 class MapRendererPath
 {
-	std::unique_ptr<CAnimation> pathNodes;
+	std::shared_ptr<CAnimation> pathNodes;
 
 	size_t selectImageReachability(bool reachableToday, size_t imageIndex);
 	size_t selectImageCross(bool reachableToday, const int3 & curr);

+ 4 - 1
client/mapView/MapViewCache.cpp

@@ -18,6 +18,9 @@
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
+
+#include "../gui/CGuiHandler.h"
 
 #include "../../lib/mapObjects/CObjectHandler.h"
 #include "../../lib/int3.h"
@@ -28,7 +31,7 @@ MapViewCache::MapViewCache(const std::shared_ptr<MapViewModel> & model)
 	: model(model)
 	, cachedLevel(0)
 	, mapRenderer(new MapRenderer())
-	, iconsStorage(new CAnimation(AnimationPath::builtin("VwSymbol")))
+	, iconsStorage(GH.renderHandler().loadAnimation(AnimationPath::builtin("VwSymbol")))
 	, intermediate(new Canvas(Point(32, 32)))
 	, terrain(new Canvas(model->getCacheDimensionsPixels()))
 	, terrainTransition(new Canvas(model->getPixelsVisibleDimensions()))

+ 1 - 1
client/mapView/MapViewCache.h

@@ -52,7 +52,7 @@ class MapViewCache
 	std::unique_ptr<Canvas> intermediate;
 	std::unique_ptr<MapRenderer> mapRenderer;
 
-	std::unique_ptr<CAnimation> iconsStorage;
+	std::shared_ptr<CAnimation> iconsStorage;
 
 	Canvas getTile(const int3 & coordinates);
 	void updateTile(const std::shared_ptr<IMapRendererContext> & context, const int3 & coordinates);

+ 1 - 0
client/render/CAnimation.h

@@ -18,6 +18,7 @@ VCMI_LIB_NAMESPACE_END
 
 class CDefFile;
 class IImage;
+class RenderHandler;
 
 /// Class for handling animation
 class CAnimation

+ 3 - 1
client/render/Graphics.cpp

@@ -24,6 +24,8 @@
 #include "../renderSDL/CTrueTypeFont.h"
 #include "../render/CAnimation.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
+#include "../gui/CGuiHandler.h"
 
 #include "../lib/filesystem/Filesystem.h"
 #include "../lib/filesystem/CBinaryReader.h"
@@ -284,7 +286,7 @@ std::shared_ptr<CAnimation> Graphics::getAnimation(const AnimationPath & path)
 	if (cachedAnimations.count(path) != 0)
 		return cachedAnimations.at(path);
 
-	auto newAnimation = std::make_shared<CAnimation>(path);
+	auto newAnimation = GH.renderHandler().loadAnimation(path);
 
 	newAnimation->preload();
 	cachedAnimations[path] = newAnimation;

+ 3 - 11
client/render/IImage.h

@@ -24,7 +24,7 @@ struct SDL_Surface;
 class ColorFilter;
 
 /// Defines which blit method will be selected when image is used for rendering
-enum class EImageBlitMode : uint8_t
+enum class EImageBlitMode
 {
 	/// Image can have no transparency and can be only used as background
 	OPAQUE,
@@ -82,15 +82,7 @@ public:
 	virtual void verticalFlip() = 0;
 	virtual void doubleFlip() = 0;
 
-	IImage();
-	virtual ~IImage();
-
-	/// loads image from specified file. Returns 0-sized images on failure
-	static std::shared_ptr<IImage> createFromFile( const ImagePath & path );
-	static std::shared_ptr<IImage> createFromFile( const ImagePath & path, EImageBlitMode mode );
-
-	/// temporary compatibility method. Creates IImage from existing SDL_Surface
-	/// Surface will be shared, called must still free it with SDL_FreeSurface
-	static std::shared_ptr<IImage> createFromSurface( SDL_Surface * source );
+	IImage() = default;
+	virtual ~IImage() = default;
 };
 

+ 36 - 0
client/render/IRenderHandler.h

@@ -0,0 +1,36 @@
+/*
+ * IRenderHandler.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+#include "../../lib/filesystem/ResourcePath.h"
+
+struct SDL_Surface;
+
+class IImage;
+class CAnimation;
+enum class EImageBlitMode;
+
+class IRenderHandler : public boost::noncopyable
+{
+public:
+	/// Loads image using given path
+	virtual std::shared_ptr<IImage> loadImage(const ImagePath & path) = 0;
+	virtual std::shared_ptr<IImage> loadImage(const ImagePath & path, EImageBlitMode mode) = 0;
+
+	/// temporary compatibility method. Creates IImage from existing SDL_Surface
+	/// Surface will be shared, caller must still free it with SDL_FreeSurface
+	virtual std::shared_ptr<IImage> createImage(SDL_Surface * source) = 0;
+
+	/// Loads animation using given path
+	virtual std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path) = 0;
+
+	/// Creates empty CAnimation
+	virtual std::shared_ptr<CAnimation> createAnimation() = 0;
+};

+ 40 - 0
client/renderSDL/RenderHandler.cpp

@@ -0,0 +1,40 @@
+/*
+ * RenderHandler.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "RenderHandler.h"
+
+#include "../render/CAnimation.h"
+#include "SDLImage.h"
+
+
+std::shared_ptr<IImage> RenderHandler::loadImage(const ImagePath & path)
+{
+	return loadImage(path, EImageBlitMode::ALPHA);
+}
+
+std::shared_ptr<IImage> RenderHandler::loadImage(const ImagePath & path, EImageBlitMode mode)
+{
+	return std::make_shared<SDLImage>(path, mode);
+}
+
+std::shared_ptr<IImage> RenderHandler::createImage(SDL_Surface * source)
+{
+	return std::make_shared<SDLImage>(source, EImageBlitMode::ALPHA);
+}
+
+std::shared_ptr<CAnimation> RenderHandler::loadAnimation(const AnimationPath & path)
+{
+	return std::make_shared<CAnimation>(path);
+}
+
+std::shared_ptr<CAnimation> RenderHandler::createAnimation()
+{
+	return std::make_shared<CAnimation>();
+}

+ 25 - 0
client/renderSDL/RenderHandler.h

@@ -0,0 +1,25 @@
+/*
+ * RenderHandler.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+#include "../render/IRenderHandler.h"
+
+class RenderHandler : public IRenderHandler
+{
+public:
+	std::shared_ptr<IImage> loadImage(const ImagePath & path) override;
+	std::shared_ptr<IImage> loadImage(const ImagePath & path, EImageBlitMode mode) override;
+
+	std::shared_ptr<IImage> createImage(SDL_Surface * source) override;
+
+	std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path) override;
+
+	std::shared_ptr<CAnimation> createAnimation() override;
+};

+ 0 - 18
client/renderSDL/SDLImage.cpp

@@ -24,24 +24,6 @@
 
 class SDLImageLoader;
 
-std::shared_ptr<IImage> IImage::createFromFile( const ImagePath & path )
-{
-	return createFromFile(path, EImageBlitMode::ALPHA);
-}
-
-std::shared_ptr<IImage> IImage::createFromFile( const ImagePath & path, EImageBlitMode mode )
-{
-	return std::shared_ptr<IImage>(new SDLImage(path, mode));
-}
-
-std::shared_ptr<IImage> IImage::createFromSurface( SDL_Surface * source )
-{
-	return std::shared_ptr<IImage>(new SDLImage(source, EImageBlitMode::ALPHA));
-}
-
-IImage::IImage() = default;
-IImage::~IImage() = default;
-
 int IImage::width() const
 {
 	return dimensions().x;

+ 2 - 1
client/widgets/Buttons.cpp

@@ -25,6 +25,7 @@
 #include "../windows/InfoWindows.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/CGeneralTextHandler.h"
@@ -268,7 +269,7 @@ void CButton::setIndex(size_t index)
 	if (index == currentImage || index>=imageNames.size())
 		return;
 	currentImage = index;
-	auto anim = std::make_shared<CAnimation>(imageNames[index]);
+	auto anim = GH.renderHandler().loadAnimation(imageNames[index]);
 	setImage(anim);
 }
 

+ 5 - 4
client/widgets/Images.cpp

@@ -15,6 +15,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../renderSDL/SDL_Extensions.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/ColorFilter.h"
@@ -51,7 +52,7 @@ CPicture::CPicture( const ImagePath & bmpname )
 {}
 
 CPicture::CPicture( const ImagePath & bmpname, const Point & position )
-	: bg(IImage::createFromFile(bmpname))
+	: bg(GH.renderHandler().loadImage(bmpname))
 	, visible(true)
 	, needRefresh(false)
 {
@@ -115,7 +116,7 @@ void CPicture::colorize(PlayerColor player)
 
 CFilledTexture::CFilledTexture(const ImagePath & imageName, Rect position):
     CIntObject(0, position.topLeft()),
-	texture(IImage::createFromFile(imageName))
+	texture(GH.renderHandler().loadImage(imageName))
 {
 	pos.w = position.w;
 	pos.h = position.h;
@@ -178,7 +179,7 @@ CAnimImage::CAnimImage(const AnimationPath & name, size_t Frame, size_t Group, i
 {
 	pos.x += x;
 	pos.y += y;
-	anim = std::make_shared<CAnimation>(name);
+	anim = GH.renderHandler().loadAnimation(name);
 	init();
 }
 
@@ -308,7 +309,7 @@ bool CAnimImage::isPlayerColored() const
 }
 
 CShowableAnim::CShowableAnim(int x, int y, const AnimationPath & name, ui8 Flags, ui32 frameTime, size_t Group, uint8_t alpha):
-	anim(std::make_shared<CAnimation>(name)),
+	anim(GH.renderHandler().loadAnimation(name)),
 	group(Group),
 	frame(0),
 	first(0),

+ 3 - 2
client/windows/CCastleInterface.cpp

@@ -31,6 +31,7 @@
 #include "../widgets/TextControls.h"
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 #include "../render/ColorFilter.h"
 #include "../adventureMap/AdventureMapInterface.h"
 #include "../adventureMap/CList.h"
@@ -89,10 +90,10 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
 	}
 
 	if(!str->borderName.empty())
-		border = IImage::createFromFile(str->borderName, EImageBlitMode::ALPHA);
+		border = GH.renderHandler().loadImage(str->borderName, EImageBlitMode::ALPHA);
 
 	if(!str->areaName.empty())
-		area = IImage::createFromFile(str->areaName, EImageBlitMode::ALPHA);
+		area = GH.renderHandler().loadImage(str->areaName, EImageBlitMode::ALPHA);
 }
 
 const CBuilding * CBuildingRect::getBuilding()

+ 3 - 2
client/windows/CHeroWindow.cpp

@@ -28,6 +28,7 @@
 #include "../widgets/TextControls.h"
 #include "../widgets/Buttons.h"
 #include "../render/CAnimation.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../CCallback.h"
 
@@ -127,7 +128,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
 		primSkillValues.push_back(value);
 	}
 
-	auto primSkills = std::make_shared<CAnimation>(AnimationPath::builtin("PSKIL42"));
+	auto primSkills = GH.renderHandler().loadAnimation(AnimationPath::builtin("PSKIL42"));
 	primSkills->preload();
 	primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 0, 0, 32, 111));
 	primSkillImages.push_back(std::make_shared<CAnimImage>(primSkills, 1, 0, 102, 111));
@@ -148,7 +149,7 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
 	expValue = std::make_shared<CLabel>(68, 252);
 	manaValue = std::make_shared<CLabel>(211, 252);
 
-	auto secSkills = std::make_shared<CAnimation>(AnimationPath::builtin("SECSKILL"));
+	auto secSkills = GH.renderHandler().loadAnimation(AnimationPath::builtin("SECSKILL"));
 	for(int i = 0; i < std::min<size_t>(hero->secSkills.size(), 8u); ++i)
 	{
 		Rect r = Rect(i%2 == 0  ?  18  :  162,  276 + 48 * (i/2),  136,  42);

+ 4 - 3
client/windows/CMessage.cpp

@@ -23,6 +23,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../render/CAnimation.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 #include "../render/Canvas.h"
 #include "../render/Graphics.h"
 #include "../render/IFont.h"
@@ -69,7 +70,7 @@ struct ComponentsToBlit
 
 namespace
 {
-	std::array<std::unique_ptr<CAnimation>, PlayerColor::PLAYER_LIMIT_I> dialogBorders;
+	std::array<std::shared_ptr<CAnimation>, PlayerColor::PLAYER_LIMIT_I> dialogBorders;
 	std::array<std::vector<std::shared_ptr<IImage>>, PlayerColor::PLAYER_LIMIT_I> piecesOfBox;
 
 	std::shared_ptr<IImage> background;//todo: should be CFilledTexture
@@ -79,7 +80,7 @@ void CMessage::init()
 {
 	for(int i=0; i<PlayerColor::PLAYER_LIMIT_I; i++)
 	{
-		dialogBorders[i] = std::make_unique<CAnimation>(AnimationPath::builtin("DIALGBOX"));
+		dialogBorders[i] = GH.renderHandler().loadAnimation(AnimationPath::builtin("DIALGBOX"));
 		dialogBorders[i]->preload();
 
 		for(int j=0; j < dialogBorders[i]->size(0); j++)
@@ -92,7 +93,7 @@ void CMessage::init()
 		}
 	}
 
-	background = IImage::createFromFile(ImagePath::builtin("DIBOXBCK.BMP"), EImageBlitMode::OPAQUE);
+	background = GH.renderHandler().loadImage(ImagePath::builtin("DIBOXBCK.BMP"), EImageBlitMode::OPAQUE);
 }
 
 void CMessage::dispose()

+ 6 - 5
client/windows/CSpellWindow.cpp

@@ -30,6 +30,7 @@
 #include "../widgets/TextControls.h"
 #include "../adventureMap/AdventureMapInterface.h"
 #include "../render/CAnimation.h"
+#include "../render/IRenderHandler.h"
 
 #include "../../CCallback.h"
 
@@ -169,15 +170,15 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
 	leftCorner = std::make_shared<CPicture>(ImagePath::builtin("SpelTrnL.bmp"), 97, 77);
 	rightCorner = std::make_shared<CPicture>(ImagePath::builtin("SpelTrnR.bmp"), 487, 72);
 
-	spellIcons = std::make_shared<CAnimation>(AnimationPath::builtin("Spells"));
+	spellIcons = GH.renderHandler().loadAnimation(AnimationPath::builtin("Spells"));
 
 	schoolTab = std::make_shared<CAnimImage>(AnimationPath::builtin("SpelTab"), selectedTab, 0, 524, 88);
 	schoolPicture = std::make_shared<CAnimImage>(AnimationPath::builtin("Schools"), 0, 0, 117, 74);
 
-	schoolBorders[0] = std::make_shared<CAnimation>(AnimationPath::builtin("SplevA.def"));
-	schoolBorders[1] = std::make_shared<CAnimation>(AnimationPath::builtin("SplevF.def"));
-	schoolBorders[2] = std::make_shared<CAnimation>(AnimationPath::builtin("SplevW.def"));
-	schoolBorders[3] = std::make_shared<CAnimation>(AnimationPath::builtin("SplevE.def"));
+	schoolBorders[0] = GH.renderHandler().loadAnimation(AnimationPath::builtin("SplevA.def"));
+	schoolBorders[1] = GH.renderHandler().loadAnimation(AnimationPath::builtin("SplevF.def"));
+	schoolBorders[2] = GH.renderHandler().loadAnimation(AnimationPath::builtin("SplevW.def"));
+	schoolBorders[3] = GH.renderHandler().loadAnimation(AnimationPath::builtin("SplevE.def"));
 
 	for(auto item : schoolBorders)
 		item->preload();

+ 4 - 3
client/windows/CWindowObject.cpp

@@ -20,6 +20,7 @@
 #include "../windows/CMessage.h"
 #include "../renderSDL/SDL_PixelAccess.h"
 #include "../render/IImage.h"
+#include "../render/IRenderHandler.h"
 #include "../render/Canvas.h"
 
 #include "../CGameInfo.h"
@@ -210,9 +211,9 @@ void CWindowObject::setShadow(bool on)
 		{
 			OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
 
-			shadowParts.push_back(std::make_shared<CPicture>( IImage::createFromSurface(shadowCorner), Point(shadowPos.x,   shadowPos.y)));
-			shadowParts.push_back(std::make_shared<CPicture>( IImage::createFromSurface(shadowRight ),  Point(shadowPos.x,   shadowStart.y)));
-			shadowParts.push_back(std::make_shared<CPicture>( IImage::createFromSurface(shadowBottom), Point(shadowStart.x, shadowPos.y)));
+			shadowParts.push_back(std::make_shared<CPicture>( GH.renderHandler().createImage(shadowCorner), Point(shadowPos.x,   shadowPos.y)));
+			shadowParts.push_back(std::make_shared<CPicture>( GH.renderHandler().createImage(shadowRight ),  Point(shadowPos.x,   shadowStart.y)));
+			shadowParts.push_back(std::make_shared<CPicture>( GH.renderHandler().createImage(shadowBottom), Point(shadowStart.x, shadowPos.y)));
 
 		}
 		SDL_FreeSurface(shadowCorner);

+ 6 - 5
client/windows/GUIClasses.cpp

@@ -42,6 +42,7 @@
 #include "../lobby/CSavingScreen.h"
 #include "../render/Canvas.h"
 #include "../render/CAnimation.h"
+#include "../render/IRenderHandler.h"
 #include "../CMT.h"
 
 #include "../../CCallback.h"
@@ -850,10 +851,10 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 	titles[0] = std::make_shared<CLabel>(147, 25, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, genTitle(heroInst[0]));
 	titles[1] = std::make_shared<CLabel>(653, 25, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, genTitle(heroInst[1]));
 
-	auto PSKIL32 = std::make_shared<CAnimation>(AnimationPath::builtin("PSKIL32"));
+	auto PSKIL32 = GH.renderHandler().loadAnimation(AnimationPath::builtin("PSKIL32"));
 	PSKIL32->preload();
 
-	auto SECSK32 = std::make_shared<CAnimation>(AnimationPath::builtin("SECSK32"));
+	auto SECSK32 = GH.renderHandler().loadAnimation(AnimationPath::builtin("SECSK32"));
 
 	for(int g = 0; g < 4; ++g) 
 	{
@@ -1262,7 +1263,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
 
-	bars = std::make_shared<CAnimation>();
+	bars = GH.renderHandler().createAnimation();
 	bars->setCustom("UNIVRED", 0, 0);
 	bars->setCustom("UNIVGOLD", 1, 0);
 	bars->setCustom("UNIVGREN", 2, 0);
@@ -1626,7 +1627,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 		rowHeaders.push_back(std::make_shared<CLabel>(135, y, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, text));
 	}
 
-	auto PRSTRIPS = std::make_shared<CAnimation>(AnimationPath::builtin("PRSTRIPS"));
+	auto PRSTRIPS = GH.renderHandler().loadAnimation(AnimationPath::builtin("PRSTRIPS"));
 	PRSTRIPS->preload();
 
 	for(int g=1; g<tgi.playerColors.size(); ++g)
@@ -1635,7 +1636,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
 	for(int g=0; g<tgi.playerColors.size(); ++g)
 		columnHeaders.push_back(std::make_shared<CLabel>(283 + 66*g, 24, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->jktexts[16+g]));
 
-	auto itgflags = std::make_shared<CAnimation>(AnimationPath::builtin("itgflags"));
+	auto itgflags = GH.renderHandler().loadAnimation(AnimationPath::builtin("itgflags"));
 	itgflags->preload();
 
 	//printing flags