1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

All images are now loaded via RenderHandler class

This commit is contained in:
Ivan Savenko
2024-05-22 11:28:13 +00:00
parent 2020d96070
commit 56f1725234
12 changed files with 147 additions and 125 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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();
}

View File

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

View File

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