#include "loading_screen.h" #include // for SDL_GetError #include // for SDL_PollEvent, SDL_Event #include // for SDL_PIXELFORMAT_RGBA8888 #include // for SDL_GetTicks #include // for rand #include // for char_traits, basic_ostream, operator<< #include "defines.h" // for GAME_SPEED #include "global_events.h" // for check #include "global_inputs.h" // for check #include "jail_audio.h" // for JA_PlayMusic, JA_SetVolume, JA_StopMusic #include "options.h" // for Options, options, OptionsVideo, Section... #include "resource.h" // for Resource #include "screen.h" // for Screen #include "s_sprite.h" // for SSprite #include "surface.h" // for Texture #include "utils.h" // for Color, stringToColor, Palette // 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(Screen::get()->getRendererSurface(), options.game.width, options.game.height)) { // Cambia el destino de las surfaces mono_loading_screen_surface_->setSurfaceDest(screen_surface_); color_loading_screen_surface_->setSurfaceDest(screen_surface_); // Configura la superficie donde se van a pintar los sprites screen_surface_->setColor(0, 0xFF000000); screen_surface_->clear(0); // Inicializa variables options.section.section = Section::LOADING_SCREEN; options.section.subsection = Subsection::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 const int numSteps = 5; const int step = 51; load_counter_ = counter_ / numSteps; if (load_counter_ < 192) { load_rect_.x = step * (counter_ % numSteps); 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) { options.section.section = Section::TITLE; options.section.subsection = Subsection::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() { loading_first_part_ ? mono_loading_screen_sprite_->render(1, stringToColor("black")) : color_loading_screen_sprite_->render(); } // Dibuja el efecto de carga en el borde void LoadingScreen::renderBorder() { // Pinta el borde de colro azul Uint8 color = stringToColor("blue"); Screen::get()->clearSurface(color); // AƱade lineas amarillas color = stringToColor("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; auto surface = Screen::get()->getRendererSurface(); 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) { surface->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) { // Prepara para empezar a dibujar en la textura del borde Screen::get()->startDrawOnBorder(); // 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()->clear(); Screen::get()->render(); while (options.section.section == Section::LOADING_SCREEN) { update(); checkEvents(); render(); } JA_SetVolume(128); }