195 lines
5.1 KiB
C++
195 lines
5.1 KiB
C++
/*
|
|
* ResourceManager.cpp
|
|
*
|
|
* Created on: Nov 7, 2016
|
|
* Author: tibi
|
|
*/
|
|
|
|
#include <GameState.h>
|
|
#include <graphics/backend/SdlRenderer.h>
|
|
#include <model/GameObject.h>
|
|
#include <resources/ResourceManager.h>
|
|
#include <resources/Resources.h>
|
|
#include <storage/Parsers.h>
|
|
#include <utils/Assert.h>
|
|
|
|
#include <iostream>
|
|
|
|
#include <boost/filesystem.hpp>
|
|
|
|
#define FONTID(id,size) (id * 1000 + size)
|
|
#define FONTID_SIZE(fontid) (fontid % 1000)
|
|
#define FONTID_ID(fontid) (fontid / 1000)
|
|
|
|
using namespace farmlands::graphics::backend;
|
|
|
|
namespace farmlands {
|
|
namespace resources {
|
|
|
|
ResourceManager ResourceManager::s_instance;
|
|
|
|
ResourceManager& ResourceManager::instance()
|
|
{
|
|
return s_instance;
|
|
}
|
|
|
|
ResourceManager::ResourceManager()
|
|
: m_loadedResources(new LoadedResource[sizeof(RInfo) / sizeof(RInfo[0])])
|
|
{
|
|
for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++)
|
|
m_loadedResources[i].loaded = false;
|
|
}
|
|
|
|
ResourceManager::~ResourceManager()
|
|
{
|
|
// Unload resources
|
|
for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++)
|
|
{
|
|
if (m_loadedResources[i].loaded)
|
|
{
|
|
switch(RInfo[i].type)
|
|
{
|
|
case ResourceType::Texture:
|
|
SDL_DestroyTexture(m_loadedResources[i].texture.texture);
|
|
SDL_FreeSurface(m_loadedResources[i].texture.surface);
|
|
break;
|
|
|
|
default:
|
|
std::cerr << "Warning: Cannot free resource " << i << " of type " << (int)RInfo[i].type << "\n";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] m_loadedResources;
|
|
|
|
// Unload fonts
|
|
for (auto pair : m_fontCache)
|
|
{
|
|
TTF_CloseFont(pair.second);
|
|
}
|
|
}
|
|
|
|
void ResourceManager::initialize()
|
|
{
|
|
}
|
|
|
|
void ResourceManager::loadMainMenu()
|
|
{
|
|
}
|
|
|
|
void ResourceManager::loadGame()
|
|
{
|
|
GameState::current().config = storage::parse<model::Configuration>(R::Config::Default);
|
|
GameState::current().scene = storage::parse<model::Scene>(R::Scenes::Game);
|
|
GameState::current().scene->root.onCreate();
|
|
|
|
storage::parseCollection(R::Items::Tools, GameState::current().itemPrefabs);
|
|
storage::parseCollection(R::Items::Weapons, GameState::current().itemPrefabs);
|
|
|
|
storage::parseCollection(R::Plants::Plantable, GameState::current().plantsPrefabs);
|
|
storage::parseCollection(R::Plants::Seeds, GameState::current().seedsPrefabs);
|
|
|
|
// Get to "Inventory" object
|
|
model::GameObject* root = &GameState::current().scene->root;
|
|
model::GameObject* player = *root->findByName("Player");
|
|
components::basic::Inventory* inventory = player->component<components::basic::Inventory>();
|
|
|
|
model::GameObject* pickables = *root->findByName("Pickables");
|
|
|
|
// Give player all items
|
|
for (auto prefab : GameState::current().itemPrefabs)
|
|
{
|
|
float x = player->transform.x + 15 * GameState::current().random.getFloat();
|
|
float y = player->transform.y + 15 * GameState::current().random.getFloat();
|
|
|
|
model::GameObject* item = model::GameObject::instantiate(prefab, "Pickable item", pickables);
|
|
item->transform.x = x;
|
|
item->transform.y = y;
|
|
item->addComponent(new components::items::Pickable());
|
|
}
|
|
|
|
for (auto prefab : GameState::current().seedsPrefabs)
|
|
{
|
|
model::GameObject* item = model::GameObject::instantiate(prefab, "inv seed", player);
|
|
inventory->add(item);
|
|
}
|
|
}
|
|
|
|
std::string ResourceManager::getPath(ResourceId resourceId)
|
|
{
|
|
Assert(resourceId >= 0 && resourceId < sizeof(RInfo) / sizeof(RInfo[0]), "Resource id out of bounds.");
|
|
|
|
boost::filesystem::path resPath(ASSETS_DIR);
|
|
resPath.append(RInfo[resourceId].path);
|
|
|
|
return resPath.native();
|
|
}
|
|
|
|
ResourceId ResourceManager::getId(std::string resPathStr)
|
|
{
|
|
boost::filesystem::path resPath(resPathStr);
|
|
|
|
for(size_t i = 0; i < sizeof(RInfo) / sizeof(RInfo[0]); i++)
|
|
{
|
|
boost::filesystem::path iPath (RInfo[i].path);
|
|
if (resPath == iPath)
|
|
return i;
|
|
}
|
|
|
|
return (ResourceId)-1;
|
|
}
|
|
|
|
TTF_Font* ResourceManager::font(ResourceId fontId, int pointSize)
|
|
{
|
|
Assert(RInfo[fontId].type == ResourceType::Font, "Resource must be a font");
|
|
|
|
// Do not load if already loaded
|
|
auto it = m_fontCache.find(FONTID(fontId, pointSize));
|
|
if (it != m_fontCache.end())
|
|
return it->second;
|
|
|
|
// Open font
|
|
std::string fontPath = getPath(fontId);
|
|
TTF_Font* font = TTF_OpenFont(fontPath.c_str(), pointSize);
|
|
if (!font)
|
|
THROW(utils::ResourceLoadException, "Could not load font " + fontPath);
|
|
|
|
// Cache font
|
|
m_fontCache.emplace(FONTID(fontId, pointSize), font);
|
|
|
|
return font;
|
|
}
|
|
|
|
SDL_Texture* ResourceManager::texture(ResourceId textureId)
|
|
{
|
|
Assert(RInfo[textureId].type == ResourceType::Texture, "Resource must be a texture");
|
|
|
|
// See if already loaded
|
|
if (!m_loadedResources[textureId].loaded)
|
|
{
|
|
// Open file
|
|
std::string texturePath = getPath(textureId);
|
|
SDL_Surface* surface = IMG_Load(texturePath.c_str());
|
|
if (surface == NULL)
|
|
THROW(utils::ResourceLoadException, "Failed to load texture " + texturePath);
|
|
|
|
SDL_Texture* texture = SDL_CreateTextureFromSurface(SdlRenderer::instance().internalRenderer(), surface);
|
|
if (texture == NULL)
|
|
THROW(utils::ResourceLoadException, "Failed to create texture " + texturePath);
|
|
|
|
// Add to loaded resources
|
|
m_loadedResources[textureId].texture.surface = surface;
|
|
m_loadedResources[textureId].texture.texture = texture;
|
|
m_loadedResources[textureId].loaded = true;
|
|
}
|
|
|
|
return m_loadedResources[textureId].texture.texture;
|
|
}
|
|
|
|
|
|
} /* namespace storage */
|
|
} /* namespace farmlands */
|
|
|
|
|