1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

resource generation

This commit is contained in:
Laserlicht 2024-08-19 23:18:14 +02:00
parent 11ac768599
commit fff0159ef6
12 changed files with 162 additions and 66 deletions

View File

@ -82,6 +82,7 @@ set(client_SRCS
media/CSoundHandler.cpp media/CSoundHandler.cpp
media/CVideoHandler.cpp media/CVideoHandler.cpp
render/AssetGenerator.cpp
render/CAnimation.cpp render/CAnimation.cpp
render/CBitmapHandler.cpp render/CBitmapHandler.cpp
render/CDefFile.cpp render/CDefFile.cpp
@ -280,6 +281,7 @@ set(client_HEADERS
media/ISoundPlayer.h media/ISoundPlayer.h
media/IVideoPlayer.h media/IVideoPlayer.h
render/AssetGenerator.h
render/CAnimation.h render/CAnimation.h
render/CBitmapHandler.h render/CBitmapHandler.h
render/CDefFile.h render/CDefFile.h

View File

@ -24,6 +24,7 @@
#include "../render/Graphics.h" #include "../render/Graphics.h"
#include "../render/IFont.h" #include "../render/IFont.h"
#include "../render/EFont.h" #include "../render/EFont.h"
#include "../render/AssetGenerator.h"
#include "../renderSDL/ScreenHandler.h" #include "../renderSDL/ScreenHandler.h"
#include "../renderSDL/RenderHandler.h" #include "../renderSDL/RenderHandler.h"
#include "../CMT.h" #include "../CMT.h"
@ -63,6 +64,8 @@ void CGuiHandler::init()
shortcutsHandlerInstance = std::make_unique<ShortcutHandler>(); shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
inputHandlerInstance = std::make_unique<InputHandler>(); // Must be after windowHandlerInstance and shortcutsHandlerInstance inputHandlerInstance = std::make_unique<InputHandler>(); // Must be after windowHandlerInstance and shortcutsHandlerInstance
framerateManagerInstance = std::make_unique<FramerateManager>(settings["video"]["targetfps"].Integer()); framerateManagerInstance = std::make_unique<FramerateManager>(settings["video"]["targetfps"].Integer());
AssetGenerator::generate();
} }
void CGuiHandler::handleEvents() void CGuiHandler::handleEvents()

View File

@ -0,0 +1,86 @@
/*
* AssetGenerator.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 "AssetGenerator.h"
#include "../gui/CGuiHandler.h"
#include "../render/IImage.h"
#include "../render/IImageLoader.h"
#include "../render/Canvas.h"
#include "../render/IRenderHandler.h"
#include "../lib/filesystem/Filesystem.h"
VCMI_LIB_NAMESPACE_BEGIN
void AssetGenerator::generate()
{
createBigSpellBook("data/SpelBk2.bmp");
}
void AssetGenerator::createBigSpellBook(std::string filename)
{
if(!CResourceHandler::get("local")->createResource(filename))
return;
auto res = ImagePath::builtin("SpelBack");
res.setOriginalResource(true);
std::shared_ptr<IImage> img = GH.renderHandler().loadImage(res, EImageBlitMode::OPAQUE);
Canvas canvas = Canvas(Point(800, 600));
// edges
canvas.draw(img, Point(0, 0), Rect(15, 38, 90, 45));
canvas.draw(img, Point(0, 460), Rect(15, 400, 90, 141));
canvas.draw(img, Point(705, 0), Rect(509, 38, 95, 45));
canvas.draw(img, Point(705, 460), Rect(509, 400, 95, 141));
// left / right
Canvas tmp1 = Canvas(Point(90, 355 - 45));
tmp1.draw(img, Point(0, 0), Rect(15, 38 + 45, 90, 355 - 45));
canvas.drawScaled(tmp1, Point(0, 45), Point(90, 415));
Canvas tmp2 = Canvas(Point(95, 355 - 45));
tmp2.draw(img, Point(0, 0), Rect(509, 38 + 45, 95, 355 - 45));
canvas.drawScaled(tmp2, Point(705, 45), Point(95, 415));
// top / bottom
Canvas tmp3 = Canvas(Point(409, 45));
tmp3.draw(img, Point(0, 0), Rect(100, 38, 409, 45));
canvas.drawScaled(tmp3, Point(90, 0), Point(615, 45));
Canvas tmp4 = Canvas(Point(409, 141));
tmp4.draw(img, Point(0, 0), Rect(100, 400, 409, 141));
canvas.drawScaled(tmp4, Point(90, 460), Point(615, 141));
// middle
Canvas tmp5 = Canvas(Point(409, 141));
tmp5.draw(img, Point(0, 0), Rect(100, 38 + 45, 509 - 15, 400 - 38));
canvas.drawScaled(tmp5, Point(90, 45), Point(615, 415));
// carpet
Canvas tmp6 = Canvas(Point(590, 59));
tmp6.draw(img, Point(0, 0), Rect(15, 484, 590, 59));
canvas.drawScaled(tmp6, Point(0, 545), Point(800, 59));
// remove bookmarks
for (int i = 0; i < 56; i++)
canvas.draw(Canvas(canvas, Rect(i < 30 ? 268 : 327, 464, 1, 46)), Point(269 + i, 464));
for (int i = 0; i < 56; i++)
canvas.draw(Canvas(canvas, Rect(469, 464, 1, 42)), Point(470 + i, 464));
for (int i = 0; i < 57; i++)
canvas.draw(Canvas(canvas, Rect(i < 30 ? 564 : 630, 464, 1, 44)), Point(565 + i, 464));
for (int i = 0; i < 56; i++)
canvas.draw(Canvas(canvas, Rect(656, 464, 1, 47)), Point(657 + i, 464));
// draw bookmarks
canvas.draw(img, Point(278, 464), Rect(220, 405, 37, 47));
canvas.draw(img, Point(481, 465), Rect(354, 406, 37, 41));
canvas.draw(img, Point(575, 465), Rect(417, 406, 37, 45));
canvas.draw(img, Point(667, 465), Rect(478, 406, 37, 47));
std::shared_ptr<IImage> image = GH.renderHandler().createImage(canvas.getInternalSurface());
ResourcePath savePath(filename, EResType::IMAGE);
image->exportBitmap(*CResourceHandler::get("local")->getResourceName(savePath));
}
VCMI_LIB_NAMESPACE_END

View File

@ -0,0 +1,23 @@
/*
* AssetGenerator.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
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE AssetGenerator
{
static void createBigSpellBook(std::string filename);
public:
static void generate();
};
VCMI_LIB_NAMESPACE_END

View File

@ -31,10 +31,6 @@
#include "../widgets/TextControls.h" #include "../widgets/TextControls.h"
#include "../widgets/Buttons.h" #include "../widgets/Buttons.h"
#include "../adventureMap/AdventureMapInterface.h" #include "../adventureMap/AdventureMapInterface.h"
#include "../render/IRenderHandler.h"
#include "../render/IImage.h"
#include "../render/IImageLoader.h"
#include "../render/Canvas.h"
#include "../../CCallback.h" #include "../../CCallback.h"
@ -119,7 +115,7 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
if(isBigSpellbook) if(isBigSpellbook)
{ {
background = std::make_shared<CPicture>(createBigSpellBook(), Point(0, 0)); background = std::make_shared<CPicture>(ImagePath::builtin("SpelBk2"), 0, 0);
updateShadow(); updateShadow();
} }
else else
@ -221,55 +217,6 @@ CSpellWindow::~CSpellWindow()
{ {
} }
std::shared_ptr<IImage> CSpellWindow::createBigSpellBook()
{
std::shared_ptr<IImage> img = GH.renderHandler().loadImage(ImagePath::builtin("SpelBack"), EImageBlitMode::OPAQUE);
Canvas canvas = Canvas(Point(800, 600));
// edges
canvas.draw(img, Point(0, 0), Rect(15, 38, 90, 45));
canvas.draw(img, Point(0, 460), Rect(15, 400, 90, 141));
canvas.draw(img, Point(705, 0), Rect(509, 38, 95, 45));
canvas.draw(img, Point(705, 460), Rect(509, 400, 95, 141));
// left / right
Canvas tmp1 = Canvas(Point(90, 355 - 45));
tmp1.draw(img, Point(0, 0), Rect(15, 38 + 45, 90, 355 - 45));
canvas.drawScaled(tmp1, Point(0, 45), Point(90, 415));
Canvas tmp2 = Canvas(Point(95, 355 - 45));
tmp2.draw(img, Point(0, 0), Rect(509, 38 + 45, 95, 355 - 45));
canvas.drawScaled(tmp2, Point(705, 45), Point(95, 415));
// top / bottom
Canvas tmp3 = Canvas(Point(409, 45));
tmp3.draw(img, Point(0, 0), Rect(100, 38, 409, 45));
canvas.drawScaled(tmp3, Point(90, 0), Point(615, 45));
Canvas tmp4 = Canvas(Point(409, 141));
tmp4.draw(img, Point(0, 0), Rect(100, 400, 409, 141));
canvas.drawScaled(tmp4, Point(90, 460), Point(615, 141));
// middle
Canvas tmp5 = Canvas(Point(409, 141));
tmp5.draw(img, Point(0, 0), Rect(100, 38 + 45, 509 - 15, 400 - 38));
canvas.drawScaled(tmp5, Point(90, 45), Point(615, 415));
// carpet
Canvas tmp6 = Canvas(Point(590, 59));
tmp6.draw(img, Point(0, 0), Rect(15, 484, 590, 59));
canvas.drawScaled(tmp6, Point(0, 545), Point(800, 59));
// remove bookmarks
for (int i = 0; i < 56; i++)
canvas.draw(Canvas(canvas, Rect(i < 30 ? 268 : 327, 464, 1, 46)), Point(269 + i, 464));
for (int i = 0; i < 56; i++)
canvas.draw(Canvas(canvas, Rect(469, 464, 1, 42)), Point(470 + i, 464));
for (int i = 0; i < 57; i++)
canvas.draw(Canvas(canvas, Rect(i < 30 ? 564 : 630, 464, 1, 44)), Point(565 + i, 464));
for (int i = 0; i < 56; i++)
canvas.draw(Canvas(canvas, Rect(656, 464, 1, 47)), Point(657 + i, 464));
// draw bookmarks
canvas.draw(img, Point(278, 464), Rect(220, 405, 37, 47));
canvas.draw(img, Point(481, 465), Rect(354, 406, 37, 41));
canvas.draw(img, Point(575, 465), Rect(417, 406, 37, 45));
canvas.draw(img, Point(667, 465), Rect(478, 406, 37, 47));
return GH.renderHandler().createImage(canvas.getInternalSurface());
}
void CSpellWindow::searchInput() void CSpellWindow::searchInput()
{ {
if(searchBox) if(searchBox)

View File

@ -113,8 +113,6 @@ class CSpellWindow : public CWindowObject
void turnPageLeft(); void turnPageLeft();
void turnPageRight(); void turnPageRight();
std::shared_ptr<IImage> createBigSpellBook();
bool openOnBattleSpells; bool openOnBattleSpells;
std::function<void(SpellID)> onSpellSelect; //external processing of selected spell std::function<void(SpellID)> onSpellSelect; //external processing of selected spell

View File

@ -65,6 +65,16 @@ CFilesystemList::~CFilesystemList()
} }
std::unique_ptr<CInputStream> CFilesystemList::load(const ResourcePath & resourceName) const std::unique_ptr<CInputStream> CFilesystemList::load(const ResourcePath & resourceName) const
{
if(resourceName.getOriginalResource())
{
for(const auto & loader : loaders)
{
if (loader->existsResource(resourceName))
return loader->load(resourceName);
}
}
else
{ {
// load resource from last loader that have it (last overridden version) // load resource from last loader that have it (last overridden version)
for(const auto & loader : boost::adaptors::reverse(loaders)) for(const auto & loader : boost::adaptors::reverse(loaders))
@ -72,6 +82,7 @@ std::unique_ptr<CInputStream> CFilesystemList::load(const ResourcePath & resourc
if (loader->existsResource(resourceName)) if (loader->existsResource(resourceName))
return loader->load(resourceName); return loader->load(resourceName);
} }
}
throw std::runtime_error("Resource with name " + resourceName.getName() + " and type " throw std::runtime_error("Resource with name " + resourceName.getName() + " and type "
+ EResTypeHelper::getEResTypeAsString(resourceName.getType()) + " wasn't found."); + EResTypeHelper::getEResTypeAsString(resourceName.getType()) + " wasn't found.");

View File

@ -118,10 +118,11 @@ std::unordered_map<ResourcePath, boost::filesystem::path> CFilesystemLoader::lis
EResType::ARCHIVE_SND, EResType::ARCHIVE_SND,
EResType::ARCHIVE_ZIP }; EResType::ARCHIVE_ZIP };
static const std::set<EResType> initialTypes(initArray, initArray + std::size(initArray)); static const std::set<EResType> initialTypes(initArray, initArray + std::size(initArray));
assert(boost::filesystem::is_directory(baseDirectory));
std::unordered_map<ResourcePath, boost::filesystem::path> fileList; std::unordered_map<ResourcePath, boost::filesystem::path> fileList;
if(!boost::filesystem::is_directory(baseDirectory))
return fileList;
std::vector<boost::filesystem::path> path; //vector holding relative path to our file std::vector<boost::filesystem::path> path; //vector holding relative path to our file
boost::filesystem::recursive_directory_iterator enddir; boost::filesystem::recursive_directory_iterator enddir;

View File

@ -182,10 +182,14 @@ void CResourceHandler::initialize()
knownLoaders["root"] = globalResourceHandler.rootLoader.get(); knownLoaders["root"] = globalResourceHandler.rootLoader.get();
knownLoaders["saves"] = new CFilesystemLoader("SAVES/", VCMIDirs::get().userSavePath()); knownLoaders["saves"] = new CFilesystemLoader("SAVES/", VCMIDirs::get().userSavePath());
knownLoaders["config"] = new CFilesystemLoader("CONFIG/", VCMIDirs::get().userConfigPath()); knownLoaders["config"] = new CFilesystemLoader("CONFIG/", VCMIDirs::get().userConfigPath());
knownLoaders["gen_data"] = new CFilesystemLoader("DATA/", VCMIDirs::get().userDataPath() / "Generated" / "Data");
knownLoaders["gen_sprites"] = new CFilesystemLoader("SPRITES/", VCMIDirs::get().userDataPath() / "Generated" / "Sprites");
auto * localFS = new CFilesystemList(); auto * localFS = new CFilesystemList();
localFS->addLoader(knownLoaders["saves"], true); localFS->addLoader(knownLoaders["saves"], true);
localFS->addLoader(knownLoaders["config"], true); localFS->addLoader(knownLoaders["config"], true);
localFS->addLoader(knownLoaders["gen_data"], true);
localFS->addLoader(knownLoaders["gen_sprites"], true);
addFilesystem("root", "initial", createInitial()); addFilesystem("root", "initial", createInitial());
addFilesystem("root", "data", new CFilesystemList()); addFilesystem("root", "data", new CFilesystemList());

View File

@ -51,19 +51,22 @@ static inline std::string readName(std::string name, bool uppercase)
ResourcePath::ResourcePath(const std::string & name_): ResourcePath::ResourcePath(const std::string & name_):
type(readType(name_)), type(readType(name_)),
name(readName(name_, true)), name(readName(name_, true)),
originalName(readName(name_, false)) originalName(readName(name_, false)),
originalResource(false)
{} {}
ResourcePath::ResourcePath(const std::string & name_, EResType type_): ResourcePath::ResourcePath(const std::string & name_, EResType type_):
type(type_), type(type_),
name(readName(name_, true)), name(readName(name_, true)),
originalName(readName(name_, false)) originalName(readName(name_, false)),
originalResource(false)
{} {}
ResourcePath::ResourcePath(const JsonNode & name, EResType type): ResourcePath::ResourcePath(const JsonNode & name, EResType type):
type(type), type(type),
name(readName(name.String(), true)), name(readName(name.String(), true)),
originalName(readName(name.String(), false)) originalName(readName(name.String(), false)),
originalResource(false)
{ {
} }

View File

@ -99,6 +99,7 @@ public:
bool empty() const {return name.empty();} bool empty() const {return name.empty();}
std::string getName() const {return name;} std::string getName() const {return name;}
std::string getOriginalName() const {return originalName;} std::string getOriginalName() const {return originalName;}
bool getOriginalResource() const {return originalResource;}
EResType getType() const {return type;} EResType getType() const {return type;}
void serializeJson(JsonSerializeFormat & handler); void serializeJson(JsonSerializeFormat & handler);
@ -108,6 +109,8 @@ public:
h & type; h & type;
h & name; h & name;
h & originalName; h & originalName;
if (h.version >= Handler::Version::RESOURCE_GENERATION)
h & originalResource;
} }
protected: protected:
@ -120,6 +123,9 @@ protected:
/// name in original case /// name in original case
std::string originalName; std::string originalName;
/// flag for requesting unmodded, original resource
bool originalResource;
}; };
template<EResType Type> template<EResType Type>
@ -180,6 +186,17 @@ public:
ResourcePathTempl result; ResourcePathTempl result;
result.name = prefix + this->getName(); result.name = prefix + this->getName();
result.originalName = prefix + this->getOriginalName(); result.originalName = prefix + this->getOriginalName();
result.originalResource = this->getOriginalResource();
return result;
}
ResourcePathTempl setOriginalResource(bool original) const
{
ResourcePathTempl result;
result.name = this->getName();
result.originalName = this->getOriginalName();
result.originalResource = original;
return result; return result;
} }

View File

@ -63,6 +63,7 @@ enum class ESerializationVersion : int32_t
STATISTICS, // 852 - removed random number generators from library classes STATISTICS, // 852 - removed random number generators from library classes
CAMPAIGN_REGIONS, // 853 - configurable campaign regions CAMPAIGN_REGIONS, // 853 - configurable campaign regions
EVENTS_PLAYER_SET, // 854 - map & town events use std::set instead of bitmask to store player list EVENTS_PLAYER_SET, // 854 - map & town events use std::set instead of bitmask to store player list
RESOURCE_GENERATION, // 855 - resource generation
CURRENT = EVENTS_PLAYER_SET CURRENT = RESOURCE_GENERATION
}; };