#include "loading_screen.h" #include // for SDL_GetTicks #include // for rand #include "asset.h" // for Asset #include "const.h" // for SECTION_LOADING_SCREEN, SECTION_QUIT #include "input.h" // for Input, REPEAT_FALSE, inputs_e #include "jail_audio.h" // for JA_DeleteMusic, JA_LoadMusic, JA_PlayMusic #include "resource.h" // for Resource #include "screen.h" // for Screen #include "sprite.h" // for Sprite #include "texture.h" // for Texture #include "utils.h" // for options_t, section_t, color_t, stringToC... #include "options.h" // Constructor LoadingScreen::LoadingScreen(Resource *resource) : screen_(Screen::get()), renderer_(Screen::get()->getRenderer()), resource_(resource), asset_(Asset::get()), input_(Input::get()) { // Reserva memoria para los punteros eventHandler = new SDL_Event(); if (options.palette == p_zxspectrum) { mono_loading_screen_texture_ = resource->getTexture("loading_screen_bn.png"); color_loading_screen_texture_ = resource->getTexture("loading_screen_color.png"); } else if (options.palette == p_zxarne) { mono_loading_screen_texture_ = resource->getTexture("loading_screen_bn_zxarne.png"); color_loading_screen_texture_ = resource->getTexture("loading_screen_color_zxarne.png"); } mono_loading_screen_sprite_ = new Sprite(0, 0, mono_loading_screen_texture_->getWidth(), mono_loading_screen_texture_->getHeight(), mono_loading_screen_texture_, renderer_); color_loading_screen_sprite_ = new Sprite(0, 0, color_loading_screen_texture_->getWidth(), color_loading_screen_texture_->getHeight(), color_loading_screen_texture_, renderer_); loading_sound1_ = JA_LoadMusic(asset_->get("loading_sound1.ogg").c_str()); loading_sound2_ = JA_LoadMusic(asset_->get("loading_sound2.ogg").c_str()); loading_sound3_ = JA_LoadMusic(asset_->get("loading_sound3.ogg").c_str()); // Inicializa variables options.section.name = SECTION_LOADING_SCREEN; options.section.subsection = 0; // 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 >= 64 && i < 128) { // Segundo bloque de 2K line_index_[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8); } else if (i >= 128 && i < 192) { // tercer bloque de 2K line_index_[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8); } } // Cambia el color del borde screen_->setBorderColor(stringToColor(options.palette, "black")); } // Destructor LoadingScreen::~LoadingScreen() { delete mono_loading_screen_sprite_; delete color_loading_screen_sprite_; delete eventHandler; JA_DeleteMusic(loading_sound1_); JA_DeleteMusic(loading_sound2_); JA_DeleteMusic(loading_sound3_); } // Comprueba el manejador de eventos void LoadingScreen::checkEvents() { // Comprueba los eventos que hay en la cola while (SDL_PollEvent(eventHandler) != 0) { // Evento de salida de la aplicación if (eventHandler->type == SDL_QUIT) { options.section.name = SECTION_QUIT; break; } } } // Comprueba las entradas void LoadingScreen::checkInput() { if (input_->checkInput(input_exit, REPEAT_FALSE)) { options.section.name = SECTION_QUIT; } else if (input_->checkInput(input_toggle_border, REPEAT_FALSE)) { screen_->toggleBorder(); } else if (input_->checkInput(input_toggle_videomode, REPEAT_FALSE)) { screen_->toggleVideoMode(); } else if (input_->checkInput(input_window_dec_size, REPEAT_FALSE)) { screen_->decWindowSize(); } else if (input_->checkInput(input_window_inc_size, REPEAT_FALSE)) { screen_->incWindowSize(); } else if (input_->checkInput(input_toggle_palette, REPEAT_FALSE)) { switchPalette(); } else if (input_->checkInput(input_pause, REPEAT_FALSE) || input_->checkInput(input_accept, REPEAT_FALSE) || input_->checkInput(input_jump, REPEAT_FALSE)) { options.section.name = SECTION_TITLE; options.section.subsection = 0; } } // 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 loadCounter 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_->setSpriteClip(load_rect_); mono_loading_screen_sprite_->setRect(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_->setRect(load_rect_); color_loading_screen_sprite_->setSpriteClip(load_rect_); JA_PlayMusic(loading_sound3_); } } // 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_->setSpriteClip(load_rect_); color_loading_screen_sprite_->setRect(load_rect_); // Comprueba si ha terminado la intro if (load_counter_ >= 768) { options.section.name = 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(loading_sound2_); } } // Dibuja la pantalla de carga void LoadingScreen::renderLoad() { loading_first_part_ ? mono_loading_screen_sprite_->render() : color_loading_screen_sprite_->render(); } // Dibuja el efecto de carga en el borde void LoadingScreen::renderBorder() { // Pinta el borde de colro azul color_t color = stringToColor(options.palette, "blue"); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); SDL_RenderClear(renderer_); // Añade lineas amarillas color = stringToColor(options.palette, "yellow"); SDL_SetRenderDrawColor(renderer_, color.r, color.g, color.b, 0xFF); const int width = GAMECANVAS_WIDTH + (options.borderWidth * 2); const int height = GAMECANVAS_HEIGHT + (options.borderHeight * 2); bool drawEnabled = rand() % 2 == 0 ? true : false; // Para (int i = 0; i < height; ++i) //{ // if (rand() % 2 == 0) // { // SDL_RenderDrawLine(renderer, 0, i, width, i); // } // } int row = 0; int rowSize = 1; while (row < height) { rowSize = (rand() % 4) + 3; if (drawEnabled) for (int i = row; i < row + rowSize; ++i) { SDL_RenderDrawLine(renderer_, 0, i, width, i); } row += rowSize; drawEnabled = !drawEnabled; } } // Actualiza las variables void LoadingScreen::update() { // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego if (SDL_GetTicks() - ticks_ > ticks_speed_) { // Actualiza el contador de ticks ticks_ = SDL_GetTicks(); // Comprueba las entradas checkInput(); // Gestiona el contador interno updateCounter(); // Gestiona el contador de carga updateLoad(); // Actualiza las notificaciones screen_->updateNotifier(); } } // Dibuja en pantalla void LoadingScreen::render() { if (options.borderEnabled) { // Prepara para empezar a dibujar en la textura del borde screen_->startDrawOnBorder(); // Dibuja el efecto de carga en el borde renderBorder(); } // Prepara para empezar a dibujar en la textura de juego screen_->start(); // Dibuja la pantalla de carga renderLoad(); // Vuelca el contenido del renderizador en pantalla screen_->render(); } // Bucle para el logo del juego void LoadingScreen::run() { // Inicia el sonido de carga JA_SetVolume(64); JA_PlayMusic(loading_sound1_); // Limpia la pantalla screen_->start(); screen_->clean(); screen_->render(); while (options.section.name == SECTION_LOADING_SCREEN) { update(); checkEvents(); render(); } JA_SetVolume(128); } // Cambia la paleta void LoadingScreen::switchPalette() { if (options.palette == p_zxspectrum) { options.palette = p_zxarne; mono_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_bn_zxarne.png")); color_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_color_zxarne.png")); } else { options.palette = p_zxspectrum; mono_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_bn.png")); color_loading_screen_sprite_->setTexture(resource_->getTexture("loading_screen_color.png")); } recreateLoadingScreen(); } // Reconstruye la pantalla de carga void LoadingScreen::recreateLoadingScreen() { // Prepara para empezar a dibujar en la textura de juego screen_->start(); // Primera parte de la carga, la parte en blanco y negro if (loading_first_part_) { const int numSteps = 5; const int step = 51; for (int i = 0; i <= counter_; i++) { load_counter_ = i / numSteps; load_rect_.x = step * (i % numSteps); load_rect_.y = line_index_[load_counter_]; mono_loading_screen_sprite_->setSpriteClip(load_rect_); mono_loading_screen_sprite_->setRect(load_rect_); mono_loading_screen_sprite_->render(); } } // Segunda parte de la carga, la parte de los bloques en color else { for (int i = 0; i <= load_counter_; i++) { load_rect_.x = (i * 8) % 256; load_rect_.y = (i / 32) * 8; color_loading_screen_sprite_->setSpriteClip(load_rect_); color_loading_screen_sprite_->setRect(load_rect_); color_loading_screen_sprite_->render(); } } // Vuelca el contenido del renderizador en pantalla screen_->render(); }