#include "game/scene_manager.hpp" // Para SceneManager #include "game/scenes/loading_screen.hpp" #include #include // Para rand #include "core/input/global_inputs.hpp" // Para check #include "core/rendering/screen.hpp" // Para Screen #include "core/rendering/surface.hpp" // Para Surface #include "core/rendering/surface_sprite.hpp" // Para SSprite #include "core/resources/resource.hpp" // Para Resource #include "external/jail_audio.h" // Para JA_PlayMusic, JA_SetVolume, JA_StopMusic #include "game/gameplay/options.hpp" // Para Options, options, SectionState, Options... #include "utils/defines.hpp" // Para GAME_SPEED #include "utils/global_events.hpp" // Para check #include "utils/utils.hpp" // Para stringToColor, PaletteColor // Constructor LoadingScreen::LoadingScreen() : mono_loading_screen_surface_(Resource::get()->getSurface("loading_screen_bn.gif")), color_loading_screen_surface_(Resource::get()->getSurface("loading_screen_color.gif")), mono_loading_screen_sprite_(std::make_shared(mono_loading_screen_surface_, 0, 0, mono_loading_screen_surface_->getWidth(), mono_loading_screen_surface_->getHeight())), color_loading_screen_sprite_(std::make_shared(color_loading_screen_surface_, 0, 0, color_loading_screen_surface_->getWidth(), color_loading_screen_surface_->getHeight())), screen_surface_(std::make_shared(Options::game.width, Options::game.height)) { // Configura la superficie donde se van a pintar los sprites screen_surface_->clear(static_cast(PaletteColor::WHITE)); // Inicializa variables SceneManager::current = SceneManager::Scene::LOADING_SCREEN; SceneManager::options = SceneManager::Options::NONE; // Establece el orden de las lineas para imitar el direccionamiento de memoria del spectrum for (int i = 0; i < 192; ++i) { if (i < 64) { // Primer bloque de 2K line_index_[i] = ((i % 8) * 8) + (i / 8); } else if (i < 128) { // Segundo bloque de 2K line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8); } else { // Tercer bloque de 2K line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8); } } // Cambia el color del borde Screen::get()->setBorderColor(stringToColor("black")); } // Destructor LoadingScreen::~LoadingScreen() { JA_StopMusic(); } // Comprueba el manejador de eventos void LoadingScreen::checkEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { globalEvents::check(event); } } // Comprueba las entradas void LoadingScreen::checkInput() { globalInputs::check(); } // Gestiona el contador de carga void LoadingScreen::updateLoad() { // Primera parte de la carga, la parte en blanco y negro if (loading_first_part_) { // Cada 5 pasos el load_counter_ se incrementa en uno constexpr int NUM_STEPS = 5; constexpr int STEPS = 51; load_counter_ = counter_ / NUM_STEPS; if (load_counter_ < 192) { load_rect_.x = STEPS * (counter_ % NUM_STEPS); load_rect_.y = line_index_[load_counter_]; mono_loading_screen_sprite_->setClip(load_rect_); mono_loading_screen_sprite_->setPosition(load_rect_); } // Una vez actualizadas las 192 lineas, pasa a la segunda fase de la carga else if (load_counter_ == 192) { loading_first_part_ = false; load_counter_ = 0; load_rect_ = {0, 0, 16, 8}; color_loading_screen_sprite_->setClip(load_rect_); color_loading_screen_sprite_->setPosition(load_rect_); JA_PlayMusic(Resource::get()->getMusic("loading_sound3.ogg")); } } // Segunda parte de la carga, la parte de los bloques en color else { load_counter_ += 2; load_rect_.x = (load_counter_ * 8) % 256; load_rect_.y = (load_counter_ / 32) * 8; color_loading_screen_sprite_->setClip(load_rect_); color_loading_screen_sprite_->setPosition(load_rect_); // Comprueba si ha terminado la intro if (load_counter_ >= 768) { SceneManager::current = SceneManager::Scene::TITLE; SceneManager::options = SceneManager::Options::TITLE_WITH_LOADING_SCREEN; JA_StopMusic(); } } } // Gestiona el contador interno void LoadingScreen::updateCounter() { (pre_counter_ >= 50) ? counter_++ : pre_counter_++; if (counter_ == 1) { JA_PlayMusic(Resource::get()->getMusic("loading_sound2.ogg")); } } // Dibuja la pantalla de carga void LoadingScreen::renderLoad() { auto previuos_renderer = Screen::get()->getRendererSurface(); Screen::get()->setRendererSurface(screen_surface_); loading_first_part_ ? mono_loading_screen_sprite_->render(1, stringToColor("black")) : color_loading_screen_sprite_->render(); Screen::get()->setRendererSurface(previuos_renderer); } // Dibuja el efecto de carga en el borde void LoadingScreen::renderBorder() { // Obtiene la Surface del borde auto border = Screen::get()->getBorderSurface(); // Pinta el borde de color azul border->clear(static_cast(PaletteColor::BLUE)); // AƱade lineas amarillas const Uint8 COLOR = static_cast(PaletteColor::YELLOW); const int WIDTH = Options::game.width + (Options::video.border.width * 2); const int HEIGHT = Options::game.height + (Options::video.border.height * 2); bool draw_enabled = rand() % 2 == 0 ? true : false; int row = 0; while (row < HEIGHT) { const int ROW_HEIGHT = (rand() % 4) + 3; if (draw_enabled) { for (int i = row; i < row + ROW_HEIGHT; ++i) { border->drawLine(0, i, WIDTH, i, COLOR); } } row += ROW_HEIGHT; draw_enabled = !draw_enabled; } } // Actualiza las variables void LoadingScreen::update() { // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego if (SDL_GetTicks() - ticks_ > GAME_SPEED) { ticks_ = SDL_GetTicks(); checkInput(); updateCounter(); updateLoad(); renderLoad(); Screen::get()->update(); } } // Dibuja en pantalla void LoadingScreen::render() { if (Options::video.border.enabled) { // Dibuja el efecto de carga en el borde renderBorder(); } // Prepara para empezar a dibujar en la textura de juego Screen::get()->start(); Screen::get()->clearSurface(stringToColor("white")); // Copia la surface a la surface de Screen screen_surface_->render(0, 0); // Vuelca el contenido del renderizador en pantalla Screen::get()->render(); } // Bucle para el logo del juego void LoadingScreen::run() { // Inicia el sonido de carga JA_SetVolume(64); JA_PlayMusic(Resource::get()->getMusic("loading_sound1.ogg")); // Limpia la pantalla Screen::get()->start(); Screen::get()->clearRenderer(); Screen::get()->render(); while (SceneManager::current == SceneManager::Scene::LOADING_SCREEN) { update(); checkEvents(); render(); } JA_SetVolume(128); }