#include "resource.h" #include // Para SDL_LogInfo, SDL_LogCategory, SDL_LogError #include // Para find_if #include // Para runtime_error #include "asset.h" // Para Asset, AssetType #include "jail_audio.h" // Para JA_DeleteMusic, JA_DeleteSound, JA_LoadMusic #include "lang.h" // Para getText #include "screen.h" // Para Screen #include "text.h" // Para Text, loadTextFile struct JA_Music_t; // lines 11-11 struct JA_Sound_t; // lines 12-12 // Singleton Resource *Resource::instance_ = nullptr; // Inicializa la instancia única del singleton void Resource::init() { Resource::instance_ = new Resource(); } // Libera la instancia void Resource::destroy() { delete Resource::instance_; } // Obtiene la instancia Resource *Resource::get() { return Resource::instance_; } // Constructor Resource::Resource() { load(); } // Vacia todos los vectores de recursos void Resource::clear() { clearSounds(); clearMusics(); textures_.clear(); text_files_.clear(); texts_.clear(); animations_.clear(); demos_.clear(); } // Carga todos los recursos void Resource::load() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES"); loadSounds(); loadMusics(); loadTextures(); loadTextFiles(); loadAnimations(); loadDemoData(); addPalettes(); createText(); createTextures(); SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** RESOURCES LOADED"); } // Recarga todos los recursos void Resource::reload() { clear(); load(); } // Recarga las texturas void Resource::reloadTextures() { loadTextures(); addPalettes(); createTextures(); } // 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; } SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Sonido no encontrado %s", name.c_str()); 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; } SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Música no encontrada %s", name.c_str()); 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; } SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Imagen no encontrada %s", name.c_str()); 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; } SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: TextFile no encontrado %s", name.c_str()); 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; } SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Text no encontrado %s", name.c_str()); throw std::runtime_error("Text 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; } SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Error: Animación no encontrada %s", name.c_str()); throw std::runtime_error("Animación no encontrada: " + name); } // Obtiene el fichero con los datos para el modo demostración a partir de un çindice DemoData &Resource::getDemoData(int index) { return demos_.at(index); } // Carga los sonidos void Resource::loadSounds() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> SOUND FILES"); 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 músicas void Resource::loadMusics() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> MUSIC FILES"); 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() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> TEXTURES"); 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() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> TEXT FILES"); 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() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> ANIMATIONS"); 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 datos para el modo demostración void Resource::loadDemoData() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> DEMO FILES"); demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo1.bin"))); demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo2.bin"))); } // Añade paletas a las texturas void Resource::addPalettes() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> PALETTES"); // Jugador 1 getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_1_coffee_palette.gif")); getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_2_coffee_palette.gif")); getTexture("player1.gif")->addPaletteFromFile(Asset::get()->get("player1_invencible_palette.gif")); // Jugador 2 getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_1_coffee_palette.gif")); getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_2_coffee_palette.gif")); getTexture("player2.gif")->addPaletteFromFile(Asset::get()->get("player2_invencible_palette.gif")); // Fuentes getTexture("smb2.gif")->addPaletteFromFile(Asset::get()->get("smb2_palette1.pal")); } // Crea texturas void Resource::createTextures() { struct NameAndText { std::string name; std::string text; NameAndText(const std::string &name_init, const std::string &text_init) : name(name_init), text(text_init) {} }; SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> CREATING TEXTURES"); // Tamaño normal std::vector strings = { {"game_text_1000_points", "1.000"}, {"game_text_2500_points", "2.500"}, {"game_text_5000_points", "5.000"}, {"game_text_powerup", lang::getText("[GAME_TEXT] 4")}, {"game_text_one_hit", lang::getText("[GAME_TEXT] 5")}, {"game_text_stop", lang::getText("[GAME_TEXT] 6")}, {"game_text_1000000_points", lang::getText("[GAME_TEXT] 8")}}; auto text = getText("04b_25"); for (const auto &s : strings) { textures_.emplace_back(ResourceTexture(s.name, text->writeToTexture(s.text, 1, -2))); printWithDots("Texture : ", s.name, "[ DONE ]"); } // Tamaño doble std::vector strings2X = { {"game_text_100000_points", "100.000"}, {"game_text_get_ready", lang::getText("[GAME_TEXT] 7")}, {"game_text_last_stage", lang::getText("[GAME_TEXT] 3")}, {"game_text_congratulations", lang::getText("[GAME_TEXT] 1")}, {"game_text_game_over", "Game Over"}}; auto text2 = getText("04b_25_2x"); for (const auto &s : strings2X) { textures_.emplace_back(ResourceTexture(s.name, text2->writeToTexture(s.text, 1, -4))); printWithDots("Texture : ", s.name, "[ DONE ]"); } } void Resource::createText() { struct ResourceInfo { std::string key; std::string textureFile; std::string textFile; ResourceInfo(const std::string &k, const std::string &tFile, const std::string &txtFile) : key(k), textureFile(tFile), textFile(txtFile) {} }; SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> CREATING TEXT OBJECTS"); std::vector resources = { {"04b_25", "04b_25.png", "04b_25.txt"}, {"04b_25_2x", "04b_25_2x.png", "04b_25_2x.txt"}, {"04b_25_metal", "04b_25_metal.png", "04b_25.txt"}, {"04b_25_grey", "04b_25_grey.png", "04b_25.txt"}, {"04b_25_flat", "04b_25_flat.png", "04b_25.txt"}, {"04b_25_reversed", "04b_25_reversed.png", "04b_25.txt"}, {"04b_25_flat_2x", "04b_25_flat_2x.png", "04b_25_2x.txt"}, {"04b_25_reversed_2x", "04b_25_reversed_2x.png", "04b_25_2x.txt"}, {"8bithud", "8bithud.png", "8bithud.txt"}, {"aseprite", "aseprite.png", "aseprite.txt"}, {"smb2", "smb2.gif", "smb2.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() { for (auto &sound : sounds_) { if (sound.sound) { JA_DeleteSound(sound.sound); sound.sound = nullptr; } } sounds_.clear(); } // Vacía el vector de músicas void Resource::clearMusics() { for (auto &music : musics_) { if (music.music) { JA_DeleteMusic(music.music); music.music = nullptr; } } musics_.clear(); }