#include "title.h" #ifdef __MIPSEL__ #include #include #endif // Constructor Title::Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::string *fileList, options_t *options, Lang *lang) { // Copia las direcciones de los punteros mWindow = window; mRenderer = renderer; 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); 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; 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; //if (!mInput->gameControllerFound()) { 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; } checkInputDevices(); mDeviceIndex[0] = mAvailableInputDevices.size() - 1; mDeviceIndex[1] = 0; 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(); 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, mInput->getControllerName(0)); 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, mInput->getControllerName(0)); 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 mMenu.options->centerMenuOnX(SCREEN_CENTER_X); mMenu.options->centerMenuOnY(SCREEN_CENTER_Y); mMenu.options->centerMenuElementsOnX(); 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 mMenu.title->centerMenuOnX(SCREEN_CENTER_X); mMenu.title->centerMenuElementsOnX(); } // Aplica las opciones de menu seleccionadas void Title::applyOptions() { SDL_SetWindowFullscreen(mWindow, mOptions->fullScreenMode); SDL_SetWindowSize(mWindow, SCREEN_WIDTH * mOptions->windowSize, SCREEN_HEIGHT * mOptions->windowSize); 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(); } // Limpia la pantalla SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_RenderClear(mRenderer); // Dibuja el tileado de fondo SDL_RenderCopy(mRenderer, mBackground, &mBackgroundWindow, NULL); // Dibuja el degradado mGradient->render(); // Dibuja los objetos mCoffeeBitmap->render(); mCrisisBitmap->render(); // Actualiza la pantalla SDL_RenderPresent(mRenderer); // 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++) { // Limpia la pantalla SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_RenderClear(mRenderer); // 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(); // Actualiza la pantalla SDL_RenderPresent(mRenderer); } 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)) { // Reproduce la música JA_PlayMusic(mMusic); } // 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--; } } // Limpia la pantalla SDL_SetRenderDrawColor(mRenderer, bgColor.r, bgColor.g, bgColor.b, 255); SDL_RenderClear(mRenderer); // 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(); // Actualiza la pantalla SDL_RenderPresent(mRenderer); } 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, mFileList, mLang); mInstructions->run(mode); delete mInstructions; } // Ejecuta el juego en modo demo void Title::runDemoGame() { mDemoGame = new Game(1, mRenderer, 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]) { printf("%i:%i\n",mDeviceIndex[0],mDeviceIndex[1]); //const int temp = mDeviceIndex[0]; //mDeviceIndex[0] = mDeviceIndex[1]; //mDeviceIndex[1] = temp; const int theOtherPlayer = (numPlayer + 1) % 2; mDeviceIndex[theOtherPlayer]--; if (mDeviceIndex[theOtherPlayer] < 0) mDeviceIndex[theOtherPlayer]=numDevices-1; printf("%i:%i\n",mDeviceIndex[0],mDeviceIndex[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", 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", mAvailableInputDevices.size(), temp.name.c_str()); }