#include "resource.h" #include // for find_if #include // for basic_ostream, operator<<, endl, cout, cerr #include // for runtime_error #include "asset.h" // for Asset, AssetType #include "jail_audio.h" // for JA_DeleteMusic, JA_DeleteSound, JA_LoadMusic #include "screen.h" // for Screen #include "text.h" // for Text, loadTextFile #include "utils.h" // for getFileName, printWithDots struct JA_Music_t; // lines 10-10 struct JA_Sound_t; // lines 11-11 // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Resource *Resource::resource_ = nullptr; // [SINGLETON] Crearemos el objeto screen con esta función estática void Resource::init() { Resource::resource_ = new Resource(); } // [SINGLETON] Destruiremos el objeto screen con esta función estática void Resource::destroy() { delete Resource::resource_; } // [SINGLETON] Con este método obtenemos el objeto screen y podemos trabajar con él Resource *Resource::get() { return Resource::resource_; } // Constructor Resource::Resource() { load(); } // Vacia todos los vectores de recursos void Resource::clear() { clearSounds(); clearMusics(); textures_.clear(); text_files_.clear(); texts_.clear(); animations_.clear(); } // Carga todos los recursos void Resource::load() { std::cout << "** LOADING RESOURCES" << std::endl; loadSounds(); loadMusics(); loadTextures(); loadTextFiles(); loadAnimations(); createText(); std::cout << "\n** RESOURCES LOADED" << std::endl; } // Recarga todos los recursos void Resource::reload() { clear(); load(); } // Obtiene el sonido a partir de un nombre JA_Sound_t *Resource::getSound(const std::string &name) { auto it = std::find_if(sounds_.begin(), sounds_.end(), [&name](const auto &s) { return s.name == name; }); if (it != sounds_.end()) { return it->sound; } std::cerr << "Error: Sonido no encontrado " << name << std::endl; throw std::runtime_error("Sonido no encontrado: " + name); } // Obtiene la música a partir de un nombre JA_Music_t *Resource::getMusic(const std::string &name) { auto it = std::find_if(musics_.begin(), musics_.end(), [&name](const auto &m) { return m.name == name; }); if (it != musics_.end()) { return it->music; } std::cerr << "Error: Música no encontrada " << name << std::endl; throw std::runtime_error("Música no encontrada: " + name); } // Obtiene la textura a partir de un nombre std::shared_ptr Resource::getTexture(const std::string &name) { auto it = std::find_if(textures_.begin(), textures_.end(), [&name](const auto &t) { return t.name == name; }); if (it != textures_.end()) { return it->texture; } std::cerr << "Error: Imagen no encontrada " << name << std::endl; throw std::runtime_error("Imagen no encontrada: " + name); } // Obtiene el fichero de texto a partir de un nombre std::shared_ptr Resource::getTextFile(const std::string &name) { auto it = std::find_if(text_files_.begin(), text_files_.end(), [&name](const auto &t) { return t.name == name; }); if (it != text_files_.end()) { return it->text_file; } std::cerr << "Error: TextFile no encontrado " << name << std::endl; throw std::runtime_error("TextFile no encontrado: " + name); } // Obtiene el objeto de texto a partir de un nombre std::shared_ptr Resource::getText(const std::string &name) { auto it = std::find_if(texts_.begin(), texts_.end(), [&name](const auto &t) { return t.name == name; }); if (it != texts_.end()) { return it->text; } std::cerr << "Error: Text no encontrado " << name << std::endl; throw std::runtime_error("Texto no encontrado: " + name); } // Obtiene la animación a partir de un nombre AnimationsFileBuffer &Resource::getAnimation(const std::string &name) { auto it = std::find_if(animations_.begin(), animations_.end(), [&name](const auto &a) { return a.name == name; }); if (it != animations_.end()) { return it->animation; } std::cerr << "Error: Animación no encontrada " << name << std::endl; throw std::runtime_error("Animación no encontrada: " + name); } // Obtiene el mapa de tiles a partir de un nombre std::vector &Resource::getTileMap(const std::string &name) { auto it = std::find_if(tile_maps_.begin(), tile_maps_.end(), [&name](const auto &t) { return t.name == name; }); if (it != tile_maps_.end()) { return it->tileMap; } std::cerr << "Error: Mapa de tiles no encontrado " << name << std::endl; throw std::runtime_error("Mapa de tiles no encontrado: " + name); } // Obtiene la habitación a partir de un nombre std::shared_ptr Resource::getRoom(const std::string &name) { auto it = std::find_if(rooms_.begin(), rooms_.end(), [&name](const auto &r) { return r.name == name; }); if (it != rooms_.end()) { return it->room; } std::cerr << "Error: Habitación no encontrada " << name << std::endl; throw std::runtime_error("Habitación no encontrada: " + name); } // Obtiene todas las habitaciones std::vector &Resource::getRooms() { return rooms_; } // Carga los sonidos void Resource::loadSounds() { std::cout << "\n>> SOUND FILES" << std::endl; auto list = Asset::get()->getListByType(AssetType::SOUND); sounds_.clear(); for (const auto &l : list) { auto name = getFileName(l); sounds_.emplace_back(ResourceSound(name, JA_LoadSound(l.c_str()))); printWithDots("Sound : ", name, "[ LOADED ]"); } } // Carga las musicas void Resource::loadMusics() { std::cout << "\n>> MUSIC FILES" << std::endl; auto list = Asset::get()->getListByType(AssetType::MUSIC); musics_.clear(); for (const auto &l : list) { auto name = getFileName(l); musics_.emplace_back(ResourceMusic(name, JA_LoadMusic(l.c_str()))); printWithDots("Music : ", name, "[ LOADED ]"); } } // Carga las texturas void Resource::loadTextures() { std::cout << "\n>> TEXTURES" << std::endl; auto list = Asset::get()->getListByType(AssetType::BITMAP); textures_.clear(); for (const auto &l : list) { auto name = getFileName(l); textures_.emplace_back(ResourceTexture(name, std::make_shared(Screen::get()->getRenderer(), l))); } } // Carga los ficheros de texto void Resource::loadTextFiles() { std::cout << "\n>> TEXT FILES" << std::endl; auto list = Asset::get()->getListByType(AssetType::FONT); text_files_.clear(); for (const auto &l : list) { auto name = getFileName(l); text_files_.emplace_back(ResourceTextFile(name, loadTextFile(l))); } } // Carga las animaciones void Resource::loadAnimations() { std::cout << "\n>> ANIMATIONS" << std::endl; auto list = Asset::get()->getListByType(AssetType::ANIMATION); animations_.clear(); for (const auto &l : list) { auto name = getFileName(l); animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l))); } } // Carga los mapas de tiles void Resource::loadTileMaps() { std::cout << "\n>> TILE MAPS" << std::endl; auto list = Asset::get()->getListByType(AssetType::TILEMAP); tile_maps_.clear(); for (const auto &l : list) { auto name = getFileName(l); tile_maps_.emplace_back(ResourceTileMap(name, loadRoomTileFile(l))); } } // Carga las habitaciones void Resource::loadRooms() { std::cout << "\n>> ROOMS" << std::endl; auto list = Asset::get()->getListByType(AssetType::ROOM); rooms_.clear(); for (const auto &l : list) { auto name = getFileName(l); rooms_.emplace_back(ResourceRoom(name, std::make_shared(loadRoomFile(l)))); } } void Resource::createText() { struct ResourceInfo { std::string key; // Identificador del recurso std::string textureFile; // Nombre del archivo de textura std::string textFile; // Nombre del archivo de texto // Constructor para facilitar la creación de objetos ResourceInfo ResourceInfo(const std::string &k, const std::string &tFile, const std::string &txtFile) : key(k), textureFile(tFile), textFile(txtFile) {} }; std::cout << "\n>> CREATING TEXT_OBJECTS" << std::endl; std::vector resources = { {"debug", "debug.png", "debug.txt"}, {"gauntlet", "gauntlet.png", "gauntlet.txt"}, {"smb2", "smb2.png", "smb2.txt"}, {"subatomic", "subatomic.png", "subatomic.txt"}, {"8bithud", "8bithud.png", "8bithud.txt"}}; for (const auto &resource : resources) { texts_.emplace_back(ResourceText(resource.key, std::make_shared( getTexture(resource.textureFile), getTextFile(resource.textFile)))); printWithDots("Text : ", resource.key, "[ DONE ]"); } } // Vacía el vector de sonidos void Resource::clearSounds() { // Itera sobre el vector y libera los recursos asociados a cada JA_Sound_t for (auto &sound : sounds_) { if (sound.sound) { JA_DeleteSound(sound.sound); sound.sound = nullptr; } } sounds_.clear(); // Limpia el vector después de liberar todos los recursos } // Vacía el vector de musicas void Resource::clearMusics() { // Itera sobre el vector y libera los recursos asociados a cada JA_Music_t for (auto &music : musics_) { if (music.music) { JA_DeleteMusic(music.music); music.music = nullptr; } } musics_.clear(); // Limpia el vector después de liberar todos los recursos }