Преглед на файлове

All images are now loaded via RenderHandler class

Ivan Savenko преди 1 година
родител
ревизия
56f1725234

+ 4 - 7
client/mapView/MapRenderer.cpp

@@ -115,14 +115,11 @@ void MapTileStorage::load(size_t index, const AnimationPath & filename, EImageBl
 			entry->getImage(i)->setBlitMode(blitMode);
 	}
 
-	for(size_t i = 0; i < terrainAnimations[0]->size(); ++i)
-	{
-		terrainAnimations[1]->getImage(i)->verticalFlip();
-		terrainAnimations[3]->getImage(i)->verticalFlip();
+	terrainAnimations[1]->verticalFlip();
+	terrainAnimations[3]->verticalFlip();
 
-		terrainAnimations[2]->getImage(i)->horizontalFlip();
-		terrainAnimations[3]->getImage(i)->horizontalFlip();
-	}
+	terrainAnimations[2]->horizontalFlip();
+	terrainAnimations[3]->horizontalFlip();
 }
 
 std::shared_ptr<IImage> MapTileStorage::find(size_t fileIndex, size_t rotationIndex, size_t imageIndex)

+ 2 - 3
client/render/CAnimation.cpp

@@ -12,7 +12,6 @@
 
 #include "CDefFile.h"
 
-#include "Graphics.h"
 #include "../../lib/filesystem/Filesystem.h"
 #include "../../lib/json/JsonUtils.h"
 #include "../renderSDL/SDLImage.h"
@@ -179,8 +178,8 @@ void CAnimation::init()
 			source[defEntry.first].resize(defEntry.second);
 	}
 
-	if (vstd::contains(graphics->imageLists, name.getName()))
-		initFromJson(graphics->imageLists[name.getName()]);
+//	if (vstd::contains(graphics->imageLists, name.getName()))
+//		initFromJson(graphics->imageLists[name.getName()]);
 
 	auto jsonResource = name.toType<EResType::JSON>();
 	auto configList = CResourceHandler::get()->getResourcesWithName(jsonResource);

+ 1 - 47
client/render/CDefFile.cpp

@@ -18,50 +18,6 @@
 
 #include <SDL_pixels.h>
 
-// Extremely simple file cache. TODO: smarter, more general solution
-class CFileCache
-{
-	static const int cacheSize = 50; //Max number of cached files
-	struct FileData
-	{
-		AnimationPath             name;
-		size_t                 size;
-		std::unique_ptr<ui8[]> data;
-
-		std::unique_ptr<ui8[]> getCopy()
-		{
-			auto ret = std::unique_ptr<ui8[]>(new ui8[size]);
-			std::copy(data.get(), data.get() + size, ret.get());
-			return ret;
-		}
-		FileData(AnimationPath name_, size_t size_, std::unique_ptr<ui8[]> data_):
-			name{std::move(name_)},
-			size{size_},
-			data{std::move(data_)}
-		{}
-	};
-
-	std::deque<FileData> cache;
-public:
-	std::unique_ptr<ui8[]> getCachedFile(AnimationPath rid)
-	{
-		for(auto & file : cache)
-		{
-			if (file.name == rid)
-				return file.getCopy();
-		}
-		// Still here? Cache miss
-		if (cache.size() > cacheSize)
-			cache.pop_front();
-
-		auto data =  CResourceHandler::get()->load(rid)->readAll();
-
-		cache.emplace_back(std::move(rid), data.second, std::move(data.first));
-
-		return cache.back().getCopy();
-	}
-};
-
 enum class DefType : uint32_t
 {
 	SPELL = 0x40,
@@ -76,8 +32,6 @@ enum class DefType : uint32_t
 	BATTLE_HERO = 0x49
 };
 
-static CFileCache animationCache;
-
 /*************************************************************************
  *  DefFile, class used for def loading                                  *
  *************************************************************************/
@@ -124,7 +78,7 @@ CDefFile::CDefFile(const AnimationPath & Name):
 		{0, 0, 0, 64 }  // shadow border below selection ( used in battle def's )
 	};
 
-	data = animationCache.getCachedFile(Name);
+	data = CResourceHandler::get()->load(Name)->readAll().first;
 
 	palette = std::unique_ptr<SDL_Color[]>(new SDL_Color[256]);
 	int it = 0;

+ 0 - 49
client/render/Graphics.cpp

@@ -131,7 +131,6 @@ Graphics::Graphics()
 	loadPaletteAndColors();
 	initializeBattleGraphics();
 	loadErmuToPicture();
-	initializeImageLists();
 
 	//(!) do not load any CAnimation here
 }
@@ -244,51 +243,3 @@ void Graphics::loadErmuToPicture()
 	}
 	assert (etp_idx == 44);
 }
-
-void Graphics::addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName)
-{
-	if (!imageName.empty())
-	{
-		JsonNode entry;
-		if (group != 0)
-			entry["group"].Integer() = group;
-		entry["frame"].Integer() = index;
-		entry["file"].String() = imageName;
-
-		imageLists["SPRITES/" + listName]["images"].Vector().push_back(entry);
-	}
-}
-
-void Graphics::addImageListEntries(const EntityService * service)
-{
-	auto cb = std::bind(&Graphics::addImageListEntry, this, _1, _2, _3, _4);
-
-	auto loopCb = [&](const Entity * entity, bool & stop)
-	{
-		entity->registerIcons(cb);
-	};
-
-	service->forEachBase(loopCb);
-}
-
-void Graphics::initializeImageLists()
-{
-	addImageListEntries(CGI->creatures());
-	addImageListEntries(CGI->heroTypes());
-	addImageListEntries(CGI->artifacts());
-	addImageListEntries(CGI->factions());
-	addImageListEntries(CGI->spells());
-	addImageListEntries(CGI->skills());
-}
-
-std::shared_ptr<CAnimation> Graphics::getAnimation(const AnimationPath & path)
-{
-	if (cachedAnimations.count(path) != 0)
-		return cachedAnimations.at(path);
-
-	auto newAnimation = GH.renderHandler().loadAnimation(path);
-
-	newAnimation->preload();
-	cachedAnimations[path] = newAnimation;
-	return newAnimation;
-}

+ 0 - 10
client/render/Graphics.h

@@ -34,20 +34,12 @@ class IFont;
 /// Handles fonts, hero images, town images, various graphics
 class Graphics
 {
-	void addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName);
-	void addImageListEntries(const EntityService * service);
-
 	void initializeBattleGraphics();
 	void loadPaletteAndColors();
 	void loadErmuToPicture();
 	void loadFonts();
-	void initializeImageLists();
-
-	std::map<AnimationPath, std::shared_ptr<CAnimation>> cachedAnimations;
 
 public:
-	std::shared_ptr<CAnimation> getAnimation(const AnimationPath & path);
-
 	//Fonts
 	static const int FONTS_NUMBER = 9;
 	std::array< std::shared_ptr<IFont>, FONTS_NUMBER> fonts;
@@ -61,8 +53,6 @@ public:
 	PlayerPalette neutralColorPalette;
 	ColorRGBA neutralColor;
 
-	std::map<std::string, JsonNode> imageLists;
-
 	//towns
 	std::map<int, std::string> ERMUtoPicture[GameConstants::F_NUMBER]; //maps building ID to it's picture's name for each town type
 	//for battles

+ 2 - 0
client/render/IRenderHandler.h

@@ -26,6 +26,8 @@ public:
 	virtual std::shared_ptr<IImage> loadImage(const ImagePath & path) = 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) = 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;

+ 107 - 1
client/renderSDL/RenderHandler.cpp

@@ -10,9 +10,66 @@
 #include "StdInc.h"
 #include "RenderHandler.h"
 
-#include "../render/CAnimation.h"
 #include "SDLImage.h"
 
+#include "../render/CAnimation.h"
+#include "../render/CDefFile.h"
+
+#include "../../lib/json/JsonNode.h"
+
+std::shared_ptr<CDefFile> RenderHandler::getAnimationFile(const AnimationPath & path)
+{
+	auto it = animationFiles.find(path);
+
+	if (it != animationFiles.end())
+		return it->second;
+
+	auto result = std::make_shared<CDefFile>(path);
+
+	animationFiles[path] = result;
+	return result;
+}
+
+std::shared_ptr<JsonNode> RenderHandler::getJsonFile(const JsonPath & path)
+{
+	auto it = jsonFiles.find(path);
+
+	if (it != jsonFiles.end())
+		return it->second;
+
+	auto result = std::make_shared<JsonNode>(path);
+
+	jsonFiles[path] = result;
+	return result;
+}
+
+std::shared_ptr<IImage> RenderHandler::loadImage(const AnimationPath & path, int frame, int group)
+{
+	AnimationLocator locator{path, frame, group};
+
+	auto it = animationFrames.find(locator);
+	if (it != animationFrames.end())
+		return it->second;
+
+	auto defFile = getAnimationFile(path);
+	auto result = std::make_shared<SDLImage>(defFile.get(), frame, group);
+
+	animationFrames[locator] = result;
+	return result;
+}
+
+//std::vector<std::shared_ptr<IImage>> RenderHandler::loadImageGroup(const AnimationPath & path, int group)
+//{
+//	const auto defFile = getAnimationFile(path);
+//
+//	size_t groupSize = defFile->getEntries().at(group);
+//
+//	std::vector<std::shared_ptr<IImage>> result;
+//	for (size_t i = 0; i < groupSize; ++i)
+//		loadImage(path, i, group);
+//
+//	return result;
+//}
 
 std::shared_ptr<IImage> RenderHandler::loadImage(const ImagePath & path)
 {
@@ -38,3 +95,52 @@ std::shared_ptr<CAnimation> RenderHandler::createAnimation()
 {
 	return std::make_shared<CAnimation>();
 }
+
+//
+//void Graphics::addImageListEntry(size_t index, size_t group, const std::string & listName, const std::string & imageName)
+//{
+//	if (!imageName.empty())
+//	{
+//		JsonNode entry;
+//		if (group != 0)
+//			entry["group"].Integer() = group;
+//		entry["frame"].Integer() = index;
+//		entry["file"].String() = imageName;
+//
+//		imageLists["SPRITES/" + listName]["images"].Vector().push_back(entry);
+//	}
+//}
+//
+//void Graphics::addImageListEntries(const EntityService * service)
+//{
+//	auto cb = std::bind(&Graphics::addImageListEntry, this, _1, _2, _3, _4);
+//
+//	auto loopCb = [&](const Entity * entity, bool & stop)
+//	{
+//		entity->registerIcons(cb);
+//	};
+//
+//	service->forEachBase(loopCb);
+//}
+//
+//void Graphics::initializeImageLists()
+//{
+//	addImageListEntries(CGI->creatures());
+//	addImageListEntries(CGI->heroTypes());
+//	addImageListEntries(CGI->artifacts());
+//	addImageListEntries(CGI->factions());
+//	addImageListEntries(CGI->spells());
+//	addImageListEntries(CGI->skills());
+//}
+//
+//std::shared_ptr<CAnimation> Graphics::getAnimation(const AnimationPath & path)
+//{
+//	if (cachedAnimations.count(path) != 0)
+//		return cachedAnimations.at(path);
+//
+//	auto newAnimation = GH.renderHandler().loadAnimation(path);
+//
+//	newAnimation->preload();
+//	cachedAnimations[path] = newAnimation;
+//	return newAnimation;
+//}

+ 27 - 0
client/renderSDL/RenderHandler.h

@@ -11,12 +11,39 @@
 
 #include "../render/IRenderHandler.h"
 
+class CDefFile;
+
 class RenderHandler : public IRenderHandler
 {
+	struct AnimationLocator
+	{
+		AnimationPath animation;
+		int frame = -1;
+		int group = -1;
+
+		bool operator < (const AnimationLocator & other) const
+		{
+			if (animation != other.animation)
+				return animation < other.animation;
+			if (group != other.group)
+				return group < other.group;
+			return frame < other.frame;
+		}
+	};
+
+	std::map<AnimationPath, std::shared_ptr<CDefFile>> animationFiles;
+	std::map<JsonPath, std::shared_ptr<JsonNode>> jsonFiles;
+	std::map<ImagePath, std::shared_ptr<IImage>> imageFiles;
+	std::map<AnimationLocator, std::shared_ptr<IImage>> animationFrames;
+
+	std::shared_ptr<CDefFile> getAnimationFile(const AnimationPath & path);
+	std::shared_ptr<JsonNode> getJsonFile(const JsonPath & path);
 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> loadImage(const AnimationPath & path, int frame, int group) override;
+
 	std::shared_ptr<IImage> createImage(SDL_Surface * source) override;
 
 	std::shared_ptr<CAnimation> loadAnimation(const AnimationPath & path) override;

+ 2 - 3
client/widgets/CGarrisonInt.cpp

@@ -17,7 +17,6 @@
 #include "../gui/CGuiHandler.h"
 #include "../gui/WindowHandler.h"
 #include "../render/IImage.h"
-#include "../render/Graphics.h"
 #include "../windows/CCreatureWindow.h"
 #include "../windows/CWindowWithArtifacts.h"
 #include "../windows/GUIClasses.h"
@@ -437,10 +436,10 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, EGa
 
 	AnimationPath imgName = AnimationPath::builtin(owner->smallIcons ? "cprsmall" : "TWCRPORT");
 
-	creatureImage = std::make_shared<CAnimImage>(graphics->getAnimation(imgName), 0);
+	creatureImage = std::make_shared<CAnimImage>(imgName, 0);
 	creatureImage->disable();
 
-	selectionImage = std::make_shared<CAnimImage>(graphics->getAnimation(imgName), 1);
+	selectionImage = std::make_shared<CAnimImage>(imgName, 1);
 	selectionImage->disable();
 	selectionImage->center(creatureImage->pos.center());
 

+ 1 - 2
client/widgets/Images.cpp

@@ -19,7 +19,6 @@
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/ColorFilter.h"
-#include "../render/Graphics.h"
 
 #include "../battle/BattleInterface.h"
 #include "../battle/BattleInterfaceClasses.h"
@@ -177,7 +176,7 @@ CAnimImage::CAnimImage(const AnimationPath & name, size_t Frame, size_t Group, i
 {
 	pos.x += x;
 	pos.y += y;
-	anim = graphics->getAnimation(name);
+	anim = GH.renderHandler().loadAnimation(name);
 	init();
 }
 

+ 1 - 2
client/widgets/MiscWidgets.cpp

@@ -28,7 +28,6 @@
 #include "../windows/CCastleInterface.h"
 #include "../windows/InfoWindows.h"
 #include "../render/Canvas.h"
-#include "../render/Graphics.h"
 
 #include "../../CCallback.h"
 
@@ -535,7 +534,7 @@ CreatureTooltip::CreatureTooltip(Point pos, const CGCreature * creature)
 	auto creatureID = creature->getCreature();
 	int32_t creatureIconIndex = CGI->creatures()->getById(creatureID)->getIconIndex();
 
-	creatureImage = std::make_shared<CAnimImage>(graphics->getAnimation(AnimationPath::builtin("TWCRPORT")), creatureIconIndex);
+	creatureImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), creatureIconIndex);
 	creatureImage->center(Point(parent->pos.x + parent->pos.w / 2, parent->pos.y + creatureImage->pos.h / 2 + 11));
 
 	bool isHeroSelected = LOCPLINT->localState->getCurrentHero() != nullptr;

+ 0 - 1
client/windows/CHeroOverview.cpp

@@ -14,7 +14,6 @@
 #include "../gui/CGuiHandler.h"
 #include "../render/Canvas.h"
 #include "../render/Colors.h"
-#include "../render/Graphics.h"
 #include "../render/IImage.h"
 #include "../renderSDL/RenderHandler.h"
 #include "../widgets/CComponent.h"