#include "intro.h" // Constructor Intro::Intro(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, Input *input, options_t *options, section_t *section) { // Copia la dirección de los objetos this->resource = resource; this->renderer = renderer; this->screen = screen; this->asset = asset; this->input = input; this->options = options; this->section = section; // Reserva memoria para los punteros eventHandler = new SDL_Event(); if (options->palette == p_zxspectrum) { loadingScreenTexture1 = resource->getTexture("loading_screen_bn.png"); loadingScreenTexture2 = resource->getTexture("loading_screen_color.png"); } else if (options->palette == p_zxarne) { loadingScreenTexture1 = resource->getTexture("loading_screen_bn_zxarne.png"); loadingScreenTexture2 = resource->getTexture("loading_screen_color_zxarne.png"); } sprite1 = new Sprite(0, 0, loadingScreenTexture1->getWidth(), loadingScreenTexture1->getHeight(), loadingScreenTexture1, renderer); sprite2 = new Sprite(0, 0, loadingScreenTexture2->getWidth(), loadingScreenTexture2->getHeight(), loadingScreenTexture2, renderer); loadingSound1 = JA_LoadMusic(asset->get("loading_sound1.ogg").c_str()); loadingSound2 = JA_LoadMusic(asset->get("loading_sound2.ogg").c_str()); loadingSound3 = JA_LoadMusic(asset->get("loading_sound3.ogg").c_str()); // Inicializa variables preCounter = 0; counter = 0; section->name = SECTION_PROG_INTRO; section->subsection = 0; ticks = 0; ticksSpeed = 15; loadCounter = 0; loadingFirstPart = true; loadRect = {0, 0, 51, 1}; // 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 lineIndex[i] = ((i % 8) * 8) + (i / 8); } else if (i >= 64 && i < 128) { // Segundo bloque de 2K lineIndex[i] = 64 + ((i % 8) * 8) + ((i - 64) / 8); } else if (i >= 128 && i < 192) { // tercer bloque de 2K lineIndex[i] = 128 + ((i % 8) * 8) + ((i - 128) / 8); } } // Cambia el color del borde screen->setBorderColor(stringToColor(options->palette, "black")); } // Destructor Intro::~Intro() { delete sprite1; delete sprite2; delete eventHandler; JA_DeleteMusic(loadingSound1); JA_DeleteMusic(loadingSound2); JA_DeleteMusic(loadingSound3); } // Comprueba el manejador de eventos void Intro::checkEventHandler() { // 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) { section->name = SECTION_PROG_QUIT; break; } } } // Comprueba las entradas void Intro::checkInput() { if (input->checkInput(input_exit, REPEAT_FALSE)) { section->name = SECTION_PROG_QUIT; } else if (input->checkInput(input_toggle_border, REPEAT_FALSE)) { screen->switchBorder(); } else if (input->checkInput(input_video_mode, REPEAT_FALSE)) { screen->switchVideoMode(); } else if (input->checkInput(input_window_size_1, REPEAT_FALSE)) { screen->setWindowSize(1); } else if (input->checkInput(input_window_size_2, REPEAT_FALSE)) { screen->setWindowSize(2); } else if (input->checkInput(input_window_size_3, REPEAT_FALSE)) { screen->setWindowSize(3); } else if (input->checkInput(input_window_size_4, REPEAT_FALSE)) { screen->setWindowSize(4); } else if (input->checkInput(input_swap_palette, REPEAT_FALSE)) { switchPalette(); } else if (input->checkInput(input_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_jump, REPEAT_FALSE)) { section->name = SECTION_PROG_TITLE; section->subsection = 0; } } // Gestiona el contador de carga void Intro::updateLoad() { // Primera parte de la carga, la parte en blanco y negro if (loadingFirstPart) { // Cada 5 pasos el loadCounter se incrementa en uno const int numSteps = 5; const int step = 51; loadCounter = counter / numSteps; if (loadCounter < 192) { loadRect.x = step * (counter % numSteps); loadRect.y = lineIndex[loadCounter]; sprite1->setSpriteClip(loadRect); sprite1->setRect(loadRect); } // Una vez actualizadas las 192 lineas, pasa a la segunda fase de la carga else if (loadCounter == 192) { loadingFirstPart = false; loadCounter = 0; loadRect = {0, 0, 16, 8}; sprite2->setRect(loadRect); sprite2->setSpriteClip(loadRect); JA_PlayMusic(loadingSound3); } } // Segunda parte de la carga, la parte de los bloques en color else { loadCounter += 2; loadRect.x = (loadCounter * 8) % 256; loadRect.y = (loadCounter / 32) * 8; sprite2->setSpriteClip(loadRect); sprite2->setRect(loadRect); // Comprueba si ha terminado la intro if (loadCounter >= 768) { section->name = SECTION_PROG_TITLE; section->subsection = 0; JA_StopMusic(); } } } // Gestiona el contador interno void Intro::updateCounter() { (preCounter >= 50) ? counter++ : preCounter++; if (counter == 1) { JA_PlayMusic(loadingSound2); } } // Dibuja la pantalla de carga void Intro::renderLoad() { loadingFirstPart ? sprite1->render() : sprite2->render(); } // Actualiza las variables void Intro::update() { // Comprueba el manejador de eventos checkEventHandler(); // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego if (SDL_GetTicks() - ticks > ticksSpeed) { // 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 Intro::render() { // 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->blit(); } // Bucle para el logo del juego void Intro::run() { // Inicia el sonido de carga JA_SetVolume(64); JA_PlayMusic(loadingSound1); while (section->name == SECTION_PROG_INTRO) { update(); render(); } JA_SetVolume(128); } // Cambia la paleta void Intro::switchPalette() { if (options->palette == p_zxspectrum) { options->palette = p_zxarne; sprite1->setTexture(resource->getTexture("loading_screen_bn_zxarne.png")); sprite2->setTexture(resource->getTexture("loading_screen_color_zxarne.png")); } else { options->palette = p_zxspectrum; sprite1->setTexture(resource->getTexture("loading_screen_bn.png")); sprite2->setTexture(resource->getTexture("loading_screen_color.png")); } recreateLoadingScreen(); } // Reconstruye la pantalla de carga void Intro::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 (loadingFirstPart) { const int numSteps = 5; const int step = 51; for (int i = 0; i <= counter; i++) { loadCounter = i / numSteps; loadRect.x = step * (i % numSteps); loadRect.y = lineIndex[loadCounter]; sprite1->setSpriteClip(loadRect); sprite1->setRect(loadRect); sprite1->render(); } } // Segunda parte de la carga, la parte de los bloques en color else { for (int i = 0; i <= loadCounter; i++) { loadRect.x = (i * 8) % 256; loadRect.y = (i / 32) * 8; sprite2->setSpriteClip(loadRect); sprite2->setRect(loadRect); sprite2->render(); } } // Vuelca el contenido del renderizador en pantalla screen->blit(); }