1025 lines
29 KiB
C++
1025 lines
29 KiB
C++
#include "title.h"
|
|
|
|
// Constructor
|
|
Title::Title(SDL_Window *window, SDL_Renderer *renderer, Screen *screen, Input *input, std::string *fileList, options_t *options, Lang *lang)
|
|
{
|
|
// Copia las direcciones de los punteros
|
|
mWindow = window;
|
|
mRenderer = renderer;
|
|
mScreen = screen;
|
|
mInput = input;
|
|
mFileList = fileList;
|
|
mOptions = options;
|
|
mLang = lang;
|
|
|
|
// Reserva memoria para los punteros propios
|
|
mEventHandler = new SDL_Event();
|
|
mFade = new Fade(renderer);
|
|
mTitleTexture = new LTexture();
|
|
mItemsTexture = new LTexture();
|
|
mTextTexture = new LTexture();
|
|
mTextTexture2 = new LTexture();
|
|
mCoffeeBitmap = new SmartSprite();
|
|
mCrisisBitmap = new SmartSprite();
|
|
mDustBitmapL = new AnimatedSprite();
|
|
mDustBitmapR = new AnimatedSprite();
|
|
mTile = new Sprite();
|
|
mGradient = new Sprite();
|
|
mText = new Text(mFileList[48], mTextTexture, mRenderer);
|
|
mText2 = new Text(mFileList[46], mTextTexture2, mRenderer);
|
|
mMenu.title = new Menu(mRenderer, mText, mInput, mFileList);
|
|
mMenu.options = new Menu(mRenderer, mText, mInput, mFileList);
|
|
|
|
// Crea la textura para el mosaico de fondo
|
|
mBackground = SDL_CreateTexture(mRenderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, SCREEN_WIDTH * 2, SCREEN_HEIGHT * 2);
|
|
if (mBackground == NULL)
|
|
printf("TitleSurface could not be created!\nSDL Error: %s\n", SDL_GetError());
|
|
}
|
|
|
|
// Destructor
|
|
Title::~Title()
|
|
{
|
|
mWindow = nullptr;
|
|
mRenderer = nullptr;
|
|
mScreen = nullptr;
|
|
mInput = nullptr;
|
|
mFileList = nullptr;
|
|
mOptions = nullptr;
|
|
mLang = nullptr;
|
|
|
|
delete mEventHandler;
|
|
mEventHandler = nullptr;
|
|
|
|
delete mText;
|
|
mText = nullptr;
|
|
|
|
delete mText2;
|
|
mText2 = nullptr;
|
|
|
|
delete mFade;
|
|
mFade = nullptr;
|
|
|
|
mTitleTexture->unload();
|
|
delete mTitleTexture;
|
|
mTitleTexture = nullptr;
|
|
|
|
mItemsTexture->unload();
|
|
delete mItemsTexture;
|
|
mItemsTexture = nullptr;
|
|
|
|
mTextTexture->unload();
|
|
delete mTextTexture;
|
|
mTextTexture = nullptr;
|
|
|
|
mTextTexture2->unload();
|
|
delete mTextTexture2;
|
|
mTextTexture2 = nullptr;
|
|
|
|
delete mCoffeeBitmap;
|
|
mCoffeeBitmap = nullptr;
|
|
|
|
delete mCrisisBitmap;
|
|
mCrisisBitmap = nullptr;
|
|
|
|
delete mDustBitmapL;
|
|
mDustBitmapL = nullptr;
|
|
|
|
delete mDustBitmapR;
|
|
mDustBitmapR = nullptr;
|
|
|
|
delete mTile;
|
|
mTile = nullptr;
|
|
|
|
delete mGradient;
|
|
mGradient = nullptr;
|
|
|
|
delete mMenu.title;
|
|
mMenu.title = nullptr;
|
|
|
|
delete mMenu.options;
|
|
mMenu.options = nullptr;
|
|
|
|
mMenu.active = nullptr;
|
|
|
|
JA_DeleteSound(mSound);
|
|
JA_DeleteMusic(mMusic);
|
|
|
|
SDL_DestroyTexture(mBackground);
|
|
mBackground = nullptr;
|
|
|
|
mWindow = nullptr;
|
|
mRenderer = nullptr;
|
|
mInput = nullptr;
|
|
mFileList = nullptr;
|
|
mOptions = nullptr;
|
|
}
|
|
|
|
// Inicializa las variables necesarias para la sección 'Title'
|
|
void Title::init(bool demo, Uint8 subsection)
|
|
{
|
|
// Carga los recursos
|
|
loadMedia();
|
|
|
|
// Inicializa variables
|
|
mSection.name = PROG_SECTION_TITLE;
|
|
mSection.subsection = subsection;
|
|
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 = demo;
|
|
|
|
// 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->init(mTitleTexture, mRenderer);
|
|
mCoffeeBitmap->setId(0);
|
|
mCoffeeBitmap->setIntroEvents(&mEvents[0]);
|
|
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->setEnabledTimer(0);
|
|
mCoffeeBitmap->setDestX(45);
|
|
mCoffeeBitmap->setDestY(11);
|
|
|
|
// Inicializa el bitmap de Crisis
|
|
mCrisisBitmap->init(mTitleTexture, mRenderer);
|
|
mCrisisBitmap->setId(1);
|
|
mCrisisBitmap->setIntroEvents(&mEvents[0]);
|
|
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, 46, 137, 46);
|
|
mCrisisBitmap->setEnabled(true);
|
|
mCrisisBitmap->setEnabledTimer(0);
|
|
mCrisisBitmap->setDestX(60);
|
|
mCrisisBitmap->setDestY(57);
|
|
|
|
// Inicializa el bitmap de DustRight
|
|
mDustBitmapR->init(mTitleTexture, mRenderer);
|
|
mDustBitmapR->setPosX(218);
|
|
mDustBitmapR->setPosY(47);
|
|
mDustBitmapR->setWidth(16);
|
|
mDustBitmapR->setHeight(14);
|
|
mDustBitmapR->setCurrentFrame(0);
|
|
mDustBitmapR->setAnimationCounter(0);
|
|
mDustBitmapR->setAnimationNumFrames(0, 7);
|
|
mDustBitmapR->setAnimationSpeed(0, 8);
|
|
mDustBitmapR->setAnimationLoop(0, false);
|
|
mDustBitmapR->setAnimationFrames(0, 0, 160 + (mDustBitmapR->getWidth() * 0), 80, mDustBitmapR->getWidth(), mDustBitmapR->getHeight());
|
|
mDustBitmapR->setAnimationFrames(0, 1, 160 + (mDustBitmapR->getWidth() * 1), 80, mDustBitmapR->getWidth(), mDustBitmapR->getHeight());
|
|
mDustBitmapR->setAnimationFrames(0, 2, 160 + (mDustBitmapR->getWidth() * 2), 80, mDustBitmapR->getWidth(), mDustBitmapR->getHeight());
|
|
mDustBitmapR->setAnimationFrames(0, 3, 160 + (mDustBitmapR->getWidth() * 3), 80, mDustBitmapR->getWidth(), mDustBitmapR->getHeight());
|
|
mDustBitmapR->setAnimationFrames(0, 4, 160 + (mDustBitmapR->getWidth() * 4), 80, mDustBitmapR->getWidth(), mDustBitmapR->getHeight());
|
|
mDustBitmapR->setAnimationFrames(0, 5, 160 + (mDustBitmapR->getWidth() * 5), 80, mDustBitmapR->getWidth(), mDustBitmapR->getHeight());
|
|
mDustBitmapR->setAnimationFrames(0, 6, 160 + (mDustBitmapR->getWidth() * 6), 80, mDustBitmapR->getWidth(), mDustBitmapR->getHeight());
|
|
|
|
// Inicializa el bitmap de DustLeft
|
|
mDustBitmapL->init(mTitleTexture, mRenderer);
|
|
mDustBitmapL->setPosX(33);
|
|
mDustBitmapL->setPosY(47);
|
|
mDustBitmapL->setWidth(16);
|
|
mDustBitmapL->setHeight(14);
|
|
mDustBitmapL->setCurrentFrame(0);
|
|
mDustBitmapL->setAnimationCounter(0);
|
|
mDustBitmapL->setAnimationNumFrames(0, 7);
|
|
mDustBitmapL->setAnimationSpeed(0, 8);
|
|
mDustBitmapL->setAnimationLoop(0, false);
|
|
mDustBitmapL->setAnimationFrames(0, 0, 160 + (mDustBitmapL->getWidth() * 0), 66, mDustBitmapL->getWidth(), mDustBitmapL->getHeight());
|
|
mDustBitmapL->setAnimationFrames(0, 1, 160 + (mDustBitmapL->getWidth() * 1), 66, mDustBitmapL->getWidth(), mDustBitmapL->getHeight());
|
|
mDustBitmapL->setAnimationFrames(0, 2, 160 + (mDustBitmapL->getWidth() * 2), 66, mDustBitmapL->getWidth(), mDustBitmapL->getHeight());
|
|
mDustBitmapL->setAnimationFrames(0, 3, 160 + (mDustBitmapL->getWidth() * 3), 66, mDustBitmapL->getWidth(), mDustBitmapL->getHeight());
|
|
mDustBitmapL->setAnimationFrames(0, 4, 160 + (mDustBitmapL->getWidth() * 4), 66, mDustBitmapL->getWidth(), mDustBitmapL->getHeight());
|
|
mDustBitmapL->setAnimationFrames(0, 5, 160 + (mDustBitmapL->getWidth() * 5), 66, mDustBitmapL->getWidth(), mDustBitmapL->getHeight());
|
|
mDustBitmapL->setAnimationFrames(0, 6, 160 + (mDustBitmapL->getWidth() * 6), 66, mDustBitmapL->getWidth(), mDustBitmapL->getHeight());
|
|
|
|
// Inicializa el sprite con el degradado
|
|
mGradient->init(0, 0, 256, 192, mTitleTexture, mRenderer);
|
|
mGradient->setSpriteClip(0, 96, 256, 192);
|
|
|
|
// Inicializa el vector de eventos de la pantalla de titulo
|
|
for (int i = 0; i < TITLE_TOTAL_EVENTS; i++)
|
|
mEvents[i] = EVENT_WAITING;
|
|
|
|
// 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 = SCREEN_WIDTH;
|
|
mBackgroundWindow.h = SCREEN_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->init("TITLE", 0, (14 * BLOCK) + 4, 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->init("OPTIONS", 0, BLOCK, 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();
|
|
}
|
|
|
|
// Carga los recursos necesarios para la sección 'Title'
|
|
bool Title::loadMedia()
|
|
{
|
|
// Indicador de éxito en la carga
|
|
bool success = true;
|
|
|
|
// Texturas
|
|
success &= loadTextureFromFile(mTitleTexture, mFileList[40], mRenderer);
|
|
success &= loadTextureFromFile(mItemsTexture, mFileList[34], mRenderer);
|
|
success &= loadTextureFromFile(mTextTexture, mFileList[30], mRenderer);
|
|
success &= loadTextureFromFile(mTextTexture2, mFileList[27], mRenderer);
|
|
|
|
// Sonidos
|
|
mSound = JA_LoadSound(mFileList[21].c_str());
|
|
|
|
// Musicas
|
|
mMusic = JA_LoadMusic(mFileList[5].c_str());
|
|
|
|
return success;
|
|
}
|
|
|
|
// 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(Uint8 subsection)
|
|
{
|
|
init(subsection);
|
|
|
|
while (mSection.name == PROG_SECTION_TITLE)
|
|
{
|
|
// Sección 1 - Titulo desplazandose
|
|
if (mSection.subsection == TITLE_SECTION_1)
|
|
{
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
// Calcula la lógica de los objetos
|
|
if (SDL_GetTicks() - mTicks > mTicksSpeed)
|
|
{
|
|
// Actualiza el contador de ticks
|
|
mTicks = SDL_GetTicks();
|
|
|
|
// Actualiza los objetos
|
|
mCoffeeBitmap->update();
|
|
mCrisisBitmap->update();
|
|
}
|
|
|
|
// 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, NULL);
|
|
|
|
// Dibuja el degradado
|
|
mGradient->render();
|
|
|
|
// Dibuja los objetos
|
|
mCoffeeBitmap->render();
|
|
mCrisisBitmap->render();
|
|
|
|
// Vuelca el contenido del renderizador en pantalla
|
|
mScreen->blit();
|
|
|
|
// Si los objetos han llegado a su destino, cambiamos de Sección
|
|
if ((mEvents[0] == EVENT_COMPLETED) && (mEvents[0] == EVENT_COMPLETED))
|
|
{
|
|
mSection.subsection = TITLE_SECTION_2;
|
|
|
|
// Pantallazo blanco
|
|
SDL_SetRenderDrawColor(mRenderer, 0xFF, 0xFF, 0xFF, 0xFF);
|
|
SDL_RenderClear(mRenderer);
|
|
SDL_RenderPresent(mRenderer);
|
|
}
|
|
}
|
|
|
|
// Sección 2 - Titulo vibrando
|
|
if (mSection.subsection == TITLE_SECTION_2)
|
|
{
|
|
// 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;
|
|
}
|
|
}
|
|
|
|
// Reproduce el efecto sonoro
|
|
JA_PlaySound(mSound);
|
|
|
|
// Agita la pantalla
|
|
int v[] = {-1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 0};
|
|
int a = mCoffeeBitmap->getPosX();
|
|
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, NULL);
|
|
|
|
// 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->animate(0);
|
|
mDustBitmapL->animate(0);
|
|
mDustBitmapR->render();
|
|
mDustBitmapL->render();
|
|
|
|
// Vuelca el contenido del renderizador en pantalla
|
|
mScreen->blit();
|
|
}
|
|
|
|
mSection.subsection = TITLE_SECTION_3;
|
|
}
|
|
|
|
// Sección 3 - La pantalla de titulo con el menú y la música
|
|
if (mSection.subsection == TITLE_SECTION_3)
|
|
{
|
|
if (mCounter > 0)
|
|
{
|
|
// 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 ((mEventHandler->type == SDL_KEYUP) || (mEventHandler->type == SDL_JOYBUTTONUP))
|
|
{
|
|
mMenuVisible = true;
|
|
mCounter = TITLE_COUNTER;
|
|
}
|
|
}
|
|
|
|
// Si la música no está sonando
|
|
if ((JA_GetMusicState() == JA_MUSIC_INVALID) || (JA_GetMusicState() == JA_MUSIC_STOPPED))
|
|
JA_PlayMusic(mMusic); // Reproduce la música
|
|
|
|
// Calcula la lógica de los objetos
|
|
if (SDL_GetTicks() - mTicks > mTicksSpeed)
|
|
{
|
|
// Actualiza el contador de ticks
|
|
mTicks = SDL_GetTicks();
|
|
|
|
// 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);
|
|
init(false);
|
|
}
|
|
else
|
|
mSection.name = PROG_SECTION_LOGO;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Actualiza el tileado de fondo
|
|
switch (mBackgroundMode)
|
|
{
|
|
case 0: // El tileado de fondo se desplaza en diagonal
|
|
mBackgroundWindow.x++;
|
|
mBackgroundWindow.x %= 64;
|
|
mBackgroundWindow.y++;
|
|
mBackgroundWindow.y %= 64;
|
|
break;
|
|
|
|
case 1: // 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));
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// 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--;
|
|
}
|
|
|
|
// 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, NULL);
|
|
|
|
// 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, SCREEN_HEIGHT - (BLOCK * 2), TEXT_COPYRIGHT, 1, noColor, 1, shdwTxtColor);
|
|
}
|
|
|
|
if (mMenuVisible == true)
|
|
mMenu.active->render();
|
|
|
|
mDustBitmapR->animate(0);
|
|
mDustBitmapL->animate(0);
|
|
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();
|
|
}
|
|
else if (mCounter == 0)
|
|
{
|
|
if (mDemo)
|
|
{
|
|
runDemoGame();
|
|
runInstructions(INSTRUCTIONS_MODE_AUTO);
|
|
init(false);
|
|
}
|
|
else
|
|
mSection.name = PROG_SECTION_LOGO;
|
|
}
|
|
}
|
|
|
|
// Sección Instrucciones
|
|
if (mSection.subsection == TITLE_SECTION_INSTRUCTIONS)
|
|
{
|
|
runInstructions(INSTRUCTIONS_MODE_AUTO);
|
|
init();
|
|
}
|
|
}
|
|
|
|
return mSection;
|
|
}
|
|
|
|
// Ejecuta la parte donde se muestran las instrucciones
|
|
void Title::runInstructions(Uint8 mode)
|
|
{
|
|
mInstructions = new Instructions(mRenderer, mScreen, mFileList, mLang);
|
|
mInstructions->run(mode);
|
|
delete mInstructions;
|
|
}
|
|
|
|
// Ejecuta el juego en modo demo
|
|
void Title::runDemoGame()
|
|
{
|
|
mDemoGame = new Game(1, mRenderer, mScreen, mFileList, 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()
|
|
{
|
|
SDL_SetRenderTarget(mRenderer, mBackground);
|
|
SDL_SetRenderDrawColor(mRenderer, 0x43, 0x43, 0x4F, 0xFF);
|
|
SDL_RenderClear(mRenderer);
|
|
|
|
mTile->init(0, 0, 64, 64, mTitleTexture, mRenderer);
|
|
mTile->setSpriteClip(192, 0, 64, 64);
|
|
for (int i = 0; i < 8; i++)
|
|
for (int j = 0; j < 6; j++)
|
|
{
|
|
mTile->setPosX(i * 64);
|
|
mTile->setPosY(j * 64);
|
|
mTile->render();
|
|
}
|
|
|
|
SDL_SetRenderTarget(mRenderer, nullptr);
|
|
}
|
|
|
|
// 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());
|
|
} |