Files
coffee_crisis_arcade_edition/source/hiscore_table.cpp

351 lines
8.3 KiB
C++

#include "hiscore_table.h"
#include "param.h"
#include "options.h"
#include <iostream>
// Constructor
HiScoreTable::HiScoreTable(Screen *screen, Asset *asset, Input *input, section_t *section, JA_Music_t *music)
{
// Copia punteros
this->screen = screen;
this->asset = asset;
this->input = input;
this->section = section;
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_PROG_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_PROG_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_PROG_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_PROG_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_PROG_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_PROG_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(int code)
{
if (screen->notificationsAreActive())
{
section->name = SECTION_PROG_QUIT;
section->options = code;
}
else
{
screen->showNotification(lang::getText(94));
}
}