350 lines
8.2 KiB
C++
350 lines
8.2 KiB
C++
#include "hiscore_table.h"
|
|
#include "param.h"
|
|
#include "options.h"
|
|
#include <iostream>
|
|
|
|
// Constructor
|
|
HiScoreTable::HiScoreTable(Asset *asset, Input *input, JA_Music_t *music)
|
|
{
|
|
// Copia punteros
|
|
screen = Screen::get();
|
|
this->asset = asset;
|
|
this->input = input;
|
|
this->music = music;
|
|
renderer = screen->getRenderer();
|
|
|
|
// Objetos
|
|
eventHandler = new SDL_Event();
|
|
fade = new Fade(renderer);
|
|
background = new Background(renderer, asset);
|
|
text = new Text(asset->get("smb2.gif"), asset->get("smb2.txt"), renderer);
|
|
|
|
// Crea un backbuffer para el renderizador
|
|
backbuffer = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, param.game.width, param.game.height);
|
|
SDL_SetTextureBlendMode(backbuffer, SDL_BLENDMODE_BLEND);
|
|
|
|
// Inicializa variables
|
|
section::name = section::NAME_HI_SCORE_TABLE;
|
|
ticks = 0;
|
|
ticksSpeed = 15;
|
|
counter = 0;
|
|
counterEnd = 800;
|
|
viewArea = {0, 0, param.game.width, param.game.height};
|
|
fadeMode = FADE_IN;
|
|
|
|
// Inicializa objetos
|
|
background->setPos(param.game.gameArea.rect);
|
|
background->setCloudsSpeed(-0.1f);
|
|
background->setGradientNumber(1);
|
|
background->setTransition(0.8f);
|
|
fade->setColor(fadeColor.r, fadeColor.g, fadeColor.b);
|
|
fade->setType(FADE_RANDOM_SQUARE);
|
|
fade->setPost(param.fade.postDuration);
|
|
fade->setMode(fadeMode);
|
|
fade->activate();
|
|
|
|
// Crea el contenido de la textura con la lista de puntuaciones
|
|
fillTexture();
|
|
}
|
|
|
|
// Destructor
|
|
HiScoreTable::~HiScoreTable()
|
|
{
|
|
delete text;
|
|
delete eventHandler;
|
|
delete background;
|
|
|
|
SDL_DestroyTexture(backbuffer);
|
|
}
|
|
|
|
// Actualiza las variables
|
|
void HiScoreTable::update()
|
|
{
|
|
// Actualiza las variables
|
|
if (SDL_GetTicks() - ticks > ticksSpeed)
|
|
{
|
|
// Actualiza el contador de ticks
|
|
ticks = SDL_GetTicks();
|
|
|
|
// Mantiene la música sonando
|
|
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
|
JA_PlayMusic(music);
|
|
|
|
// Actualiza el objeto screen
|
|
screen->update();
|
|
|
|
// Actualiza el fondo
|
|
background->update();
|
|
|
|
// Gestiona el fade
|
|
updateFade();
|
|
|
|
// Gestiona el contador y sus eventos
|
|
counter++;
|
|
|
|
if (counter == 150)
|
|
{
|
|
background->setColor({0, 0, 0});
|
|
background->setAlpha(96);
|
|
}
|
|
|
|
if (counter == counterEnd)
|
|
{
|
|
fade->activate();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Crea el contenido de la textura con la lista de puntuaciones
|
|
void HiScoreTable::fillTexture()
|
|
{
|
|
// hay 27 letras - 7 de puntos quedan 20 caracteres 20 - nameLenght 0 numDots
|
|
const int maxNames = 10;
|
|
const int spaceBetweenHeader = 32;
|
|
const int spaceBetweenLines = text->getCharacterSize() * 2.0f;
|
|
const int size = spaceBetweenHeader + spaceBetweenLines * (maxNames - 1) + text->getCharacterSize();
|
|
const int firstLine = (param.game.height - size) / 2;
|
|
|
|
// Pinta en el backbuffer el texto y los sprites
|
|
SDL_Texture *temp = SDL_GetRenderTarget(renderer);
|
|
SDL_SetRenderTarget(renderer, backbuffer);
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
|
|
SDL_RenderClear(renderer);
|
|
|
|
// Escribe el texto: Mejores puntuaciones
|
|
text->writeDX(TXT_CENTER | TXT_COLOR | TXT_SHADOW, param.game.gameArea.centerX, firstLine, lang::getText(42), 1, orangeColor, 1, shdwTxtColor);
|
|
|
|
// Escribe los nombres de la tabla de puntuaciones
|
|
for (int i = 0; i < maxNames; ++i)
|
|
{
|
|
const int nameLenght = options.game.hiScoreTable[i].name.length();
|
|
const std::string score = format(options.game.hiScoreTable[i].score);
|
|
const int scoreLenght = score.size();
|
|
const int numDots = 25 - nameLenght - scoreLenght;
|
|
std::string dots = "";
|
|
for (int j = 0; j < numDots; ++j)
|
|
{
|
|
dots = dots + ".";
|
|
}
|
|
const std::string line = options.game.hiScoreTable[i].name + dots + score;
|
|
text->writeDX(TXT_CENTER | TXT_SHADOW, param.game.gameArea.centerX, (i * spaceBetweenLines) + firstLine + spaceBetweenHeader, line, 1, orangeColor, 1, shdwTxtColor);
|
|
}
|
|
|
|
// Cambia el destino de renderizado
|
|
SDL_SetRenderTarget(renderer, temp);
|
|
}
|
|
|
|
// Pinta en pantalla
|
|
void HiScoreTable::render()
|
|
{
|
|
// Prepara para empezar a dibujar en la textura de juego
|
|
screen->start();
|
|
|
|
// Limpia la pantalla
|
|
screen->clean(bgColor);
|
|
|
|
// Pinta el fondo
|
|
background->render();
|
|
|
|
// Establece la ventana del backbuffer
|
|
viewArea.y = std::max(0, param.game.height - counter + 100);
|
|
|
|
// Copia el backbuffer al renderizador
|
|
SDL_RenderCopy(renderer, backbuffer, nullptr, &viewArea);
|
|
|
|
fade->render();
|
|
|
|
// Vuelca el contenido del renderizador en pantalla
|
|
screen->blit();
|
|
}
|
|
|
|
// Recarga todas las texturas
|
|
void HiScoreTable::reloadTextures()
|
|
{
|
|
text->reLoadTexture();
|
|
fillTexture();
|
|
}
|
|
|
|
// Comprueba los eventos
|
|
void HiScoreTable::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)
|
|
{
|
|
section::name = section::NAME_QUIT;
|
|
break;
|
|
}
|
|
|
|
// Comprueba si se ha cambiado el tamaño de la ventana
|
|
else if (eventHandler->type == SDL_WINDOWEVENT)
|
|
{
|
|
if (eventHandler->window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
|
|
{
|
|
reloadTextures();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Comprueba las entradas
|
|
void HiScoreTable::checkInput()
|
|
{
|
|
// Comprueba si se sale con el teclado
|
|
if (input->checkInput(input_exit, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_KEYBOARD))
|
|
{
|
|
quit(section::OPTIONS_QUIT_NORMAL);
|
|
return;
|
|
}
|
|
|
|
// Comprueba si se ha pulsado cualquier botón (de los usados para jugar)
|
|
if (input->checkAnyButtonPressed())
|
|
{
|
|
JA_StopMusic();
|
|
section::name = section::NAME_TITLE;
|
|
section::options = section::OPTIONS_TITLE_1;
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < input->getNumControllers(); ++i)
|
|
{
|
|
// Comprueba si se sale con el mando
|
|
if (input->checkModInput(input_service, input_exit, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i))
|
|
{
|
|
quit(section::OPTIONS_QUIT_SHUTDOWN);
|
|
return;
|
|
}
|
|
|
|
// Comprueba si se va a resetear el juego
|
|
if (input->checkModInput(input_service, input_reset, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i))
|
|
{
|
|
section::name = section::NAME_LOGO;
|
|
screen->showNotification("Reset");
|
|
return;
|
|
}
|
|
|
|
// Comprueba si se va a activar o desactivar el audio
|
|
if (input->checkModInput(input_service, input_mute, INPUT_DO_NOT_ALLOW_REPEAT, INPUT_USE_GAMECONTROLLER, i))
|
|
{
|
|
options.audio.sound.enabled = options.audio.music.enabled = !options.audio.music.enabled;
|
|
JA_EnableMusic(options.audio.music.enabled);
|
|
JA_EnableSound(options.audio.sound.enabled);
|
|
screen->showNotification("Audio " + boolToOnOff(options.audio.music.enabled));
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Comprueba el input para el resto de objetos
|
|
screen->checkInput();
|
|
}
|
|
|
|
// Bucle para la pantalla de instrucciones
|
|
void HiScoreTable::run()
|
|
{
|
|
while (section::name == section::NAME_HI_SCORE_TABLE)
|
|
{
|
|
checkInput();
|
|
update();
|
|
checkEvents(); // Tiene que ir antes del render
|
|
render();
|
|
}
|
|
}
|
|
|
|
// Transforma un valor numérico en una cadena de 6 cifras
|
|
std::string HiScoreTable::scoreToString(int 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));
|
|
}
|
|
|
|
// Gestiona el fade
|
|
void HiScoreTable::updateFade()
|
|
{
|
|
fade->update();
|
|
|
|
if (fade->hasEnded() && fadeMode == FADE_IN)
|
|
{
|
|
fade->reset();
|
|
fadeMode = FADE_OUT;
|
|
fade->setMode(fadeMode);
|
|
}
|
|
|
|
if (fade->hasEnded() && fadeMode == FADE_OUT)
|
|
{
|
|
section::name = section::NAME_INSTRUCTIONS;
|
|
}
|
|
}
|
|
|
|
// Convierte un entero a un string con separadores de miles
|
|
std::string HiScoreTable::format(int number)
|
|
{
|
|
const std::string separator = ".";
|
|
const std::string score = std::to_string(number);
|
|
|
|
int index = (int)score.size() - 1;
|
|
std::string result = "";
|
|
int i = 0;
|
|
while (index >= 0)
|
|
{
|
|
result = score.at(index) + result;
|
|
index--;
|
|
i++;
|
|
if (i == 3)
|
|
{
|
|
i = 0;
|
|
result = separator + result;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Termina
|
|
void HiScoreTable::quit(section::options_e code)
|
|
{
|
|
if (screen->notificationsAreActive())
|
|
{
|
|
section::name = section::NAME_QUIT;
|
|
section::options = code;
|
|
}
|
|
else
|
|
{
|
|
screen->showNotification(lang::getText(94));
|
|
}
|
|
} |