#include "hiscore_table.h" #include "common/jscore.h" #include const Uint8 SELF = 0; // Constructor HiScoreTable::HiScoreTable(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Lang *lang, options_t *options, section_t *section) { // Copia los punteros this->renderer = renderer; this->screen = screen; this->asset = asset; this->input = input; this->lang = lang; this->section = section; this->options = options; // Reserva memoria para los punteros eventHandler = new SDL_Event(); text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); // Crea un backbuffer para el renderizador backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT); if (backbuffer == nullptr) { if (options->console) { std::cout << "Error: textTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } } // Inicializa variables section->name = SELF; ticks = 0; ticksSpeed = 15; manualQuit = false; counter = 0; counterEnd = 600; } // Destructor HiScoreTable::~HiScoreTable() { delete eventHandler; delete text; SDL_DestroyTexture(backbuffer); } // Actualiza las variables void HiScoreTable::update() { // Comprueba los eventos checkEventHandler(); // Comprueba las entradas checkInput(); // Actualiza las variables if (SDL_GetTicks() - ticks > ticksSpeed) { // Actualiza el contador de ticks ticks = SDL_GetTicks(); // Actualiza las notificaciones screen->updateNotifier(); if (mode == mhst_auto) { // Modo automático counter++; if (counter == counterEnd) { section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_1; } } else { // Modo manual ++counter %= 60000; if (manualQuit) { section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_3; } } } } // Pinta en pantalla void HiScoreTable::render() { // Pinta en pantalla SDL_Rect window = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; const color_t orangeColor = {0xFF, 0x7A, 0x00}; // hay 27 letras - 7 de puntos quedan 20 caracteres 20 - nameLenght 0 numDots const int spaceBetweenHeader = 32; const int spaceBetweenLines = text->getCharacterSize() * 1.8f; // Pinta en el backbuffer el texto y los sprites SDL_SetRenderTarget(renderer, backbuffer); SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_RenderClear(renderer); // Escribe el texto: Mejores puntuaciones text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, 8, lang->getText(42), 1, orangeColor, 1, shdwTxtColor); // Escribe la lista de jugadores int numUsers = jscore::getNumUsers(); for (int i = 0; i < numUsers; ++i) { const std::string userName = jscore::getUserName(i).substr(0, 17); const int nameLenght = (int)userName.length(); const int numDots = 20 - nameLenght; std::string dots = ""; for (int j = 0; j < numDots; ++j) { dots = dots + "."; } const std::string line = userName + dots + scoreToString(jscore::getPoints(i)); text->writeDX(TXT_CENTER | TXT_SHADOW, GAMECANVAS_CENTER_X, (i * spaceBetweenLines) + spaceBetweenHeader, line, 1, orangeColor, 1, shdwTxtColor); } // Rellena la lista con otros nombres if (numUsers < 10) { std::vector names; names.insert(names.end(), {"Bry", "Usufondo", "G.Lucas", "P.Delgat", "P.Arrabalera", "Pelechano", "Sahuquillo", "Bacteriol", "Pepe", "Rosita"}); for (int i = numUsers; i < 10; ++i) { const int nameLenght = names[i - numUsers].length(); const int numDots = 20 - nameLenght; std::string dots = ""; for (int j = 0; j < numDots; ++j) { dots = dots + "."; } const std::string line = names[i - numUsers] + dots + "0000000"; text->writeDX(TXT_CENTER | TXT_SHADOW, GAMECANVAS_CENTER_X, (i * spaceBetweenLines) + spaceBetweenHeader, line, 1, orangeColor, 1, shdwTxtColor); } } if ((mode == mhst_manual) && (counter % 50 > 14)) { text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, GAMECANVAS_CENTER_X, GAMECANVAS_HEIGHT - 12, lang->getText(22), 1, orangeColor, 1, shdwTxtColor); } // Cambia el destino de renderizado SDL_SetRenderTarget(renderer, nullptr); // Prepara para empezar a dibujar en la textura de juego screen->start(); // Limpia la pantalla screen->clean(bgColor); // Establece la ventana del backbuffer if (mode == mhst_auto) { window.y = std::max(8, GAMECANVAS_HEIGHT - counter + 100); } else { window.y = 0; } // Copia el backbuffer al renderizador SDL_RenderCopy(renderer, backbuffer, nullptr, &window); // Vuelca el contenido del renderizador en pantalla screen->blit(); } // Comprueba los eventos void HiScoreTable::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 HiScoreTable::checkInput() { if (input->checkInput(input_exit, REPEAT_FALSE)) { section->name = SECTION_PROG_QUIT; } else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE)) { screen->switchVideoMode(); } 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_pause, REPEAT_FALSE) || input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_fire_left, REPEAT_FALSE) || input->checkInput(input_fire_center, REPEAT_FALSE) || input->checkInput(input_fire_right, REPEAT_FALSE)) { if (mode == mhst_auto) { JA_StopMusic(); section->name = SECTION_PROG_TITLE; section->subsection = SUBSECTION_TITLE_1; } else { if (counter > 30) { manualQuit = true; } } } } // Bucle para la pantalla de instrucciones void HiScoreTable::run(mode_hiScoreTable_e mode) { this->mode = mode; while (section->name == SELF) { update(); render(); } } // Transforma un valor numérico en una cadena de 6 cifras std::string HiScoreTable::scoreToString(Uint32 num) { if ((num >= 0) && (num <= 9)) { return ("000000" + std::to_string(num)); } if ((num >= 10) && (num <= 99)) { return ("00000" + std::to_string(num)); } if ((num >= 100) && (num <= 999)) { return ("0000" + std::to_string(num)); } if ((num >= 1000) && (num <= 9999)) { return ("000" + std::to_string(num)); } if ((num >= 010000) && (num <= 99999)) { return ("00" + std::to_string(num)); } if ((num >= 100000) && (num <= 999999)) { return ("0" + std::to_string(num)); } if ((num >= 1000000) && (num <= 9999999)) { return (std::to_string(num)); } return (std::to_string(num)); }