Files
coffee_crisis/source/title.cpp

967 lines
26 KiB
C++

#include "title.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
mRenderer = renderer;
mScreen = screen;
mInput = input;
mAsset = asset;
mOptions = options;
mLang = lang;
// Reserva memoria para los punteros propios
mEventHandler = new SDL_Event();
mFade = new Fade(renderer);
dustTexture = new LTexture(mRenderer, mAsset->get("title_dust.png"));
coffeeTexture = new LTexture(mRenderer, mAsset->get("title_coffee.png"));
crisisTexture = new LTexture(mRenderer, mAsset->get("title_crisis.png"));
gradientTexture = new LTexture(mRenderer, mAsset->get("title_gradient.png"));
mCoffeeBitmap = new SmartSprite(coffeeTexture, mRenderer);
mCrisisBitmap = new SmartSprite(crisisTexture, mRenderer);
mDustBitmapL = new AnimatedSprite(dustTexture, mRenderer, mAsset->get("title_dust.ani"));
mDustBitmapR = new AnimatedSprite(dustTexture, mRenderer, mAsset->get("title_dust.ani"));
mGradient = new Sprite({0, 0, 256, 192}, gradientTexture, mRenderer);
mText = new Text(mAsset->get("smb2.png"), mAsset->get("smb2.txt"), mRenderer);
mText2 = new Text(mAsset->get("8bithud.png"), mAsset->get("8bithud.txt"), mRenderer);
mMenu.title = new Menu(mRenderer, mAsset, mInput, mAsset->get("title.men"));
mMenu.options = new Menu(mRenderer, mAsset, mInput, mAsset->get("title.men"));
// Sonidos
mSound = JA_LoadSound(mAsset->get("title.wav").c_str());
// Musicas
mMusic = JA_LoadMusic(mAsset->get("title.ogg").c_str());
// Inicializa variables
mSection = section;
mCounter = TITLE_COUNTER;
mBackgroundCounter = 0;
mBackgroundMode = rand() % 2;
mMenuVisible = false;
mMenu.active = mMenu.title;
mNextSection.name = PROG_SECTION_GAME;
mPostFade = 0;
mTicks = 0;
mTicksSpeed = 15;
mFade->init(0x17, 0x17, 0x26);
mDemo = false;
// Pone valores por defecto a las opciones de control
mOptions->input[0].id = 0;
mOptions->input[0].name = "KEYBOARD";
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].id = 0;
mOptions->input[1].name = "GAME CONTROLLER";
mOptions->input[1].deviceType = INPUT_USE_GAMECONTROLLER;
// Comprueba si hay mandos conectados
checkInputDevices();
// Pone valores por defecto
mDeviceIndex[0] = mAvailableInputDevices.size() - 1; // El último dispositivo encontrado es el teclado
mDeviceIndex[1] = 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 (mInput->gameControllerFound())
{
mOptions->input[1].id = mAvailableInputDevices[mDeviceIndex[1]].id;
mOptions->input[1].name = mAvailableInputDevices[mDeviceIndex[1]].name;
mOptions->input[1].deviceType = mAvailableInputDevices[mDeviceIndex[1]].deviceType;
}
// Inicializa el bitmap de Coffee
mCoffeeBitmap->setPosX(45);
mCoffeeBitmap->setPosY(11 - 200);
mCoffeeBitmap->setWidth(167);
mCoffeeBitmap->setHeight(46);
mCoffeeBitmap->setVelX(0.0f);
mCoffeeBitmap->setVelY(2.5f);
mCoffeeBitmap->setAccelX(0.0f);
mCoffeeBitmap->setAccelY(0.1f);
mCoffeeBitmap->setSpriteClip(0, 0, 167, 46);
mCoffeeBitmap->setEnabled(true);
mCoffeeBitmap->setEnabledCounter(0);
mCoffeeBitmap->setDestX(45);
mCoffeeBitmap->setDestY(11);
// Inicializa el bitmap de Crisis
mCrisisBitmap->setPosX(60);
mCrisisBitmap->setPosY(57 + 200);
mCrisisBitmap->setWidth(137);
mCrisisBitmap->setHeight(46);
mCrisisBitmap->setVelX(0.0f);
mCrisisBitmap->setVelY(-2.5f);
mCrisisBitmap->setAccelX(0.0f);
mCrisisBitmap->setAccelY(-0.1f);
mCrisisBitmap->setSpriteClip(0, 0, 137, 46);
mCrisisBitmap->setEnabled(true);
mCrisisBitmap->setEnabledCounter(0);
mCrisisBitmap->setDestX(60);
mCrisisBitmap->setDestY(57);
// Inicializa el bitmap de DustRight
mDustBitmapR->setPosX(218);
mDustBitmapR->setPosY(47);
mDustBitmapR->setWidth(16);
mDustBitmapR->setHeight(16);
mDustBitmapR->setFlip(SDL_FLIP_HORIZONTAL);
// Inicializa el bitmap de DustLeft
mDustBitmapL->setPosX(33);
mDustBitmapL->setPosY(47);
mDustBitmapL->setWidth(16);
mDustBitmapL->setHeight(16);
// Inicializa el sprite con el degradado
mGradient->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
mBackgroundWindow.x = 128;
mBackgroundWindow.y = 96;
mBackgroundWindow.w = GAME_WIDTH;
mBackgroundWindow.h = GAME_HEIGHT;
// Inicializa los valores del vector con los valores del seno
for (int i = 0; i < 360; ++i)
{
mSin[i] = SDL_sinf((float)i * 3.14f / 180.0f);
}
// Inicializa los objetos de menu
// mMenu.title->setText(mAsset->get("smb2.png"), mAsset->get("smb2.txt"));
// mMenu.title->setName("TITLE");
// mMenu.title->setPos(0, (14 * BLOCK) + 4);
// mMenu.title->setBackgroundType(MENU_BACKGROUND_TRANSPARENT);
// mMenu.title->addItem(mLang->getText(51), 2); // 1 PLAYER
// mMenu.title->addItem(mLang->getText(52), 7); // 2 PLAYERS
// mMenu.title->addItem(mLang->getText(1), 7); // OPTIONS
// mMenu.title->addItem(mLang->getText(3)); // QUIT
// mMenu.title->setDefaultActionWhenCancel(3);
// mMenu.title->setBackgroundColor({0x30, 0x30, 0x40}, 192);
// mMenu.title->setSelectorColor({0xe5, 0x1c, 0x23}, 0);
// mMenu.title->setSelectorTextColor({0xFF, 0xB4, 0x00});
// mMenu.title->centerMenuOnX(SCREEN_CENTER_X);
// mMenu.title->centerMenuElementsOnX();
// mMenu.options->setText(mAsset->get("smb2.png"), mAsset->get("smb2.txt"));
// mMenu.options->setName("OPTIONS");
// mMenu.options->setPos(0, BLOCK);
// mMenu.options->setBackgroundType(MENU_BACKGROUND_TRANSPARENT);
// mMenu.options->addItem(mLang->getText(59), 7); // (0) DIFFICULTY
// mMenu.options->addItem(mLang->getText(62), 2, true, false, true); // (1) PLAYER 1 CONTROLS
// mMenu.options->addItem(mLang->getText(69), 7, false, false); // (2) KEYBOARD
// mMenu.options->addItem(mLang->getText(63), 2, true, false, true); // (3) PLAYER 2 CONTROLS
// mMenu.options->addItem(mLang->getText(70), 7, false, false); // (4) GAME CONTROLLER
// mMenu.options->addItem(mLang->getText(8), 7); // (5) LANGUAGE
// mMenu.options->addItem(mLang->getText(58), 2, true, false, true); // (6) DISPLAY MODE
// mMenu.options->addItem(mLang->getText(4), 7, false, false); // (7) WINDOW
// mMenu.options->addItem(mLang->getText(7), 2); // (8) WINDOW SIZE
// mMenu.options->addItem(mLang->getText(60), 2); // (9) FILTER
// mMenu.options->addItem(mLang->getText(61), 7); // (10) VSYNC
// mMenu.options->addItem(mLang->getText(2), 7); // (11) HOW TO PLAY
// mMenu.options->addItem(mLang->getText(9), 2); // (12) ACCEPT
// mMenu.options->addItem(mLang->getText(10)); // (13) CANCEL
// mMenu.options->setDefaultActionWhenCancel(13);
// mMenu.options->setBackgroundColor({0x30, 0x30, 0x40}, 192);
// mMenu.options->setSelectorColor({0xe5, 0x1c, 0x23}, 255);
// mMenu.options->setSelectorTextColor({0xFF, 0xF1, 0x76});
// mMenu.options->centerMenuOnX(SCREEN_CENTER_X);
// mMenu.options->centerMenuOnY(SCREEN_CENTER_Y);
// Actualiza los textos de los menus
// updateMenuLabels();
}
// Destructor
Title::~Title()
{
delete mEventHandler;
delete mFade;
dustTexture->unload();
delete dustTexture;
coffeeTexture->unload();
delete coffeeTexture;
crisisTexture->unload();
delete crisisTexture;
gradientTexture->unload();
delete gradientTexture;
delete mCoffeeBitmap;
delete mCrisisBitmap;
delete mDustBitmapL;
delete mDustBitmapR;
delete mGradient;
delete mText;
delete mText2;
delete mMenu.title;
delete mMenu.options;
JA_DeleteSound(mSound);
JA_DeleteMusic(mMusic);
SDL_DestroyTexture(mBackground);
}
// Actualiza las variables del objeto
void Title::update()
{
// Comprueba los eventos
checkEventHandler();
// Calcula la lógica de los objetos
if (SDL_GetTicks() - mTicks > mTicksSpeed)
{
// Actualiza el contador de ticks
mTicks = SDL_GetTicks();
switch (mSection.subsection)
{
// Sección 1 - Titulo desplazandose
case TITLE_SECTION_1:
{ // Actualiza los objetos
mCoffeeBitmap->update();
mCrisisBitmap->update();
// Si los objetos han llegado a su destino, cambiamos de Sección
if (mCoffeeBitmap->hasFinished() && mCrisisBitmap->hasFinished())
{
mSection.subsection = TITLE_SECTION_2;
// Pantallazo blanco
SDL_SetRenderDrawColor(mRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderClear(mRenderer);
SDL_RenderPresent(mRenderer);
}
}
break;
// Sección 2 - Titulo vibrando
case TITLE_SECTION_2:
{
}
break;
// Sección 3 - La pantalla de titulo con el menú y la música
case TITLE_SECTION_3:
{
// Reproduce la música
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
{
JA_PlayMusic(mMusic);
}
// Actualiza el contador de ticks
mTicks = SDL_GetTicks();
mDustBitmapR->update();
mDustBitmapL->update();
// Actualiza la lógica del titulo
mMenu.active->update();
mFade->update();
if (mFade->hasEnded())
{
switch (mPostFade)
{
case 0: // 1 PLAYER
mSection.name = PROG_SECTION_GAME;
mSection.subsection = GAME_SECTION_PLAY_1P;
JA_StopMusic();
break;
case 1: // 2 PLAYERS
mSection.name = PROG_SECTION_GAME;
mSection.subsection = GAME_SECTION_PLAY_2P;
JA_StopMusic();
break;
case 2: // QUIT
mSection.name = PROG_SECTION_QUIT;
JA_StopMusic();
break;
case 3: // TIME OUT
mCounter = TITLE_COUNTER;
mMenu.active->reset();
if (mDemo)
{
runDemoGame();
runInstructions(INSTRUCTIONS_MODE_AUTO);
}
else
mSection.name = PROG_SECTION_LOGO;
break;
default:
break;
}
}
// Actualiza el tileado de fondo
updateBG();
// Comprueba las entradas para el menu
if (mMenuVisible == true)
{
mMenu.active->checkInput();
}
// Comprueba si se ha seleccionado algún item del menú
if (mMenu.active->getName() == "TITLE")
{
switch (mMenu.active->getItemSelected())
{
case 0: // 1 PLAYER
mPostFade = 0;
mFade->activateFade();
break;
case 1: // 2 PLAYERS
mPostFade = 1;
mFade->activateFade();
break;
case 2: // OPTIONS
mMenu.active = mMenu.options;
mOptionsPrevious = *mOptions;
break;
case 3: // QUIT
mPostFade = 2;
mFade->activateFade();
break;
default:
break;
}
}
// Comprueba si se ha seleccionado algún item de opciones
if (mMenu.active->getName() == "OPTIONS")
{
switch (mMenu.active->getItemSelected())
{
case 0: // Difficulty
if (mOptions->difficulty == DIFFICULTY_EASY)
mOptions->difficulty = DIFFICULTY_NORMAL;
else if (mOptions->difficulty == DIFFICULTY_NORMAL)
mOptions->difficulty = DIFFICULTY_HARD;
else
mOptions->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
mOptions->language++;
if (mOptions->language == 3)
mOptions->language = 0;
updateMenuLabels();
break;
case 6: // Display mode
switchFullScreenModeVar();
if (mOptions->fullScreenMode != 0)
{
mMenu.options->setSelectable(8, false);
mMenu.options->setGreyed(8, true);
}
else
{
mMenu.options->setSelectable(8, true);
mMenu.options->setGreyed(8, false);
}
updateMenuLabels();
break;
case 8: // Windows size
mOptions->windowSize++;
if (mOptions->windowSize == 5)
mOptions->windowSize = 1;
updateMenuLabels();
break;
case 9: // FILTER
if (mOptions->filter == FILTER_LINEAL)
mOptions->filter = FILTER_NEAREST;
else
mOptions->filter = FILTER_LINEAL;
updateMenuLabels();
break;
case 10: // VSYNC
if (mOptions->vSync)
mOptions->vSync = false;
else
mOptions->vSync = true;
updateMenuLabels();
break;
case 11: // HOW TO PLAY
runInstructions(INSTRUCTIONS_MODE_MANUAL);
break;
case 12: // ACCEPT
applyOptions();
mMenu.active->reset();
mMenu.active = mMenu.title;
break;
case 13: // CANCEL
mOptions = &mOptionsPrevious;
updateMenuLabels();
mMenu.active->reset();
mMenu.active = mMenu.title;
break;
default:
break;
}
}
if (mMenu.active->getName() == "TITLE")
{
mCounter--;
}
}
break;
default:
break;
}
}
}
// Dibuja el objeto en pantalla
void Title::render()
{
switch (mSection.subsection)
{
// Sección 1 - Titulo desplazandose
case TITLE_SECTION_1:
{
mScreen->start(); // Prepara para empezar a dibujar en la textura de juego
mScreen->clean(bgColor); // Limpia la pantalla
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, nullptr); // Dibuja el tileado de fondo
mGradient->render(); // Dibuja el degradado
mCoffeeBitmap->render(); // Dibuja los objetos
mCrisisBitmap->render(); // Dibuja los objetos
mScreen->blit(); // Vuelca el contenido del renderizador en pantalla
}
break;
// Sección 2 - Titulo vibrando
case TITLE_SECTION_2:
{ // Reproduce el efecto sonoro
JA_PlaySound(mSound);
// Agita la pantalla
const int v[] = {-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 0};
const int a = mCoffeeBitmap->getPosX();
const int b = mCrisisBitmap->getPosX();
for (int n = 0; n < 11 * 3; ++n)
{
// Prepara para empezar a dibujar en la textura de juego
mScreen->start();
// Limpia la pantalla
mScreen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, nullptr);
// Dibuja el degradado
mGradient->render();
// Dibuja los objetos
mCoffeeBitmap->setPosX(a + v[n / 3]);
mCrisisBitmap->setPosX(b + v[n / 3]);
mCoffeeBitmap->render();
mCrisisBitmap->render();
mDustBitmapR->update();
mDustBitmapL->update();
mDustBitmapR->render();
mDustBitmapL->render();
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
mSection.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
mScreen->start();
// Limpia la pantalla
mScreen->clean(bgColor);
// Dibuja el tileado de fondo
SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, nullptr);
// Dibuja el degradado
mGradient->render();
// Dibuja los objetos
if (mMenu.active->getName() != "OPTIONS")
{
// Bitmaps con el logo/titulo del juego
mCoffeeBitmap->render();
mCrisisBitmap->render();
// Texto con el copyright y versión
mText2->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, GAME_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 1, noColor, 1, shdwTxtColor);
}
if (mMenuVisible == true)
{
mMenu.active->render();
}
mDustBitmapR->render();
mDustBitmapL->render();
// PRESS ANY KEY!
if ((mCounter % 50 > 14) && (mMenuVisible == false))
{
mText->writeDX(TXT_CENTER | TXT_SHADOW, SCREEN_CENTER_X, PLAY_AREA_THIRD_QUARTER_Y + BLOCK, mLang->getText(23), 1, noColor, 1, shdwTxtColor);
}
// Fade
mFade->render();
// Vuelca el contenido del renderizador en pantalla
mScreen->blit();
}
break;
default:
break;
}
}
// Comprueba los eventos
void Title::checkEventHandler()
{
// Comprueba los eventos que hay en la cola
while (SDL_PollEvent(mEventHandler) != 0)
{
// Evento de salida de la aplicación
if (mEventHandler->type == SDL_QUIT)
{
mSection.name = PROG_SECTION_QUIT;
break;
}
if (mSection.subsection == TITLE_SECTION_3)
{ // Si se pulsa alguna tecla durante la tercera sección del titulo
if ((mEventHandler->type == SDL_KEYUP) || (mEventHandler->type == SDL_JOYBUTTONUP))
{
// Muestra el menu
mMenuVisible = true;
// Reinicia el contador
mCounter = TITLE_COUNTER;
}
}
}
}
// Actualiza el tileado de fondo
void Title::updateBG()
{
if (mBackgroundMode == 0)
{ // El tileado de fondo se desplaza en diagonal
++mBackgroundWindow.x %= 64;
++mBackgroundWindow.y %= 64;
}
else
{ // El tileado de fondo se desplaza en circulo
++mBackgroundCounter %= 360;
mBackgroundWindow.x = 128 + (int(mSin[(mBackgroundCounter + 270) % 360] * 128));
mBackgroundWindow.y = 96 + (int(mSin[(360 - mBackgroundCounter) % 360] * 96));
}
}
// Cambia el valor de la variable de modo de pantalla completa
void Title::switchFullScreenModeVar()
{
switch (mOptions->fullScreenMode)
{
case 0:
mOptions->fullScreenMode = SDL_WINDOW_FULLSCREEN;
break;
case SDL_WINDOW_FULLSCREEN:
mOptions->fullScreenMode = SDL_WINDOW_FULLSCREEN_DESKTOP;
break;
case SDL_WINDOW_FULLSCREEN_DESKTOP:
mOptions->fullScreenMode = 0;
break;
default:
mOptions->fullScreenMode = 0;
break;
}
}
// Actualiza los elementos de los menus
void Title::updateMenuLabels()
{
int i = 0;
// DIFFICULTY
switch (mOptions->difficulty)
{
case DIFFICULTY_EASY:
mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(66)); // EASY
break;
case DIFFICULTY_NORMAL:
mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(67)); // NORMAL
break;
case DIFFICULTY_HARD:
mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(68)); // HARD
break;
default:
mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(67)); // NORMAL
break;
}
i++;
// PLAYER 1 CONTROLS
mMenu.options->setItemCaption(i, mLang->getText(62));
i++;
// PLAYER 1 CONTROLS - OPTIONS
switch (mOptions->input[0].deviceType)
{
case INPUT_USE_KEYBOARD:
mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD
mMenu.options->setGreyed(i, false);
break;
case INPUT_USE_GAMECONTROLLER:
mMenu.options->setItemCaption(i, mLang->getText(70)); // GAME CONTROLLER
if (!mInput->gameControllerFound())
mMenu.options->setGreyed(i, true);
else
{
mMenu.options->setGreyed(i, false);
mMenu.options->setItemCaption(i, mOptions->input[0].name);
}
break;
default:
mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD
break;
}
i++;
// PLAYER 2 CONTROLS
mMenu.options->setItemCaption(i, mLang->getText(63));
i++;
// PLAYER 2 CONTROLS - OPTIONS
switch (mOptions->input[1].deviceType)
{
case INPUT_USE_KEYBOARD:
mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD
mMenu.options->setGreyed(i, false);
break;
case INPUT_USE_GAMECONTROLLER:
mMenu.options->setItemCaption(i, mLang->getText(70)); // GAME CONTROLLER
if (!mInput->gameControllerFound())
mMenu.options->setGreyed(i, true);
else
{
mMenu.options->setGreyed(i, false);
mMenu.options->setItemCaption(i, mOptions->input[1].name);
}
break;
default:
mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD
break;
}
i++;
// LANGUAGE
switch (mOptions->language)
{
case es_ES:
mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(24)); // SPANISH
break;
case ba_BA:
mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(25)); // VALENCIAN
break;
case en_UK:
mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(26)); // ENGLISH
break;
default:
mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(26)); // ENGLISH
break;
}
i++;
// DISPLAY MODE
mMenu.options->setItemCaption(i, mLang->getText(58));
i++;
// DISPLAY MODE - OPTIONS
switch (mOptions->fullScreenMode)
{
case 0:
mMenu.options->setItemCaption(i, mLang->getText(4)); // WINDOW
break;
case SDL_WINDOW_FULLSCREEN:
mMenu.options->setItemCaption(i, mLang->getText(5)); // FULLSCREEN
break;
case SDL_WINDOW_FULLSCREEN_DESKTOP:
mMenu.options->setItemCaption(i, mLang->getText(6)); // FAKE FULLSCREEN
break;
default:
mMenu.options->setItemCaption(i, mLang->getText(4)); // WINDOW
break;
}
i++;
// WINDOW SIZE
mMenu.options->setItemCaption(i, mLang->getText(7) + " x" + std::to_string(mOptions->windowSize)); // WINDOW SIZE
i++;
// FILTER
if (mOptions->filter == FILTER_LINEAL)
mMenu.options->setItemCaption(i, mLang->getText(60) + ": " + mLang->getText(71)); // BILINEAL
else
mMenu.options->setItemCaption(i, mLang->getText(60) + ": " + mLang->getText(72)); // LINEAL
i++;
// VSYNC
if (mOptions->vSync)
mMenu.options->setItemCaption(i, mLang->getText(61) + ": " + mLang->getText(73)); // ON
else
mMenu.options->setItemCaption(i, mLang->getText(61) + ": " + mLang->getText(74)); // OFF
i++;
// HOW TO PLAY
mMenu.options->setItemCaption(i, mLang->getText(2));
i++;
// ACCEPT
mMenu.options->setItemCaption(i, mLang->getText(9)); // ACCEPT
i++;
// CANCEL
mMenu.options->setItemCaption(i, mLang->getText(10)); // CANCEL
// Recoloca el menu de opciones
mMenu.options->centerMenuOnX(SCREEN_CENTER_X);
mMenu.options->centerMenuOnY(SCREEN_CENTER_Y);
mMenu.options->centerMenuElementsOnX();
// Establece las etiquetas del menu de titulo
mMenu.title->setItemCaption(0, mLang->getText(51)); // 1 PLAYER
mMenu.title->setItemCaption(1, mLang->getText(52)); // 2 PLAYERS
mMenu.title->setItemCaption(2, mLang->getText(1)); // OPTIONS
mMenu.title->setItemCaption(3, mLang->getText(3)); // QUIT
// Recoloca el menu de titulo
mMenu.title->centerMenuOnX(SCREEN_CENTER_X);
mMenu.title->centerMenuElementsOnX();
}
// Aplica las opciones de menu seleccionadas
void Title::applyOptions()
{
mScreen->setVideoMode(mOptions->fullScreenMode);
mLang->setLang(mOptions->language);
updateMenuLabels();
createTiledBackground();
}
// Bucle para el titulo del juego
section_t Title::run()
{
while (mSection.name == PROG_SECTION_TITLE)
{
update();
render();
// Sección 3 - La pantalla de titulo con el menú y la música
// Sección Instrucciones
// if (mSection.subsection == TITLE_SECTION_INSTRUCTIONS)
//{
// runInstructions(INSTRUCTIONS_MODE_AUTO);
//}
}
return mSection;
}
// Ejecuta la parte donde se muestran las instrucciones
void Title::runInstructions(Uint8 mode)
{
mInstructions = new Instructions(mRenderer, mScreen, mAsset, mLang);
mInstructions->run(mode);
delete mInstructions;
}
// Ejecuta el juego en modo demo
void Title::runDemoGame()
{
mDemoGame = new Game(1, 0, mRenderer, mScreen, mAsset, mLang, mInput, true, mOptions);
mDemoGame->run();
delete mDemoGame;
}
// Modifica las opciones para los controles de los jugadores
bool Title::updatePlayerInputs(int numPlayer)
{
const int numDevices = mAvailableInputDevices.size();
// Si no hay mandos se deja todo de manera prefijada
if (!mInput->gameControllerFound())
{
mDeviceIndex[0] = 0;
mDeviceIndex[1] = 0;
mOptions->input[0].id = -1;
mOptions->input[0].name = "KEYBOARD";
mOptions->input[0].deviceType = INPUT_USE_KEYBOARD;
mOptions->input[1].id = 0;
mOptions->input[1].name = "GAME CONTROLLER";
mOptions->input[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", mDeviceIndex[numPlayer]);
// Incrementa el indice
if (mDeviceIndex[numPlayer] < numDevices - 1)
{
mDeviceIndex[numPlayer]++;
}
else
{
mDeviceIndex[numPlayer] = 0;
}
printf("deviceindex:%i\n", mDeviceIndex[numPlayer]);
// Si coincide con el del otro jugador, se lo intercambian
if (mDeviceIndex[0] == mDeviceIndex[1])
{
const int theOtherPlayer = (numPlayer + 1) % 2;
mDeviceIndex[theOtherPlayer]--;
if (mDeviceIndex[theOtherPlayer] < 0)
{
mDeviceIndex[theOtherPlayer] = numDevices - 1;
}
}
// Copia el dispositivo marcado por el indice a la variable de opciones de cada jugador
mOptions->input[0] = mAvailableInputDevices[mDeviceIndex[0]];
mOptions->input[1] = mAvailableInputDevices[mDeviceIndex[1]];
return true;
}
}
// Crea el mosaico de fondo del titulo
void Title::createTiledBackground()
{
// Crea la textura para el mosaico de fondo
mBackground = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAME_WIDTH * 2, GAME_HEIGHT * 2);
if (mBackground == nullptr)
{
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
}
// Crea los objetos para pintar en la textura de fondo
LTexture *bgTileTexture = new LTexture(mRenderer, mAsset->get("title_bg_tile.png"));
Sprite *tile = new Sprite({0, 0, 64, 64}, bgTileTexture, mRenderer);
// Prepara para dibujar sobre la textura
SDL_SetRenderTarget(mRenderer, mBackground);
SDL_SetRenderDrawColor(mRenderer, 0x43, 0x43, 0x4F, 0xFF);
SDL_RenderClear(mRenderer);
// 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(mRenderer, 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");
int numControllers = mInput->getNumControllers();
mAvailableInputDevices.clear();
input_t temp;
// Añade todos los mandos
if (numControllers > 0)
for (int i = 0; i < numControllers; i++)
{
temp.id = i;
temp.name = mInput->getControllerName(i);
temp.deviceType = INPUT_USE_GAMECONTROLLER;
mAvailableInputDevices.push_back(temp);
printf("Device %i:\t%s\n", (int)mAvailableInputDevices.size(), temp.name.c_str());
}
// Añade el teclado al final
temp.id = -1;
temp.name = "KEYBOARD";
temp.deviceType = INPUT_USE_KEYBOARD;
mAvailableInputDevices.push_back(temp);
printf("Device %i:\t%s\n\n", (int)mAvailableInputDevices.size(), temp.name.c_str());
}