#include "credits.h" // Constructor Credits::Credits(SDL_Renderer *renderer, Screen *screen, Resource *resource, Asset *asset, options_t *options) { // Copia la dirección de los objetos this->resource = resource; this->renderer = renderer; this->screen = screen; this->asset = asset; this->options = options; // Reserva memoria para los punteros eventHandler = new SDL_Event(); text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer); sprite = new AnimatedSprite(renderer, resource->getAnimation("shine.ani")); // Inicializa variables counter = 0; counterEnabled = true; subCounter = 0; section.name = SECTION_PROG_CREDITS; section.subsection = 0; ticks = 0; ticksSpeed = 15; sprite->setRect({194, 174, 8, 8}); // Cambia el color del borde screen->setBorderColor(stringToColor(options->palette, "black")); // Crea la textura para el texto que se escribe en pantalla textTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); if (textTexture == nullptr) { printf("Error: textTexture could not be created!\nSDL Error: %s\n", SDL_GetError()); } SDL_SetTextureBlendMode(textTexture, SDL_BLENDMODE_BLEND); // Crea la textura para cubrir el rexto coverTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); if (coverTexture == nullptr) { printf("Error: coverTexture could not be created!\nSDL Error: %s\n", SDL_GetError()); } SDL_SetTextureBlendMode(coverTexture, SDL_BLENDMODE_BLEND); // Escribe el texto en la textura fillTexture(); } // Destructor Credits::~Credits() { delete eventHandler; delete text; delete sprite; SDL_DestroyTexture(textTexture); SDL_DestroyTexture(coverTexture); } // Comprueba el manejador de eventos void Credits::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 teclas que se han pulsado if ((eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0) || (eventHandler->type == SDL_JOYBUTTONDOWN)) { switch (eventHandler->key.keysym.scancode) { case SDL_SCANCODE_ESCAPE: section.name = SECTION_PROG_QUIT; break; case SDL_SCANCODE_B: screen->switchBorder(); resource->reLoadTextures(); break; case SDL_SCANCODE_F: screen->switchVideoMode(); resource->reLoadTextures(); break; case SDL_SCANCODE_F1: screen->setWindowSize(1); resource->reLoadTextures(); break; case SDL_SCANCODE_F2: screen->setWindowSize(2); resource->reLoadTextures(); break; case SDL_SCANCODE_F3: screen->setWindowSize(3); resource->reLoadTextures(); break; case SDL_SCANCODE_F4: screen->setWindowSize(4); resource->reLoadTextures(); break; case SDL_SCANCODE_F5: switchPalette(); break; default: section.name = SECTION_PROG_TITLE; section.subsection = 0; break; } } } } // Escribe el texto en la textura void Credits::fillTexture() { // Inicializa los textos texts.clear(); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"INSTRUCTIONS:", stringToColor(options->palette, "yellow")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"HELP JAILDOC TO GET BACK ALL HIS", stringToColor(options->palette, "white")}); texts.push_back({"PROJECTS AND GO TO THE JAIL TO", stringToColor(options->palette, "white")}); texts.push_back({"FINISH THEM", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"KEYS:", stringToColor(options->palette, "yellow")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"USE 'CURSORS' TO MOVE AND JUMP", stringToColor(options->palette, "white")}); texts.push_back({"'F1-F4' TO CHANGE WINDOWS SIZE", stringToColor(options->palette, "white")}); texts.push_back({"'F' TO SWITCH TO FULLSCREEN", stringToColor(options->palette, "white")}); texts.push_back({"'B' TO SWITCH THE BORDER SCREEN", stringToColor(options->palette, "white")}); texts.push_back({"'M' TO TURN ON/OFF THE MUSIC", stringToColor(options->palette, "white")}); texts.push_back({"'ESC' TO LEAVE THE GAME", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"A GAME BY JAILDESIGNER", stringToColor(options->palette, "yellow")}); texts.push_back({"MADE ON SUMMER/FALL 2022", stringToColor(options->palette, "yellow")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")}); texts.push_back({"I LOVE JAILGAMES! ", stringToColor(options->palette, "white")}); texts.push_back({"", stringToColor(options->palette, "white")}); // Rellena la textura de texto SDL_SetRenderTarget(renderer, textTexture); const color_t c = stringToColor(options->palette, "black"); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0x00); SDL_RenderClear(renderer); // Escribe el texto en la textura const int size = text->getCharacterSize(); int i = 0; for (auto t : texts) { text->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, i * size, t.label, 1, t.color); i++; } // Escribe el corazón const int textLenght = text->lenght(texts.at(22).label, 1) - text->lenght(" ", 1); // Se resta el ultimo caracter que es un espacio const int posX = ((PLAY_AREA_WIDTH - textLenght) / 2) + textLenght; text->writeColored(posX, 176, "}", stringToColor(options->palette, "bright_red")); // Recoloca el sprite del brillo sprite->setPosX(posX + 2); SDL_SetRenderTarget(renderer, nullptr); // Rellena la textura que cubre el texto SDL_SetRenderTarget(renderer, coverTexture); SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0x00); SDL_RenderClear(renderer); // Los primeros 8 pixels crea una malla SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF); for (int i = 0; i < 256; i += 2) { SDL_RenderDrawPoint(renderer, i, 0); SDL_RenderDrawPoint(renderer, i, 2); SDL_RenderDrawPoint(renderer, i, 4); SDL_RenderDrawPoint(renderer, i, 6); // SDL_RenderDrawPoint(renderer, i + 1, 1); // SDL_RenderDrawPoint(renderer, i + 1, 3); SDL_RenderDrawPoint(renderer, i + 1, 5); SDL_RenderDrawPoint(renderer, i + 1, 7); } // El resto se rellena de color sólido SDL_Rect rect = {0, 8, 256, 192}; SDL_RenderFillRect(renderer, &rect); SDL_SetRenderTarget(renderer, nullptr); } // Actualiza el contador void Credits::updateCounter() { // Incrementa el contador if (counterEnabled) { counter++; if (counter == 224 || counter == 544 || counter == 672) { counterEnabled = false; } } else { subCounter++; if (subCounter == 100) { counterEnabled = true; subCounter = 0; } } // Comprueba si ha terminado la sección if (counter > 1200) { section.name = SECTION_PROG_DEMO; } } // Actualiza las variables void Credits::update() { // 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 el manejador de eventos checkEventHandler(); // Actualiza el contador updateCounter(); // Actualiza el sprite con el brillo if (counter > 770) { sprite->update(); } } } // Dibuja en pantalla void Credits::render() { // Prepara para empezar a dibujar en la textura de juego screen->start(); // Limpia la pantalla screen->clean(); if (counter < 1150) { // Dibuja la textura con el texto en pantalla SDL_RenderCopy(renderer, textTexture, nullptr, nullptr); // Dibuja la textura que cubre el texto const int offset = std::min(counter / 8, 192 / 2); SDL_Rect srcRect = {1, 0, 254, 190 - (offset * 2)}; SDL_Rect dstRect = {1, offset * 2, 254, 190 - (offset * 2)}; SDL_RenderCopy(renderer, coverTexture, &srcRect, &dstRect); // Dibuja el sprite con el brillo sprite->render(); } // Vuelca el contenido del renderizador en pantalla screen->blit(); } // Bucle para el logo del juego section_t Credits::run() { while (section.name == SECTION_PROG_CREDITS) { update(); render(); } return section; } // Cambia la paleta void Credits::switchPalette() { if (options->palette == p_zxspectrum) { options->palette = p_zxarne; } else { options->palette = p_zxspectrum; } fillTexture(); }