Files
coffee_crisis/source/title.cpp

1136 lines
27 KiB
C++

#include "title.h"
#include "common/jscore.h"
// Constructor
Title::Title(SDL_Renderer *renderer, Screen *screen, Input *input, Asset *asset, options_t *options, Lang *lang, section_t section)
{
// Copia las direcciones de los punteros
this->renderer = renderer;
this->screen = screen;
this->input = input;
this->asset = asset;
this->options = options;
this->lang = lang;
this->section = section;
// Reserva memoria para los punteros
eventHandler = new SDL_Event();
fade = new Fade(renderer);
dustTexture = new Texture(renderer, asset->get("title_dust.png"));
coffeeTexture = new Texture(renderer, asset->get("title_coffee.png"));
crisisTexture = new Texture(renderer, asset->get("title_crisis.png"));
gradientTexture = new Texture(renderer, asset->get("title_gradient.png"));
coffeeBitmap = new SmartSprite(coffeeTexture, renderer);
crisisBitmap = new SmartSprite(crisisTexture, renderer);
dustBitmapL = new AnimatedSprite(dustTexture, renderer, asset->get("title_dust.ani"));
dustBitmapR = new AnimatedSprite(dustTexture, renderer, asset->get("title_dust.ani"));
gradient = new Sprite({0, 0, 256, 192}, gradientTexture, renderer);
text1 = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer);
text2 = new Text(asset->get("8bithud.png"), asset->get("8bithud.txt"), renderer);
menu.title = new Menu(renderer, asset, input, asset->get("title.men"));
menu.options = new Menu(renderer, asset, input, asset->get("options.men"));
menu.playerSelect = new Menu(renderer, asset, input, asset->get("player_select.men"));
// Sonidos
crashSound = JA_LoadSound(asset->get("title.wav").c_str());
// Musicas
titleMusic = JA_LoadMusic(asset->get("title.ogg").c_str());
// Inicializa los valores
init();
}
// Destructor
Title::~Title()
{
delete eventHandler;
delete fade;
dustTexture->unload();
delete dustTexture;
coffeeTexture->unload();
delete coffeeTexture;
crisisTexture->unload();
delete crisisTexture;
gradientTexture->unload();
delete gradientTexture;
delete coffeeBitmap;
delete crisisBitmap;
delete dustBitmapL;
delete dustBitmapR;
delete gradient;
delete text1;
delete text2;
delete menu.title;
delete menu.options;
delete menu.playerSelect;
JA_DeleteSound(crashSound);
JA_DeleteMusic(titleMusic);
SDL_DestroyTexture(background);
}
// Inicializa los valores
void Title::init()
{
// Inicializa variables
section.subsection = TITLE_SECTION_1;
counter = TITLE_COUNTER;
backgroundCounter = 0;
backgroundMode = rand() % 2;
menuVisible = false;
menu.active = menu.title;
nextSection.name = PROG_SECTION_GAME;
postFade = 0;
ticks = 0;
ticksSpeed = 15;
fade->init(0x17, 0x17, 0x26);
demo = true;
// Pone valores por defecto a las opciones de control
options->input.clear();
input_t i;
i.id = 0;
i.name = "KEYBOARD";
i.deviceType = INPUT_USE_KEYBOARD;
options->input.push_back(i);
i.id = 0;
i.name = "GAME CONTROLLER";
i.deviceType = INPUT_USE_GAMECONTROLLER;
options->input.push_back(i);
// Comprueba si hay mandos conectados
checkInputDevices();
// Pone valores por defecto. El primer jugador el teclado. El segundo jugador el primer mando
deviceIndex.clear();
deviceIndex.push_back(availableInputDevices.size() - 1); // El último dispositivo encontrado es el teclado
deviceIndex.push_back(0); // El primer mando encontrado. Si no ha encontrado ninguno es el teclado
// Si ha encontrado un mando se lo asigna al segundo jugador
if (input->gameControllerFound())
{
options->input.at(1).id = availableInputDevices.at(deviceIndex.at(1)).id;
options->input.at(1).name = availableInputDevices.at(deviceIndex.at(1)).name;
options->input.at(1).deviceType = availableInputDevices.at(deviceIndex.at(1)).deviceType;
}
// Inicializa el bitmap de Coffee
coffeeBitmap->init();
coffeeBitmap->setPosX(45);
coffeeBitmap->setPosY(11 - 200);
coffeeBitmap->setWidth(167);
coffeeBitmap->setHeight(46);
coffeeBitmap->setVelX(0.0f);
coffeeBitmap->setVelY(2.5f);
coffeeBitmap->setAccelX(0.0f);
coffeeBitmap->setAccelY(0.1f);
coffeeBitmap->setSpriteClip(0, 0, 167, 46);
coffeeBitmap->setEnabled(true);
coffeeBitmap->setEnabledCounter(0);
coffeeBitmap->setDestX(45);
coffeeBitmap->setDestY(11);
// Inicializa el bitmap de Crisis
crisisBitmap->init();
crisisBitmap->setPosX(60);
crisisBitmap->setPosY(57 + 200);
crisisBitmap->setWidth(137);
crisisBitmap->setHeight(46);
crisisBitmap->setVelX(0.0f);
crisisBitmap->setVelY(-2.5f);
crisisBitmap->setAccelX(0.0f);
crisisBitmap->setAccelY(-0.1f);
crisisBitmap->setSpriteClip(0, 0, 137, 46);
crisisBitmap->setEnabled(true);
crisisBitmap->setEnabledCounter(0);
crisisBitmap->setDestX(60);
crisisBitmap->setDestY(57);
// Inicializa el bitmap de DustRight
dustBitmapR->resetAnimation();
dustBitmapR->setPosX(218);
dustBitmapR->setPosY(47);
dustBitmapR->setWidth(16);
dustBitmapR->setHeight(16);
dustBitmapR->setFlip(SDL_FLIP_HORIZONTAL);
// Inicializa el bitmap de DustLeft
dustBitmapL->resetAnimation();
dustBitmapL->setPosX(33);
dustBitmapL->setPosY(47);
dustBitmapL->setWidth(16);
dustBitmapL->setHeight(16);
// Inicializa el sprite con el degradado
gradient->setSpriteClip(0, 96, 256, 192);
// Crea el mosaico de fondo del titulo
createTiledBackground();
// Coloca la ventana que recorre el mosaico de fondo de manera que coincida con el mosaico que hay pintado en el titulo al iniciar
backgroundWindow.x = 128;
backgroundWindow.y = 96;
backgroundWindow.w = GAME_WIDTH;
backgroundWindow.h = GAME_HEIGHT;
// Inicializa los valores del vector con los valores del seno
for (int i = 0; i < 360; ++i)
{
sin[i] = SDL_sinf((float)i * 3.14f / 180.0f);
}
// Actualiza los textos de los menus
updateMenuLabels();
}
// Actualiza las variables del objeto
void Title::update()
{
// Comprueba los eventos
checkEventHandler();
// Calcula la lógica de los objetos
if (SDL_GetTicks() - ticks > ticksSpeed)
{
// Actualiza el contador de ticks
ticks = SDL_GetTicks();
// Actualiza las notificaciones
screen->updateNotifier();
switch (section.subsection)
{
// Sección 1 - Titulo desplazandose
case TITLE_SECTION_1:
{
// Actualiza los objetos
coffeeBitmap->update();
crisisBitmap->update();
// Si los objetos han llegado a su destino, cambiamos de Sección
if (coffeeBitmap->hasFinished() && crisisBitmap->hasFinished())
{
section.subsection = TITLE_SECTION_2;
// Pantallazo blanco
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(renderer);
SDL_RenderPresent(renderer);
// Reproduce el efecto sonoro
JA_PlaySound(crashSound);
}
}
break;
// Sección 2 - Titulo vibrando
case TITLE_SECTION_2:
{
// Agita la pantalla
static const int v[] = {-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 0};
static const int a = coffeeBitmap->getPosX();
static const int b = crisisBitmap->getPosX();
static int step = 0;
coffeeBitmap->setPosX(a + v[step / 3]);
crisisBitmap->setPosX(b + v[step / 3]);
dustBitmapR->update();
dustBitmapL->update();
step++;
if (step == 33)
{
section.subsection = TITLE_SECTION_3;
}
}
break;
// Sección 3 - La pantalla de titulo con el menú y la música
case TITLE_SECTION_3:
{
if (counter > 0)
{ // Reproduce la música
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{
JA_PlayMusic(titleMusic);
}
dustBitmapR->update();
dustBitmapL->update();
// Actualiza la lógica del titulo
fade->update();
if (fade->hasEnded())
{
switch (postFade)
{
case 0: // 1 PLAYER
section.name = PROG_SECTION_GAME;
section.subsection = GAME_SECTION_PLAY_1P;
JA_StopMusic();
break;
case 1: // 2 PLAYERS
section.name = PROG_SECTION_GAME;
section.subsection = GAME_SECTION_PLAY_2P;
JA_StopMusic();
break;
case 2: // QUIT
section.name = PROG_SECTION_QUIT;
JA_StopMusic();
break;
case 3: // TIME OUT
counter = TITLE_COUNTER;
menu.active->reset();
if (demo)
{
runDemoGame();
if (section.name != PROG_SECTION_QUIT)
{
runInstructions(m_auto);
}
if (section.name != PROG_SECTION_QUIT)
{
runHiScoreTable(mhst_auto);
}
}
else
section.name = PROG_SECTION_LOGO;
break;
default:
break;
}
}
// Actualiza el tileado de fondo
updateBG();
// Comprueba las entradas para el menu
if (menuVisible == true)
{
menu.active->update();
}
// Comprueba si se ha seleccionado algún item del menú de titulo
if (menu.active->getName() == "TITLE")
{
switch (menu.active->getItemSelected())
{
case 0: // 1 PLAYER -> Cambia al manu de selección de jugador
menu.active = menu.playerSelect;
break;
case 1: // 2 PLAYERS
postFade = 1;
fade->activateFade();
break;
case 2: // OPTIONS
menu.active = menu.options;
optionsPrevious = *options;
break;
case 3: // QUIT
postFade = 2;
fade->activateFade();
break;
default:
break;
}
}
// Comprueba si se ha seleccionado algún item del menú de selección de jugador
if (menu.active->getName() == "PLAYER_SELECT")
{
switch (menu.active->getItemSelected())
{
case 0:
// Este item no se puede seleccionar y actua de titulo
break;
case 1: // BAL1
postFade = 0;
options->playerSelected = 0;
fade->activateFade();
break;
case 2: // AROUNDER
postFade = 0;
options->playerSelected = 1;
fade->activateFade();
break;
case 3: // BACK
menu.active = menu.title;
menu.playerSelect->reset();
break;
default:
break;
}
}
// Comprueba si se ha seleccionado algún item de opciones
if (menu.active->getName() == "OPTIONS")
{
switch (menu.active->getItemSelected())
{
case 0: // Difficulty
if (options->difficulty == DIFFICULTY_EASY)
options->difficulty = DIFFICULTY_NORMAL;
else if (options->difficulty == DIFFICULTY_NORMAL)
options->difficulty = DIFFICULTY_HARD;
else
options->difficulty = DIFFICULTY_EASY;
updateMenuLabels();
break;
case 1: // PLAYER 1 CONTROLS
updatePlayerInputs(0);
updateMenuLabels();
break;
case 3: // PLAYER 2 CONTROLS
updatePlayerInputs(1);
updateMenuLabels();
break;
case 5: // Language
options->language++;
if (options->language == 3)
options->language = 0;
updateMenuLabels();
break;
case 6: // Display mode
switchFullScreenModeVar();
if (options->videoMode != 0)
{
menu.options->setSelectable(8, false);
menu.options->setGreyed(8, true);
}
else
{
menu.options->setSelectable(8, true);
menu.options->setGreyed(8, false);
}
updateMenuLabels();
break;
case 8: // Windows size
options->windowSize++;
if (options->windowSize == 5)
options->windowSize = 1;
updateMenuLabels();
break;
case 9: // FILTER
if (options->filter == FILTER_LINEAL)
options->filter = FILTER_NEAREST;
else
options->filter = FILTER_LINEAL;
updateMenuLabels();
break;
case 10: // VSYNC
if (options->vSync)
options->vSync = false;
else
options->vSync = true;
updateMenuLabels();
break;
case 11: // HOW TO PLAY
runInstructions(m_manual);
break;
case 12: // ACCEPT
applyOptions();
menu.active->reset();
menu.active = menu.title;
break;
case 13: // CANCEL
options = &optionsPrevious;
updateMenuLabels();
menu.active->reset();
menu.active = menu.title;
break;
default:
break;
}
}
if (menu.active->getName() == "TITLE")
{
counter--;
}
}
else if (counter == 0)
{
if (demo)
{
runDemoGame();
if (section.name != PROG_SECTION_QUIT)
{
runInstructions(m_auto);
}
if (section.name != PROG_SECTION_QUIT)
{
runHiScoreTable(mhst_auto);
}
init();
demo = false;
counter = TITLE_COUNTER;
}
else
{
section.name = PROG_SECTION_LOGO;
}
}
// Sección Instrucciones
if (section.subsection == TITLE_SECTION_INSTRUCTIONS)
{
runInstructions(m_auto);
counter = TITLE_COUNTER;
demo = true;
}
}
break;
default:
break;
}
}
}
// Dibuja el objeto en pantalla
void Title::render()
{
switch (section.subsection)
{
// Sección 1 - Titulo desplazandose
case TITLE_SECTION_1:
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(renderer, background, &backgroundWindow, nullptr);
// Dibuja el degradado
gradient->render();
// Dibuja los objetos
coffeeBitmap->render();
crisisBitmap->render();
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
break;
// Sección 2 - Titulo vibrando
case TITLE_SECTION_2:
{ // Reproduce el efecto sonoro
JA_PlaySound(crashSound);
// Agita la pantalla
const int v[] = {-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 0};
const int a = coffeeBitmap->getPosX();
const int b = crisisBitmap->getPosX();
for (int n = 0; n < 11 * 3; ++n)
{
// Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(renderer, background, &backgroundWindow, nullptr);
// Dibuja el degradado
gradient->render();
// Dibuja los objetos
coffeeBitmap->setPosX(a + v[n / 3]);
crisisBitmap->setPosX(b + v[n / 3]);
coffeeBitmap->render();
crisisBitmap->render();
dustBitmapR->update();
dustBitmapL->update();
dustBitmapR->render();
dustBitmapL->render();
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
section.subsection = TITLE_SECTION_3;
}
break;
// Sección 3 - La pantalla de titulo con el menú y la música
case TITLE_SECTION_3:
{ // Prepara para empezar a dibujar en la textura de juego
screen->start();
// Limpia la pantalla
screen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(renderer, background, &backgroundWindow, nullptr);
// Dibuja el degradado
gradient->render();
// Dibuja los objetos
if (menu.active->getName() != "OPTIONS")
{
// Bitmaps con el logo/titulo del juego
coffeeBitmap->render();
crisisBitmap->render();
// Texto con el copyright y versión
text2->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, GAME_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 1, noColor, 1, shdwTxtColor);
}
if (menuVisible == true)
{
menu.active->render();
}
dustBitmapR->render();
dustBitmapL->render();
// PRESS ANY KEY!
if ((counter % 50 > 14) && (menuVisible == false))
{
text1->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, lang->getText(23), 1, noColor, 1, shdwTxtColor);
}
// Fade
fade->render();
// Vuelca el contenido del renderizador en pantalla
screen->blit();
}
break;
default:
break;
}
}
// Comprueba los eventos
void Title::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 = PROG_SECTION_QUIT;
break;
}
else if (eventHandler->type == SDL_RENDER_DEVICE_RESET || eventHandler->type == SDL_RENDER_TARGETS_RESET)
{
reLoadTextures();
}
else if (eventHandler->type == SDL_KEYDOWN && eventHandler->key.repeat == 0)
{
switch (eventHandler->key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
section.name = PROG_SECTION_QUIT;
break;
case SDL_SCANCODE_F:
screen->switchVideoMode();
reLoadTextures();
break;
case SDL_SCANCODE_F1:
screen->setWindowSize(1);
reLoadTextures();
break;
case SDL_SCANCODE_F2:
screen->setWindowSize(2);
reLoadTextures();
break;
case SDL_SCANCODE_F3:
screen->setWindowSize(3);
reLoadTextures();
break;
case SDL_SCANCODE_F4:
screen->setWindowSize(4);
reLoadTextures();
break;
default:
break;
}
}
if (section.subsection == TITLE_SECTION_3)
{ // Si se pulsa alguna tecla durante la tercera sección del titulo
if ((eventHandler->type == SDL_KEYUP) || (eventHandler->type == SDL_JOYBUTTONUP))
{
// Muestra el menu
menuVisible = true;
// Reinicia el contador
counter = TITLE_COUNTER;
}
}
}
}
// Actualiza el tileado de fondo
void Title::updateBG()
{
if (backgroundMode == 0)
{ // El tileado de fondo se desplaza en diagonal
++backgroundWindow.x %= 64;
++backgroundWindow.y %= 64;
}
else
{ // El tileado de fondo se desplaza en circulo
++backgroundCounter %= 360;
backgroundWindow.x = 128 + (int(sin[(backgroundCounter + 270) % 360] * 128));
backgroundWindow.y = 96 + (int(sin[(360 - backgroundCounter) % 360] * 96));
}
}
// Cambia el valor de la variable de modo de pantalla completa
void Title::switchFullScreenModeVar()
{
switch (options->videoMode)
{
case 0:
options->videoMode = SDL_WINDOW_FULLSCREEN;
break;
case SDL_WINDOW_FULLSCREEN:
options->videoMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
break;
case SDL_WINDOW_FULLSCREEN_DESKTOP:
options->videoMode = 0;
break;
default:
options->videoMode = 0;
break;
}
}
// Actualiza los elementos de los menus
void Title::updateMenuLabels()
{
int i = 0;
// DIFFICULTY
switch (options->difficulty)
{
case DIFFICULTY_EASY:
menu.options->setItemCaption(i, lang->getText(59) + ": " + lang->getText(66)); // EASY
break;
case DIFFICULTY_NORMAL:
menu.options->setItemCaption(i, lang->getText(59) + ": " + lang->getText(67)); // NORMAL
break;
case DIFFICULTY_HARD:
menu.options->setItemCaption(i, lang->getText(59) + ": " + lang->getText(68)); // HARD
break;
default:
menu.options->setItemCaption(i, lang->getText(59) + ": " + lang->getText(67)); // NORMAL
break;
}
i++;
// PLAYER 1 CONTROLS
menu.options->setItemCaption(i, lang->getText(62));
i++;
// PLAYER 1 CONTROLS - OPTIONS
switch (options->input[0].deviceType)
{
case INPUT_USE_KEYBOARD:
menu.options->setItemCaption(i, lang->getText(69)); // KEYBOARD
menu.options->setGreyed(i, false);
break;
case INPUT_USE_GAMECONTROLLER:
menu.options->setItemCaption(i, lang->getText(70)); // GAME CONTROLLER
if (!input->gameControllerFound())
menu.options->setGreyed(i, true);
else
{
menu.options->setGreyed(i, false);
menu.options->setItemCaption(i, options->input[0].name);
}
break;
default:
menu.options->setItemCaption(i, lang->getText(69)); // KEYBOARD
break;
}
i++;
// PLAYER 2 CONTROLS
menu.options->setItemCaption(i, lang->getText(63));
i++;
// PLAYER 2 CONTROLS - OPTIONS
switch (options->input[1].deviceType)
{
case INPUT_USE_KEYBOARD:
menu.options->setItemCaption(i, lang->getText(69)); // KEYBOARD
menu.options->setGreyed(i, false);
break;
case INPUT_USE_GAMECONTROLLER:
menu.options->setItemCaption(i, lang->getText(70)); // GAME CONTROLLER
if (!input->gameControllerFound())
menu.options->setGreyed(i, true);
else
{
menu.options->setGreyed(i, false);
menu.options->setItemCaption(i, options->input[1].name);
}
break;
default:
menu.options->setItemCaption(i, lang->getText(69)); // KEYBOARD
break;
}
i++;
// LANGUAGE
switch (options->language)
{
case es_ES:
menu.options->setItemCaption(i, lang->getText(8) + ": " + lang->getText(24)); // SPANISH
break;
case ba_BA:
menu.options->setItemCaption(i, lang->getText(8) + ": " + lang->getText(25)); // VALENCIAN
break;
case en_UK:
menu.options->setItemCaption(i, lang->getText(8) + ": " + lang->getText(26)); // ENGLISH
break;
default:
menu.options->setItemCaption(i, lang->getText(8) + ": " + lang->getText(26)); // ENGLISH
break;
}
i++;
// DISPLAY MODE
menu.options->setItemCaption(i, lang->getText(58));
i++;
// DISPLAY MODE - OPTIONS
switch (options->videoMode)
{
case 0:
menu.options->setItemCaption(i, lang->getText(4)); // WINDOW
break;
case SDL_WINDOW_FULLSCREEN:
menu.options->setItemCaption(i, lang->getText(5)); // FULLSCREEN
break;
case SDL_WINDOW_FULLSCREEN_DESKTOP:
menu.options->setItemCaption(i, lang->getText(6)); // FAKE FULLSCREEN
break;
default:
menu.options->setItemCaption(i, lang->getText(4)); // WINDOW
break;
}
i++;
// WINDOW SIZE
menu.options->setItemCaption(i, lang->getText(7) + " x" + std::to_string(options->windowSize)); // WINDOW SIZE
i++;
// FILTER
if (options->filter == FILTER_LINEAL)
menu.options->setItemCaption(i, lang->getText(60) + ": " + lang->getText(71)); // BILINEAL
else
menu.options->setItemCaption(i, lang->getText(60) + ": " + lang->getText(72)); // LINEAL
i++;
// VSYNC
if (options->vSync)
menu.options->setItemCaption(i, lang->getText(61) + ": " + lang->getText(73)); // ON
else
menu.options->setItemCaption(i, lang->getText(61) + ": " + lang->getText(74)); // OFF
i++;
// HOW TO PLAY
menu.options->setItemCaption(i, lang->getText(2));
i++;
// ACCEPT
menu.options->setItemCaption(i, lang->getText(9)); // ACCEPT
i++;
// CANCEL
menu.options->setItemCaption(i, lang->getText(10)); // CANCEL
// Recoloca el menu de opciones
menu.options->centerMenuOnX(SCREEN_CENTER_X);
menu.options->centerMenuOnY(SCREEN_CENTER_Y);
menu.options->centerMenuElementsOnX();
// Establece las etiquetas del menu de titulo
menu.title->setItemCaption(0, lang->getText(51)); // 1 PLAYER
menu.title->setItemCaption(1, lang->getText(52)); // 2 PLAYERS
menu.title->setItemCaption(2, lang->getText(1)); // OPTIONS
menu.title->setItemCaption(3, lang->getText(3)); // QUIT
// Recoloca el menu de titulo
menu.title->centerMenuOnX(SCREEN_CENTER_X);
menu.title->centerMenuElementsOnX();
// Establece las etiquetas del menu de seleccion de jugador
menu.playerSelect->setItemCaption(0, lang->getText(39)); // SELECT PLAYER
menu.playerSelect->setItemCaption(3, lang->getText(40)); // BACK
// Recoloca el menu de selección de jugador
menu.playerSelect->centerMenuOnX(SCREEN_CENTER_X);
menu.playerSelect->centerMenuElementsOnX();
}
// Aplica las opciones de menu seleccionadas
void Title::applyOptions()
{
screen->setVideoMode(options->videoMode);
lang->setLang(options->language);
updateMenuLabels();
createTiledBackground();
}
// Bucle para el titulo del juego
section_t Title::run()
{
while (section.name == PROG_SECTION_TITLE)
{
update();
render();
}
return section;
}
// Ejecuta la parte donde se muestran las instrucciones
section_t Title::runInstructions(mode_e mode)
{
instructions = new Instructions(renderer, screen, asset, lang);
section = instructions->run(mode);
delete instructions;
return section;
}
// Ejecuta la parte donde se muestra la tabla de puntuaciones
section_t Title::runHiScoreTable(mode_hiScoreTable_e mode)
{
if (!options->online.enabled)
{
section.name = PROG_SECTION_TITLE;
section.subsection = TITLE_SECTION_1;
return section;
}
hiScoreTable = new HiScoreTable(renderer, screen, asset, lang, options);
section = hiScoreTable->run(mode);
delete hiScoreTable;
return section;
}
// Ejecuta el juego en modo demo
section_t Title::runDemoGame()
{
demoGame = new Game(1, 0, renderer, screen, asset, lang, input, true, options);
section = demoGame->run();
delete demoGame;
return section;
}
// Modifica las opciones para los controles de los jugadores
bool Title::updatePlayerInputs(int numPlayer)
{
const int numDevices = availableInputDevices.size();
if (!input->gameControllerFound())
{ // Si no hay mandos se deja todo de manera prefijada
deviceIndex.at(0) = 0;
deviceIndex.at(1) = 0;
options->input.at(0).id = -1;
options->input.at(0).name = "KEYBOARD";
options->input.at(0).deviceType = INPUT_USE_KEYBOARD;
options->input.at(1).id = 0;
options->input.at(1).name = "GAME CONTROLLER";
options->input.at(1).deviceType = INPUT_USE_GAMECONTROLLER;
return true;
}
else
{ // Si hay mas de un dispositivo, se recorre el vector
printf("numplayer:%i\n", numPlayer);
printf("deviceindex:%i\n", deviceIndex.at(numPlayer));
// Incrementa el indice
if (deviceIndex.at(numPlayer) < numDevices - 1)
{
deviceIndex.at(numPlayer)++;
}
else
{
deviceIndex.at(numPlayer) = 0;
}
printf("deviceindex:%i\n", deviceIndex.at(numPlayer));
// Si coincide con el del otro jugador, se lo intercambian
if (deviceIndex.at(0) == deviceIndex.at(1))
{
const int theOtherPlayer = (numPlayer + 1) % 2;
deviceIndex.at(theOtherPlayer)--;
if (deviceIndex.at(theOtherPlayer) < 0)
{
deviceIndex.at(theOtherPlayer) = numDevices - 1;
}
}
// Copia el dispositivo marcado por el indice a la variable de opciones de cada jugador
options->input[0] = availableInputDevices.at(deviceIndex.at(0));
options->input[1] = availableInputDevices.at(deviceIndex.at(1));
return true;
}
}
// Crea el mosaico de fondo del titulo
void Title::createTiledBackground()
{
// Crea la textura para el mosaico de fondo
background = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH * 2, GAME_HEIGHT * 2);
if (background == nullptr)
{
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
}
// Crea los objetos para pintar en la textura de fondo
Texture *bgTileTexture = new Texture(renderer, asset->get("title_bg_tile.png"));
Sprite *tile = new Sprite({0, 0, 64, 64}, bgTileTexture, renderer);
// Prepara para dibujar sobre la textura
SDL_SetRenderTarget(renderer, background);
SDL_SetRenderDrawColor(renderer, 0x43, 0x43, 0x4F, 0xFF);
SDL_RenderClear(renderer);
// Rellena la textura con el tile
tile->setSpriteClip(0, 0, 64, 64);
for (int i = 0; i < 8; ++i)
{
for (int j = 0; j < 6; ++j)
{
tile->setPosX(i * 64);
tile->setPosY(j * 64);
tile->render();
}
}
// Vuelve a colocar el renderizador apuntando a la pantalla
SDL_SetRenderTarget(renderer, nullptr);
// Libera la memoria utilizada por los objetos
bgTileTexture->unload();
delete bgTileTexture;
delete tile;
}
// Comprueba cuantos mandos hay conectados para gestionar el menu de opciones
void Title::checkInputDevices()
{
printf("Filling devices for options menu...\n");
const int numControllers = input->getNumControllers();
availableInputDevices.clear();
input_t temp;
// Añade todos los mandos
if (numControllers > 0)
for (int i = 0; i < numControllers; ++i)
{
temp.id = i;
temp.name = input->getControllerName(i);
temp.deviceType = INPUT_USE_GAMECONTROLLER;
availableInputDevices.push_back(temp);
printf("Device %i:\t%s\n", (int)availableInputDevices.size(), temp.name.c_str());
}
// Añade el teclado al final
temp.id = -1;
temp.name = "KEYBOARD";
temp.deviceType = INPUT_USE_KEYBOARD;
availableInputDevices.push_back(temp);
printf("Device %i:\t%s\n\n", (int)availableInputDevices.size(), temp.name.c_str());
}
// Recarga las texturas
void Title::reLoadTextures()
{
dustTexture->reLoad();
coffeeTexture->reLoad();
crisisTexture->reLoad();
gradientTexture->reLoad();
createTiledBackground();
}