Files
jaildoctors_dilemma/source/title.cpp

408 lines
12 KiB
C++

#include "title.h"
// Constructor
Title::Title(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();
cheevos = new Cheevos(screen, options, asset->get("cheevos.bin"));
if (options->palette == p_zxspectrum)
{
texture = resource->getTexture("loading_screen_color.png");
}
else if (options->palette == p_zxarne)
{
texture = resource->getTexture("loading_screen_color_zxarne.png");
}
sprite = new Sprite(0, 0, texture->getWidth(), texture->getHeight(), texture, renderer);
text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);
infoText = new Text(resource->getOffset("debug.txt"), resource->getTexture("debug.png"), renderer);
// Inicializa variables
counter = 0;
section->name = SECTION_PROG_TITLE;
section->subsection = 0;
ticks = 0;
ticksSpeed = 15;
marqueeSpeed = 3;
initMarquee();
showCheevos = false;
// Crea el cartel de PRESS ENTER
#ifdef GAME_CONSOLE
const std::string caption = "PRESS START TO PLAY";
#else
const std::string caption = "PRESS ENTER TO PLAY";
#endif
const color_t textColor = stringToColor(options->palette, "white");
const color_t strokeColor = stringToColor(options->palette, "bright_blue");
// Crea la textura
pressEnterTexture = new Texture(renderer);
pressEnterTexture->createBlank(renderer, text->lenght(caption) + 2, text->getCharacterSize() + 2, SDL_TEXTUREACCESS_TARGET);
pressEnterTexture->setAsRenderTarget(renderer);
pressEnterTexture->setBlendMode(SDL_BLENDMODE_BLEND);
text->writeDX(TXT_COLOR | TXT_STROKE, 1, 1, caption, 1, textColor, 1, strokeColor);
// Crea el sprite
pressEnterSprite = new Sprite(128 - (pressEnterTexture->getWidth() / 2), 192 / 5 * 4, pressEnterTexture->getWidth(), pressEnterTexture->getHeight(), pressEnterTexture, renderer);
// Crea la textura con el listado de logros
const std::vector<cheevos_t> cheevosList = cheevos->list();
const int iconSize = 16; // Altura del icono que representa a cada logro
const int cheevoHeight = iconSize + 2; // EL espacio que ocupa cada logro es igual a la altura del icono mas dos pixeles de separación
const int cheevosTextureWidth = 200;
const int cheevosTextureViewHeight = GAMECANVAS_HEIGHT - 32;
cheevosTexture = new Texture(renderer);
cheevosTexture->createBlank(renderer, cheevosTextureWidth, cheevoHeight * cheevosList.size(), SDL_TEXTUREACCESS_TARGET);
cheevosTexture->setAsRenderTarget(renderer);
cheevosTexture->setBlendMode(SDL_BLENDMODE_BLEND);
const color_t cheevosBGColor = stringToColor(options->palette, "blue");
SDL_SetRenderDrawColor(renderer, cheevosBGColor.r, cheevosBGColor.g, cheevosBGColor.b, 0xFF);
SDL_RenderClear(renderer);
const std::string cheevosListCaption = "ACHIEVEMENTS (" + std::to_string(cheevos->unlocked()) + " / " + std::to_string(cheevos->count()) + ")";
infoText->writeDX(TXT_CENTER | TXT_COLOR, cheevosTexture->getWidth() / 2, 2, cheevosListCaption, 1, stringToColor(options->palette, "bright_white"));
int pos = 9;
const color_t cheevoLockedColor = stringToColor(options->palette, "white");
const color_t cheevoUnlockedColor = stringToColor(options->palette, "bright_white");
color_t cheevoColor;
Texture *iconTexture = new Texture(renderer, asset->get("notify.png"));
Sprite *sp = new Sprite({0, 0, iconSize, iconSize}, iconTexture, renderer);
for (auto cheevo : cheevosList)
{
cheevoColor = cheevo.completed ? cheevoUnlockedColor : cheevoLockedColor;
sp->setPos({2, pos, iconSize, iconSize});
sp->setSpriteClip({iconSize * 2, 0, iconSize, iconSize});
sp->getTexture()->setColor(cheevoColor.r, cheevoColor.g, cheevoColor.b);
sp->render();
pos += 2;
infoText->writeColored(2 + iconSize + 2, pos, cheevo.caption, cheevoColor);
pos += 6;
infoText->writeColored(2 + iconSize + 2, pos, cheevo.description, cheevoColor);
pos += 9;
}
delete sp;
delete iconTexture;
// Crea el sprite para el listado de logros
cheevosSprite = new Sprite((GAMECANVAS_WIDTH - cheevosTexture->getWidth()) / 2, (GAMECANVAS_HEIGHT - cheevosTextureViewHeight) / 2, cheevosTexture->getWidth(), cheevosTexture->getHeight(), cheevosTexture, renderer);
cheevosTextureView = {0, 0, cheevosTexture->getWidth(), cheevosTextureViewHeight};
cheevosSprite->setSpriteClip(cheevosTextureView);
// Cambia el color del borde
screen->setBorderColor(stringToColor(options->palette, "black"));
}
// Destructor
Title::~Title()
{
delete cheevos;
delete eventHandler;
delete sprite;
delete pressEnterSprite;
delete pressEnterTexture;
delete cheevosSprite;
delete cheevosTexture;
delete text;
delete infoText;
}
// Inicializa la marquesina
void Title::initMarquee()
{
letters.clear();
longText = "HEY JAILERS!! IT'S 2022 AND WE'RE STILL ROCKING LIKE IT'S 1998!!! HAVE YOU HEARD IT? JAILGAMES ARE BACK!! YEEESSS BACK!! MORE THAN 10 TITLES ON JAILDOC'S KITCHEN!! THATS A LOOOOOOT OF JAILGAMES, BUT WHICH ONE WILL STRIKE FIRST? THERE IS ALSO A NEW DEVICE TO COME THAT WILL BLOW YOUR MIND WITH JAILGAMES ON THE GO: P.A.C.O. BUT WAIT! WHAT'S THAT BEAUTY I'M SEEING RIGHT OVER THERE?? OOOH THAT TINY MINIASCII IS PURE LOVE!! I WANT TO LICK EVERY BYTE OF IT!! OH SHIT! AND DON'T FORGET TO BRING BACK THOSE OLD AND FAT MS-DOS JAILGAMES TO GITHUB TO KEEP THEM ALIVE!! WHAT WILL BE THE NEXT JAILDOC RELEASE? WHAT WILL BE THE NEXT PROJECT TO COME ALIVE?? OH BABY WE DON'T KNOW BUT HERE YOU CAN FIND THE ANSWER, YOU JUST HAVE TO COMPLETE JAILDOCTOR'S DILEMMA ... COULD YOU?";
for (int i = 0; i < (int)longText.length(); ++i)
{
letter_t l;
l.letter = longText.substr(i, 1);
l.x = 256;
l.enabled = false;
letters.push_back(l);
}
letters[0].enabled = true;
}
// Comprueba el manejador de eventos
void Title::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;
}
if (eventHandler->type == SDL_KEYDOWN)
{
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_A:
showCheevos = !showCheevos;
break;
case SDL_SCANCODE_Z:
runEnterID();
break;
default:
break;
}
}
}
}
// Comprueba las entradas
void Title::checkInput()
{
if (showCheevos)
{
if (input->checkInput(input_down, REPEAT_TRUE))
{
moveCheevosList(1);
}
else if (input->checkInput(input_up, REPEAT_TRUE))
{
moveCheevosList(0);
}
}
if (input->checkInput(input_exit, REPEAT_FALSE))
{
section->name = SECTION_PROG_QUIT;
}
else if (input->checkInput(input_toggle_border, REPEAT_FALSE))
{
screen->switchBorder();
resource->reLoadTextures();
}
else if (input->checkInput(input_window_fullscreen, REPEAT_FALSE))
{
screen->switchVideoMode();
resource->reLoadTextures();
}
else if (input->checkInput(input_window_dec_size, REPEAT_FALSE))
{
screen->decWindowSize();
resource->reLoadTextures();
}
else if (input->checkInput(input_window_inc_size, REPEAT_FALSE))
{
screen->incWindowSize();
resource->reLoadTextures();
}
else if (input->checkInput(input_swap_palette, REPEAT_FALSE))
{
switchPalette();
}
else if (input->checkInput(input_accept, REPEAT_FALSE) || input->checkInput(input_pause, REPEAT_FALSE))
{
section->name = SECTION_PROG_GAME;
section->subsection = 0;
}
}
// Actualiza la marquesina
void Title::updateMarquee()
{
for (int i = 0; i < (int)letters.size(); ++i)
{
if (letters[i].enabled)
{
letters[i].x -= marqueeSpeed;
if (letters[i].x < -10)
{
letters[i].enabled = false;
}
}
else
{
if (i > 0 && letters[i - 1].x < 256 && letters[i - 1].enabled)
{
letters[i].enabled = true;
letters[i].x = letters[i - 1].x + text->lenght(letters[i - 1].letter) + 1;
}
}
}
}
// Dibuja la marquesina
void Title::renderMarquee()
{
for (auto l : letters)
{
if (l.enabled)
{
text->writeColored(l.x, 184, l.letter, stringToColor(options->palette, "white"));
}
}
}
// Dibuja la linea de información inferior
void Title::renderInfo()
{
const std::string loginText = options->online.enabled ? "OnLine: " + options->online.jailerID : "OnLine: OFF";
// infoText->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_FIRST_QUARTER_X, 1, loginText, 1, stringToColor(options->palette, "white"));
// infoText->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, 1, "H: Help", 1, stringToColor(options->palette, "white"));
// infoText->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_THIRD_QUARTER_X, 1, "A: Achievements", 1, stringToColor(options->palette, "white"));
infoText->write(1, 1, loginText);
const std::string version = "v.1.09";
const int x = GAMECANVAS_WIDTH - infoText->lenght(version) - 1;
infoText->write(x, 1, version);
}
// Actualiza las variables
void Title::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 las entradas
checkInput();
// Incrementa el contador
counter++;
// Actualiza la marquesina
updateMarquee();
// Actualiza las notificaciones
screen->updateNotifier();
// Comprueba si ha terminado la marquesina y acaba con el titulo
if (letters[letters.size() - 1].x < -10)
{
if (!showCheevos)
{
section->name = SECTION_PROG_CREDITS;
section->subsection = 0;
}
else
{
// Inicializa la marquesina
initMarquee();
}
}
}
}
// Dibuja en pantalla
void Title::render()
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Dibuja el fondo del titulo
sprite->render();
// Dibuja el texto de PRESS ENTER TO PLAY
if (counter % 80 < 60)
{
pressEnterSprite->render();
}
// Dibuja la marquesina
renderMarquee();
// Dibuja la linea de información inferior
renderInfo();
// Dibuja la información de logros
if (showCheevos)
{
cheevosSprite->render();
}
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
// Bucle para el logo del juego
void Title::run()
{
while (section->name == SECTION_PROG_TITLE)
{
update();
checkEvents();
render();
}
}
// Recarga las texturas
void Title::reLoadTextures()
{
// Carga la textura adecuada
if (options->palette == p_zxspectrum)
{
// texture->loadFromFile(asset->get("loading_screen_color.png"), renderer);
texture = resource->getTexture("loading_screen_color.png");
}
else if (options->palette == p_zxarne)
{
// texture->loadFromFile(asset->get("loading_screen_color_zxarne.png"), renderer);
texture = resource->getTexture("loading_screen_color_zxarne.png");
}
texture->reLoad();
}
// Cambia la paleta
void Title::switchPalette()
{
if (options->palette == p_zxspectrum)
{
options->palette = p_zxarne;
sprite->setTexture(resource->getTexture("loading_screen_color_zxarne.png"));
}
else
{
options->palette = p_zxspectrum;
sprite->setTexture(resource->getTexture("loading_screen_color.png"));
}
// Cambia el color del borde
screen->setBorderColor(stringToColor(options->palette, "bright_blue"));
}
// Desplaza la lista de logros
void Title::moveCheevosList(int direction)
{
cheevosTextureView.y = direction == 0 ? cheevosTextureView.y - 1 : cheevosTextureView.y + 1;
const int bottom = cheevosTexture->getHeight() - cheevosTextureView.h;
if (cheevosTextureView.y < 0)
cheevosTextureView.y = 0;
else if (cheevosTextureView.y > bottom)
cheevosTextureView.y = bottom;
cheevosSprite->setSpriteClip(cheevosTextureView);
}
// Ejecuta la seccion en la que se solicita al usuario su ID online
void Title::runEnterID()
{
enterID = new EnterID(renderer, screen, asset, options, section);
enterID->run();
delete enterID;
}