diff --git a/source/asset.cpp b/source/asset.cpp index cd3f5e6..18ff1d2 100644 --- a/source/asset.cpp +++ b/source/asset.cpp @@ -52,7 +52,7 @@ bool Asset::check() const SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** CHECKING FILES"); // Comprueba la lista de ficheros clasificándolos por tipo - for (int type = 0; type < static_cast(AssetType::MAX_ASSET_TYPE); ++type) + for (int type = 0; type < static_cast(AssetType::COUNT); ++type) { // Comprueba si hay ficheros de ese tipo bool any = false; diff --git a/source/asset.h b/source/asset.h index ecc299a..153ff38 100644 --- a/source/asset.h +++ b/source/asset.h @@ -18,7 +18,7 @@ enum class AssetType : int ANIMATION, PALETTE, ITEM, - MAX_ASSET_TYPE, + COUNT, }; // Clase Asset: gestor de recursos (singleton) diff --git a/source/resource.cpp b/source/resource.cpp index 6cc3191..a076842 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -1,14 +1,15 @@ #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 +#include +#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; @@ -40,6 +41,9 @@ void Resource::clear() // Carga todos los recursos void Resource::load() { + calculateTotal(); + Screen::get()->show(); + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n** LOADING RESOURCES"); loadSounds(); loadMusics(); @@ -174,8 +178,9 @@ void Resource::loadSounds() for (const auto &l : list) { auto name = getFileName(l); - sounds_.emplace_back(ResourceSound(name, JA_LoadSound(l.c_str()))); + sounds_.emplace_back(Resource::ResourceSound(name, JA_LoadSound(l.c_str()))); printWithDots("Sound : ", name, "[ LOADED ]"); + updateLoadingProgress(); } } @@ -189,8 +194,9 @@ void Resource::loadMusics() for (const auto &l : list) { auto name = getFileName(l); - musics_.emplace_back(ResourceMusic(name, JA_LoadMusic(l.c_str()))); + musics_.emplace_back(Resource::ResourceMusic(name, JA_LoadMusic(l.c_str()))); printWithDots("Music : ", name, "[ LOADED ]"); + updateLoadingProgress(); } } @@ -204,7 +210,8 @@ void Resource::loadTextures() for (const auto &l : list) { auto name = getFileName(l); - textures_.emplace_back(ResourceTexture(name, std::make_shared(Screen::get()->getRenderer(), l))); + textures_.emplace_back(Resource::ResourceTexture(name, std::make_shared(Screen::get()->getRenderer(), l))); + updateLoadingProgress(); } } @@ -218,7 +225,8 @@ void Resource::loadTextFiles() for (const auto &l : list) { auto name = getFileName(l); - text_files_.emplace_back(ResourceTextFile(name, loadTextFile(l))); + text_files_.emplace_back(Resource::ResourceTextFile(name, loadTextFile(l))); + updateLoadingProgress(); } } @@ -232,7 +240,8 @@ void Resource::loadAnimations() for (const auto &l : list) { auto name = getFileName(l); - animations_.emplace_back(ResourceAnimation(name, loadAnimationsFromFile(l))); + animations_.emplace_back(Resource::ResourceAnimation(name, loadAnimationsFromFile(l))); + updateLoadingProgress(); } } @@ -241,7 +250,9 @@ void Resource::loadDemoData() { SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "\n>> DEMO FILES"); demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo1.bin"))); + updateLoadingProgress(); demos_.emplace_back(loadDemoDataFromFile(Asset::get()->get("demo2.bin"))); + updateLoadingProgress(); } // Añade paletas a las texturas @@ -290,7 +301,7 @@ void Resource::createTextures() auto text = getText("04b_25"); for (const auto &s : strings) { - textures_.emplace_back(ResourceTexture(s.name, text->writeToTexture(s.text, 1, -2))); + textures_.emplace_back(Resource::ResourceTexture(s.name, text->writeToTexture(s.text, 1, -2))); printWithDots("Texture : ", s.name, "[ DONE ]"); } @@ -305,7 +316,7 @@ void Resource::createTextures() auto text2 = getText("04b_25_2x"); for (const auto &s : strings2X) { - textures_.emplace_back(ResourceTexture(s.name, text2->writeToTexture(s.text, 1, -4))); + textures_.emplace_back(Resource::ResourceTexture(s.name, text2->writeToTexture(s.text, 1, -4))); printWithDots("Texture : ", s.name, "[ DONE ]"); } } @@ -339,7 +350,7 @@ void Resource::createText() for (const auto &resource : resources) { - texts_.emplace_back(ResourceText(resource.key, std::make_shared( + texts_.emplace_back(Resource::ResourceText(resource.key, std::make_shared( getTexture(resource.textureFile), getTextFile(resource.textFile)))); printWithDots("Text : ", resource.key, "[ DONE ]"); @@ -372,4 +383,75 @@ void Resource::clearMusics() } } musics_.clear(); +} + +// Calcula el numero de recursos para cargar +void Resource::calculateTotal() +{ + size_t total = 0; + for (int i = 0; i < static_cast(AssetType::COUNT); ++i) + { + auto assetType = static_cast(i); + auto list = Asset::get()->getListByType(assetType); + total += list.size(); + } + + count_ = ResourceCount(total, 0); +} + +// Muestra el progreso de carga +void Resource::renderProgress() +{ + auto screen = Screen::get(); + auto renderer = screen->getRenderer(); + + constexpr float X_PADDING = 10.0f; + constexpr float Y_PADDING = 10.0f; + constexpr float BAR_HEIGHT = 10.0f; + const float bar_position = param.game.height - BAR_HEIGHT - Y_PADDING; + screen->start(); + screen->clean(); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + + const float wired_bar_width = param.game.width - (X_PADDING * 2); + SDL_FRect rect_wired = {X_PADDING, bar_position, wired_bar_width, X_PADDING}; + SDL_RenderRect(renderer, &rect_wired); + + const float full_bar_width = wired_bar_width * count_.getPercentage(); + SDL_FRect rect_full = {X_PADDING, bar_position, full_bar_width, X_PADDING}; + SDL_RenderFillRect(renderer, &rect_full); + + screen->render(); +} + +// Comprueba los eventos de la pantalla de carga +void Resource::checkEvents() +{ + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_EVENT_QUIT: + exit(0); + break; + case SDL_EVENT_KEY_DOWN: + if (event.key.key == SDLK_ESCAPE) + { + exit(0); + } + break; + } + } +} + +// Actualiza el progreso de carga +void Resource::updateLoadingProgress(int steps) +{ + count_.add(1); + if (count_.loaded % steps == 0 || count_.loaded == count_.total) + { + renderProgress(); + } + checkEvents(); } \ No newline at end of file diff --git a/source/resource.h b/source/resource.h index 330b91a..c5c5eb1 100644 --- a/source/resource.h +++ b/source/resource.h @@ -1,77 +1,13 @@ #pragma once -#include // Para shared_ptr -#include // Para string -#include // Para vector -#include "animated_sprite.h" // Para AnimationsFileBuffer -#include "text.h" // Para TextFile, Text -#include "texture.h" // Para Texture -#include "utils.h" // Para DemoData - -struct JA_Music_t; -struct JA_Sound_t; - -// --- Estructuras para recursos individuales --- - -// Sonido -struct ResourceSound -{ - std::string name; // Nombre del sonido - JA_Sound_t *sound; // Objeto con el sonido - - ResourceSound(const std::string &name, JA_Sound_t *sound) - : name(name), sound(sound) {} -}; - -// Música -struct ResourceMusic -{ - std::string name; // Nombre de la música - JA_Music_t *music; // Objeto con la música - - ResourceMusic(const std::string &name, JA_Music_t *music) - : name(name), music(music) {} -}; - -// Textura -struct ResourceTexture -{ - std::string name; // Nombre de la textura - std::shared_ptr texture; // Objeto con la textura - - ResourceTexture(const std::string &name, std::shared_ptr texture) - : name(name), texture(texture) {} -}; - -// Fichero de texto (fuente) -struct ResourceTextFile -{ - std::string name; // Nombre del fichero - std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto - - ResourceTextFile(const std::string &name, std::shared_ptr text_file) - : name(name), text_file(text_file) {} -}; - -// Objeto de texto -struct ResourceText -{ - std::string name; // Nombre del objeto - std::shared_ptr text; // Objeto - - ResourceText(const std::string &name, std::shared_ptr text) - : name(name), text(text) {} -}; - -// Animación -struct ResourceAnimation -{ - std::string name; // Nombre del fichero - AnimationsFileBuffer animation; // Objeto con las animaciones - - ResourceAnimation(const std::string &name, const AnimationsFileBuffer &animation) - : name(name), animation(animation) {} -}; +#include +#include +#include +#include "animated_sprite.h" +#include "text.h" +#include "texture.h" +#include "utils.h" +#include "jail_audio.h" // --- Clase Resource: gestiona todos los recursos del juego (singleton) --- class Resource @@ -91,13 +27,84 @@ public: AnimationsFileBuffer &getAnimation(const std::string &name); // Obtiene la animación por nombre DemoData &getDemoData(int index); // Obtiene los datos de demo por índice - // --- Recarga de recursos --- + // --- Métodos de recarga de recursos --- void reload(); // Recarga todos los recursos void reloadTextures(); // Recarga solo las texturas private: - // --- Singleton --- - static Resource *instance_; + // --- Estructuras para recursos individuales --- + struct ResourceSound + { + std::string name; // Nombre del sonido + JA_Sound_t *sound; // Objeto con el sonido + + ResourceSound(const std::string &name, JA_Sound_t *sound) + : name(name), sound(sound) {} + }; + + struct ResourceMusic + { + std::string name; // Nombre de la música + JA_Music_t *music; // Objeto con la música + + ResourceMusic(const std::string &name, JA_Music_t *music) + : name(name), music(music) {} + }; + + struct ResourceTexture + { + std::string name; // Nombre de la textura + std::shared_ptr texture; // Objeto con la textura + + ResourceTexture(const std::string &name, std::shared_ptr texture) + : name(name), texture(texture) {} + }; + + struct ResourceTextFile + { + std::string name; // Nombre del fichero + std::shared_ptr text_file; // Objeto con los descriptores de la fuente de texto + + ResourceTextFile(const std::string &name, std::shared_ptr text_file) + : name(name), text_file(text_file) {} + }; + + struct ResourceText + { + std::string name; // Nombre del objeto + std::shared_ptr text; // Objeto de texto + + ResourceText(const std::string &name, std::shared_ptr text) + : name(name), text(text) {} + }; + + struct ResourceAnimation + { + std::string name; // Nombre de la animación + AnimationsFileBuffer animation; // Objeto con las animaciones + + ResourceAnimation(const std::string &name, const AnimationsFileBuffer &animation) + : name(name), animation(animation) {} + }; + + // --- Estructura para el progreso de carga --- + struct ResourceCount + { + int total; // Número total de recursos + int loaded; // Número de recursos cargados + + ResourceCount() : total(0), loaded(0) {} + ResourceCount(int total, int loaded) : total(total), loaded(loaded) {} + + void add(int amount) { loaded += amount; } + float getPercentage() const + { + return total > 0 ? static_cast(loaded) / static_cast(total) : 0.0f; + } + }; + + // --- Instancia singleton --- + static Resource *instance_; // Instancia única de Resource // --- Vectores de recursos --- std::vector sounds_; // Vector con los sonidos @@ -108,6 +115,9 @@ private: std::vector animations_; // Vector con las animaciones std::vector demos_; // Vector con los ficheros de datos para el modo demostración + // --- Progreso de carga --- + ResourceCount count_; // Contador de recursos cargados + // --- Métodos internos de carga y gestión --- void loadSounds(); // Carga los sonidos void loadMusics(); // Carga las músicas @@ -123,6 +133,12 @@ private: void clearSounds(); // Vacía el vector de sonidos void clearMusics(); // Vacía el vector de músicas + // --- Métodos internos para gestionar el progreso --- + void calculateTotal(); // Calcula el número de recursos para cargar + void renderProgress(); // Muestra el progreso de carga + void checkEvents(); // Comprueba los eventos durante la carga + void updateLoadingProgress(int steps = 1); // Actualiza el progreso de carga + // --- Constructores y destructor privados (singleton) --- Resource(); // Constructor privado ~Resource() = default; // Destructor privado diff --git a/source/screen.cpp b/source/screen.cpp index ab43cb6..aab6d37 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -35,7 +35,12 @@ Screen *Screen::get() { return Screen::instance_; } // Constructor Screen::Screen() - : src_rect_(SDL_FRect{0, 0, static_cast(param.game.width), static_cast(param.game.height)}), + : window_(nullptr), + renderer_(nullptr), + game_canvas_(nullptr), + service_menu_(nullptr), + notifier_(nullptr), + src_rect_(SDL_FRect{0, 0, static_cast(param.game.width), static_cast(param.game.height)}), dst_rect_(SDL_FRect{0, 0, static_cast(param.game.width), static_cast(param.game.height)}) { // Arranca SDL VIDEO, crea la ventana y el renderizador @@ -173,8 +178,10 @@ void Screen::update() fps_.calculate(SDL_GetTicks()); shake_effect_.update(src_rect_, dst_rect_); flash_effect_.update(); - serviceMenu_->update(); - notifier_->update(); + if (service_menu_) + service_menu_->update(); + if (notifier_) + notifier_->update(); Mouse::updateCursorVisibility(); } @@ -279,8 +286,10 @@ void Screen::renderOverlays() renderShake(); renderFlash(); renderAttenuate(); - serviceMenu_->render(); - notifier_->render(); + if (service_menu_) + service_menu_->render(); + if (notifier_) + notifier_->render(); #ifdef DEBUG renderInfo(); #endif @@ -409,7 +418,7 @@ void Screen::toggleVSync() // Obtiene los punteros a los singletones void Screen::getSingletons() { - serviceMenu_ = ServiceMenu::get(); + service_menu_ = ServiceMenu::get(); notifier_ = Notifier::get(); } diff --git a/source/screen.h b/source/screen.h index efac7a3..1ccdf0e 100644 --- a/source/screen.h +++ b/source/screen.h @@ -189,7 +189,7 @@ private: SDL_Window *window_; // Ventana de la aplicación SDL_Renderer *renderer_; // El renderizador de la ventana SDL_Texture *game_canvas_; // Textura donde se dibuja todo antes de volcarse al renderizador - ServiceMenu *serviceMenu_; // Objeto para mostrar el menú de servicio + ServiceMenu *service_menu_; // Objeto para mostrar el menú de servicio Notifier *notifier_; // Objeto para mostrar las notificaciones por pantalla // --- Variables de estado ---