433 lines
12 KiB
C++
433 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("gauntlet.txt"), resource->getTexture("gauntlet.png"), renderer);
|
|
infoText = new Text(resource->getOffset("debug.txt"), resource->getTexture("debug.png"), renderer);
|
|
|
|
// Crea la textura para los graficos que aparecen en el fondo de la pantalla de titulo
|
|
bgTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
|
|
if (bgTexture == nullptr)
|
|
{
|
|
if (options->console)
|
|
{
|
|
std::cout << "Error: bgTexture could not be created!\nSDL Error: " << SDL_GetError() << std::endl;
|
|
}
|
|
}
|
|
SDL_SetTextureBlendMode(bgTexture, SDL_BLENDMODE_BLEND);
|
|
|
|
// Inicializa variables
|
|
counter = 0;
|
|
section->name = SECTION_PROG_TITLE;
|
|
section->subsection = 0;
|
|
ticks = 0;
|
|
ticksSpeed = 15;
|
|
marqueeSpeed = 3;
|
|
initMarquee();
|
|
showCheevos = false;
|
|
|
|
// 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"));
|
|
|
|
// Rellena la textura de fondo con todos los gráficos
|
|
fillTexture();
|
|
}
|
|
|
|
// Destructor
|
|
Title::~Title()
|
|
{
|
|
delete cheevos;
|
|
delete eventHandler;
|
|
delete sprite;
|
|
delete cheevosSprite;
|
|
delete cheevosTexture;
|
|
delete text;
|
|
delete infoText;
|
|
SDL_DestroyTexture(bgTexture);
|
|
}
|
|
|
|
// 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->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 la textura de fondo
|
|
SDL_RenderCopy(renderer, bgTexture, nullptr, nullptr);
|
|
|
|
// Dibuja la marquesina
|
|
renderMarquee();
|
|
|
|
// 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;
|
|
}
|
|
|
|
// Rellena la textura de fondo con todos los gráficos
|
|
void Title::fillTexture()
|
|
{
|
|
// Coloca el puntero del renderizador sobre la textura
|
|
SDL_SetRenderTarget(renderer, bgTexture);
|
|
|
|
// Rellena la textura de color
|
|
const color_t c = stringToColor(options->palette, "black");
|
|
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, 0xFF);
|
|
SDL_RenderClear(renderer);
|
|
|
|
// Pinta el grafico del titulo a partir del sprite
|
|
sprite->setSpriteClip(0, 0, sprite->getWidth(), 63);
|
|
sprite->render();
|
|
|
|
sprite->setPosY(64);
|
|
sprite->setSpriteClip(0, 64, 5, 16);
|
|
sprite->render();
|
|
|
|
sprite->setPosX(16);
|
|
sprite->setSpriteClip(16, 64, 37, 8);
|
|
sprite->render();
|
|
|
|
sprite->setPosX(251);
|
|
sprite->setSpriteClip(251, 64, 5, 16);
|
|
sprite->render();
|
|
|
|
sprite->setPosX(203);
|
|
sprite->setSpriteClip(203, 64, 33, 8);
|
|
sprite->render();
|
|
|
|
// Escribe el texto en la textura
|
|
const color_t textColor = stringToColor(options->palette, "green");
|
|
const int textSize = text->getCharacterSize();
|
|
text->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, 11 * textSize, "1. PLAY", 1, textColor);
|
|
text->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, 13 * textSize, "2. ACHIEVEMENTS", 1, textColor);
|
|
text->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, 15 * textSize, "3. ONLINE MODE", 1, textColor);
|
|
text->writeDX(TXT_CENTER | TXT_COLOR, PLAY_AREA_CENTER_X, 18 * textSize, "ESC. EXIT GAME", 1, textColor);
|
|
|
|
// Devuelve el puntero del renderizador a su sitio
|
|
SDL_SetRenderTarget(renderer, nullptr);
|
|
} |