From 0341a0fe9d954724f72866b3801607d796c5cd43 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Sat, 28 Aug 2021 23:17:00 +0200 Subject: [PATCH] working on options menu, almost done --- source/const.h | 2 +- source/director.cpp | 5 +- source/menu.cpp | 46 ++++++------- source/menu.h | 10 ++- source/title.cpp | 160 +++++++++++++++++++++++++++++--------------- source/title.h | 4 ++ source/utils.h | 3 - 7 files changed, 141 insertions(+), 89 deletions(-) diff --git a/source/const.h b/source/const.h index 28d22d7..39c7d44 100644 --- a/source/const.h +++ b/source/const.h @@ -298,7 +298,7 @@ const int MULTIPLIER_NUMBER_Y = SCREEN_HEIGHT - (2 * BLOCK) + 2; #define ITEM_COFFEE_MACHINE_ODDS 4 // Cantidad de objetos simultaneos -#define MAX_ITEMS 5 +#define MAX_ITEMS 10 // Valores para las variables asociadas a los objetos #define REMAINING_EXPLOSIONS 3 diff --git a/source/director.cpp b/source/director.cpp index f438ef9..664c890 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -24,7 +24,7 @@ Director::Director(std::string path) // Inicializa el objeto de idioma mLang = new Lang(mFileList); - // Crea el objeto y carga el fichero de configuración + // Crea el puntero a la estructura y carga el fichero de configuración mOptions = new options_t; if (!loadConfigFile()) { @@ -32,11 +32,8 @@ Director::Director(std::string path) mOptions->windowSize = 3; mOptions->language = en_UK; mOptions->fullScreenMode = 0; - mOptions->fullScreenModePrevious = 0; mOptions->windowSize = 3; - mOptions->windowSizePrevious = 3; mOptions->language = en_UK; - mOptions->languagePrevious = en_UK; mOptions->difficulty = 0; mOptions->player1Input = INPUT_USE_KEYBOARD; mOptions->player2Input = INPUT_USE_GAMECONTROLLER; diff --git a/source/menu.cpp b/source/menu.cpp index be18901..0cad019 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -63,7 +63,7 @@ void Menu::init(std::string name, int x, int y, int backgroundType) mSelector.moving = false; // Elementos del menu - for (int i = 0; i < 10; i++) + for (int i = 0; i < MAX_ITEMS; i++) { mItem[i].label = ""; mItem[i].w = 0; @@ -209,6 +209,8 @@ bool Menu::increaseSelectorIndex() if (mSelector.index < (mTotalItems - 1)) { mSelector.index++; + while ((!mItem[mSelector.index].selectable) && (mSelector.index < (mTotalItems - 1))) + mSelector.index++; success = true; } @@ -227,6 +229,8 @@ bool Menu::decreaseSelectorIndex() if (mSelector.index > 0) { mSelector.index--; + while ((!mItem[mSelector.index].selectable) && (mSelector.index > 0)) + mSelector.index--; success = true; } @@ -302,6 +306,7 @@ void Menu::setRectSize() void Menu::setTotalItems(int num) { mTotalItems = num; + mTotalItems > MAX_ITEMS ? MAX_ITEMS : mTotalItems; } // Establece el color del rectangulo de fondo @@ -346,7 +351,7 @@ void Menu::centerMenuOnX(int value) mPosX = (value) - (mWidestItem / 2); // Reposiciona los elementos del menu - for (int i = 0; i < 10; i++) + for (int i = 0; i < MAX_ITEMS; i++) { mItem[i].x = mPosX; } @@ -395,33 +400,24 @@ void Menu::centerMenuElementsOnX() } // Añade un item al menu -void Menu::addItem(std::string text, const Uint8 hPaddingUp, const Uint8 hPaddingDown) +void Menu::addItem(std::string text, const Uint8 hPaddingUp, const Uint8 hPaddingDown, bool selectable, bool greyed) { - // Si es el primer item coge la posición y del propio menu + // Si es el primer item coge la posición en el eje Y del propio menu if (mTotalItems == 0) - { - mItem[mTotalItems].label = text; - mItem[mTotalItems].w = mText->lenght(mItem[mTotalItems].label); - mItem[mTotalItems].h = mText->getCharacterWidth() + (mVerticalPadding * 2); - mItem[mTotalItems].x = mPosX; mItem[mTotalItems].y = mPosY; - mItem[mTotalItems].hPaddingUp = hPaddingUp; - mItem[mTotalItems].hPaddingDown = hPaddingDown; - } else - { - // En caso contrario, coge la posición y a partir del elemento anterior - if (mTotalItems < 10) - { - mItem[mTotalItems].label = text; - mItem[mTotalItems].w = mText->lenght(mItem[mTotalItems].label); - mItem[mTotalItems].h = mText->getCharacterWidth() + (mVerticalPadding * 2); - mItem[mTotalItems].x = mPosX; - mItem[mTotalItems].y = mItem[mTotalItems - 1].y + mItem[mTotalItems - 1].h + mItem[mTotalItems - 1].hPaddingDown; - mItem[mTotalItems].hPaddingUp = hPaddingUp; - mItem[mTotalItems].hPaddingDown = hPaddingDown; - } - } + // En caso contrario, coge la posición en el eje Y a partir del elemento anterior + mItem[mTotalItems].y = mItem[mTotalItems - 1].y + mItem[mTotalItems - 1].h + mItem[mTotalItems - 1].hPaddingDown; + + mItem[mTotalItems].label = text; + mItem[mTotalItems].w = mText->lenght(mItem[mTotalItems].label); + mItem[mTotalItems].h = mText->getCharacterWidth() + (mVerticalPadding * 2); + mItem[mTotalItems].x = mPosX; + mItem[mTotalItems].hPaddingUp = hPaddingUp; + mItem[mTotalItems].hPaddingDown = hPaddingDown; + mItem[mTotalItems].selectable = selectable; + mItem[mTotalItems].greyed = greyed; + setTotalItems(mTotalItems + 1); reorganize(); setSelectorPos(0); diff --git a/source/menu.h b/source/menu.h index 7d254e1..5249af1 100644 --- a/source/menu.h +++ b/source/menu.h @@ -8,6 +8,8 @@ #ifndef MENU_H #define MENU_H +#define MENU_MAX_ITEMS 50 + // Clase menu class Menu { @@ -27,7 +29,7 @@ private: bool mIsCenteredOnY; // Variable para saber si el menu debe estar centrado respecto a un punto en el eje Y int mCenterX; // Centro del menu en el eje X int mCenterY; // Centro del menu en el eje Y - bool mAreElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X + bool mAreElementsCenteredOnX; // Variable para saber si los elementos van centrados en el eje X Uint16 mWidestItem; // Anchura del elemento más ancho Uint16 mHeight; // Altura del menu Uint16 mWidth; // Anchura del menu @@ -55,8 +57,10 @@ private: Uint8 h; // Alto del elemento Uint8 hPaddingUp; // Espaciado sobre el elemento Uint8 hPaddingDown; // Espaciado bajo el elemento + bool selectable; // Indica si se puede seleccionar + bool greyed; // Indica si ha de aparecer con otro color mas oscuro }; - item mItem[10]; // Estructura para cada elemento del menu + item mItem[MENU_MAX_ITEMS]; // Estructura para cada elemento del menu struct selector { @@ -170,7 +174,7 @@ public: void centerMenuElementsOnX(); // Añade un item al menu - void addItem(std::string text, const Uint8 hPaddingUp = 0, const Uint8 hPaddingDown = 0); + void addItem(std::string text, const Uint8 hPaddingUp = 0, const Uint8 hPaddingDown = 0, bool selectable = true, bool greyed = false); // Cambia el texto de un item void setItemCaption(Uint8 index, std::string text); diff --git a/source/title.cpp b/source/title.cpp index 136d188..a6169ab 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -263,23 +263,25 @@ void Title::init(bool demo, Uint8 subsection) mMenu.title->centerMenuElementsOnX(); mMenu.options->init("OPTIONS", 0, BLOCK, MENU_BACKGROUND_TRANSPARENT); - mMenu.options->addItem(mLang->getText(59), 0, 5); // DIFFICULTY - mMenu.options->addItem(mLang->getText(62)); // PLAYER 1 CONTROLS - mMenu.options->addItem(mLang->getText(63), 0, 5); // PLAYER 2 CONTROLS - mMenu.options->addItem(mLang->getText(8), 0, 5); // LANGUAGE - mMenu.options->addItem(mLang->getText(58)); // DISPLAY MODE - mMenu.options->addItem(mLang->getText(7)); // WINDOW SIZE - mMenu.options->addItem(mLang->getText(60)); // FILTER - mMenu.options->addItem(mLang->getText(61), 0, 5); //VSYNC - mMenu.options->addItem(mLang->getText(9)); // ACCEPT - mMenu.options->addItem(mLang->getText(10)); // CANCEL + mMenu.options->addItem(mLang->getText(59), 0, 5); // (0) DIFFICULTY + mMenu.options->addItem(mLang->getText(62)); // (1) PLAYER 1 CONTROLS + mMenu.options->addItem(mLang->getText(69), 0, 0, false, false); // (2) KEYBOARD + mMenu.options->addItem(mLang->getText(63)); // (3) PLAYER 2 CONTROLS + mMenu.options->addItem(mLang->getText(70), 0, 5, false, false); // (4) GAME CONTROLLER + mMenu.options->addItem(mLang->getText(8), 0, 5); // (5) LANGUAGE + mMenu.options->addItem(mLang->getText(58)); // (6) DISPLAY MODE + mMenu.options->addItem(mLang->getText(4), 0, 0, false, false); // (7) WINDOWED + mMenu.options->addItem(mLang->getText(7)); // (8) WINDOW SIZE + mMenu.options->addItem(mLang->getText(60)); // (9) FILTER + mMenu.options->addItem(mLang->getText(61), 0, 5); // (10) VSYNC + mMenu.options->addItem(mLang->getText(9)); // (11) ACCEPT + mMenu.options->addItem(mLang->getText(10)); // (12) CANCEL mMenu.options->setDefaultActionWhenCancel(9); 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); - mMenu.options->centerMenuElementsOnX(); // Actualiza los textos de los menus updateMenuLabels(); @@ -330,122 +332,132 @@ void Title::switchFullScreenModeVar() // Actualiza los elementos de los menus void Title::updateMenuLabels() { + int i = 0; // DIFFICULTY switch (mOptions->difficulty) { case DIFFICULTY_EASY: - mMenu.options->setItemCaption(0, mLang->getText(59) + ": " + mLang->getText(66)); // EASY + mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(66)); // EASY break; case DIFFICULTY_NORMAL: - mMenu.options->setItemCaption(0, mLang->getText(59) + ": " + mLang->getText(67)); // NORMAL + mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(67)); // NORMAL break; case DIFFICULTY_HARD: - mMenu.options->setItemCaption(0, mLang->getText(59) + ": " + mLang->getText(68)); // HARD + mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(68)); // HARD break; default: - mMenu.options->setItemCaption(0, mLang->getText(59) + ": " + mLang->getText(67)); // NORMAL + mMenu.options->setItemCaption(i, mLang->getText(59) + ": " + mLang->getText(67)); // NORMAL break; } + i = 2; // PLAYER 1 CONTROLS switch (mOptions->player1Input) { case INPUT_USE_KEYBOARD: - mMenu.options->setItemCaption(1, mLang->getText(62) + ": " + mLang->getText(69)); // KEYBOARD + mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD break; case INPUT_USE_GAMECONTROLLER: - mMenu.options->setItemCaption(1, mLang->getText(62) + ": " + mLang->getText(70)); // GAME CONTROLLER + mMenu.options->setItemCaption(i, mLang->getText(70)); // GAME CONTROLLER break; default: - mMenu.options->setItemCaption(1, mLang->getText(62) + ": " + mLang->getText(69)); // KEYBOARD + mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD break; } + i = 4; // PLAYER 2 CONTROLS switch (mOptions->player2Input) { case INPUT_USE_KEYBOARD: - mMenu.options->setItemCaption(2, mLang->getText(63) + ": " + mLang->getText(69)); // KEYBOARD + mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD break; case INPUT_USE_GAMECONTROLLER: - mMenu.options->setItemCaption(2, mLang->getText(63) + ": " + mLang->getText(70)); // GAME CONTROLLER + mMenu.options->setItemCaption(i, mLang->getText(70)); // GAME CONTROLLER break; default: - mMenu.options->setItemCaption(2, mLang->getText(63) + ": " + mLang->getText(69)); // KEYBOARD + mMenu.options->setItemCaption(i, mLang->getText(69)); // KEYBOARD break; } + i++; // LANGUAGE switch (mOptions->language) { case es_ES: - mMenu.options->setItemCaption(3, mLang->getText(8) + ": " + mLang->getText(24)); // SPANISH + mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(24)); // SPANISH break; case ba_BA: - mMenu.options->setItemCaption(3, mLang->getText(8) + ": " + mLang->getText(25)); // VALENCIAN + mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(25)); // VALENCIAN break; case en_UK: - mMenu.options->setItemCaption(3, mLang->getText(8) + ": " + mLang->getText(26)); // ENGLISH + mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(26)); // ENGLISH break; default: - mMenu.options->setItemCaption(3, mLang->getText(8) + ": " + mLang->getText(26)); // ENGLISH + mMenu.options->setItemCaption(i, mLang->getText(8) + ": " + mLang->getText(26)); // ENGLISH break; } + i = 7; // DISPLAY MODE switch (mOptions->fullScreenMode) { case 0: - mMenu.options->setItemCaption(4, mLang->getText(58) + ": " + mLang->getText(4)); // WINDOW + mMenu.options->setItemCaption(i, mLang->getText(4)); // WINDOW break; case SDL_WINDOW_FULLSCREEN: - mMenu.options->setItemCaption(4, mLang->getText(58) + ": " + mLang->getText(5)); // FULLSCREEN + mMenu.options->setItemCaption(i, mLang->getText(5)); // FULLSCREEN break; case SDL_WINDOW_FULLSCREEN_DESKTOP: - mMenu.options->setItemCaption(4, mLang->getText(58) + ": " + mLang->getText(6)); // FAKE FULLSCREEN + mMenu.options->setItemCaption(i, mLang->getText(6)); // FAKE FULLSCREEN break; default: - mMenu.options->setItemCaption(4, mLang->getText(58) + ": " + mLang->getText(4)); // WINDOW + mMenu.options->setItemCaption(i, mLang->getText(4)); // WINDOW break; } + i++; // WINDOW SIZE - mMenu.options->setItemCaption(5, mLang->getText(7) + " x" + std::to_string(mOptions->windowSize)); // WINDOW SIZE + mMenu.options->setItemCaption(i, mLang->getText(7) + " x" + std::to_string(mOptions->windowSize)); // WINDOW SIZE + i++; // FILTER if (mOptions->filter == FILTER_BILINEAL) - mMenu.options->setItemCaption(6, mLang->getText(60) + ": " + mLang->getText(71)); // BILINEAL + mMenu.options->setItemCaption(i, mLang->getText(60) + ": " + mLang->getText(71)); // BILINEAL else - mMenu.options->setItemCaption(6, mLang->getText(60) + ": " + mLang->getText(72)); // LINEAL + mMenu.options->setItemCaption(i, mLang->getText(60) + ": " + mLang->getText(72)); // LINEAL + i++; // VSYNC if (mOptions->vSync) - mMenu.options->setItemCaption(7, mLang->getText(61) + ": " + mLang->getText(73)); // ON + mMenu.options->setItemCaption(i, mLang->getText(61) + ": " + mLang->getText(73)); // ON else - mMenu.options->setItemCaption(7, mLang->getText(61) + ": " + mLang->getText(74)); // OFF + mMenu.options->setItemCaption(i, mLang->getText(61) + ": " + mLang->getText(74)); // OFF + i++; // ACCEPT - mMenu.options->setItemCaption(8, mLang->getText(9)); // ACCEPT + mMenu.options->setItemCaption(i, mLang->getText(9)); // ACCEPT + i++; // CANCEL - mMenu.options->setItemCaption(9, mLang->getText(10)); // 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.options->centerMenuElementsOnX(); mMenu.title->setItemCaption(0, mLang->getText(51)); // 1 PLAYER mMenu.title->setItemCaption(1, mLang->getText(52)); // 2 PLAYERS @@ -694,9 +706,10 @@ section_t Title::run(Uint8 subsection) break; case 2: // OPTIONS mMenu.active = mMenu.options; - mOptions->fullScreenModePrevious = mOptions->fullScreenMode; - mOptions->windowSizePrevious = mOptions->windowSize; - mOptions->languagePrevious = mOptions->language; + mOptionsPrevious = *mOptions; + //mOptions->fullScreenModePrevious = mOptions->fullScreenMode; + //mOptions->windowSizePrevious = mOptions->windowSize; + //mOptions->languagePrevious = mOptions->language; break; //case 3: // HOW TO PLAY // runInstructions(INSTRUCTIONS_MODE_MANUAL); @@ -716,31 +729,63 @@ section_t Title::run(Uint8 subsection) { switch (mMenu.active->getItemSelected()) { - case 0: // Fullscreen mode - switchFullScreenModeVar(); + 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: // Windows size - mOptions->windowSize++; - if (mOptions->windowSize == 5) - mOptions->windowSize = 1; + case 1: // PLAYER 1 CONTROLS + SwitchInputs(1); updateMenuLabels(); break; - case 2: // Language + case 3: // PLAYER 2 CONTROLS + SwitchInputs(2); + updateMenuLabels(); + break; + case 5: // Language mOptions->language++; if (mOptions->language == 3) mOptions->language = 0; updateMenuLabels(); break; - case 3: // OK + case 6: // Display mode + switchFullScreenModeVar(); + updateMenuLabels(); + break; + case 8: // Windows size + mOptions->windowSize++; + if (mOptions->windowSize == 5) + mOptions->windowSize = 1; + updateMenuLabels(); + break; + case 9: // FILTER + if (mOptions->filter == FILTER_BILINEAL) + mOptions->filter = FILTER_LINEAL; + else + mOptions->filter = FILTER_BILINEAL; + updateMenuLabels(); + break; + case 10: // VSYNC + if (mOptions->vSync) + mOptions->vSync = false; + else + mOptions->vSync = true; + updateMenuLabels(); + break; + case 11: // ACCEPT applyOptions(); mMenu.active->reset(); mMenu.active = mMenu.title; break; - case 4: // CANCEL - mOptions->fullScreenMode = mOptions->fullScreenModePrevious; - mOptions->windowSize = mOptions->windowSizePrevious; - mOptions->language = mOptions->languagePrevious; + case 12: // CANCEL + mOptions = &mOptionsPrevious; + //mOptions->fullScreenMode = mOptions->fullScreenModePrevious; + //mOptions->windowSize = mOptions->windowSizePrevious; + //mOptions->language = mOptions->languagePrevious; updateMenuLabels(); mMenu.active->reset(); mMenu.active = mMenu.title; @@ -831,4 +876,13 @@ void Title::runDemoGame() mDemoGame = new Game(1, mRenderer, mFileList, mLang, mInput, mInput, true, DIFFICULTY_NORMAL); mDemoGame->run(); delete mDemoGame; -} \ No newline at end of file +} + + // Modifica las opciones para los controles de los jugadores + void Title::SwitchInputs(int value) + { + Uint8 temp; + temp = mOptions->player1Input; + mOptions->player1Input = mOptions->player2Input; + mOptions->player2Input = temp; + } \ No newline at end of file diff --git a/source/title.h b/source/title.h index fa85bbe..ec9d838 100644 --- a/source/title.h +++ b/source/title.h @@ -71,6 +71,7 @@ private: menu_t mMenu; // Variable con todos los objetos menus y sus variables struct options_t *mOptions; // Variable con todas las variables de las opciones del programa + options_t mOptionsPrevious; // Variable de respaldo para las opciones // Carga los recursos necesarios para la sección 'Title' bool loadMedia(); @@ -90,6 +91,9 @@ private: // Ejecuta el juego en modo demo void runDemoGame(); + // Modifica las opciones para los controles de los jugadores + void SwitchInputs(int value); + public: // Constructor Title(SDL_Window *window, SDL_Renderer *renderer, Input *input, std::string *fileList, options_t *options, Lang *lang); diff --git a/source/utils.h b/source/utils.h index bfe7824..f336f0f 100644 --- a/source/utils.h +++ b/source/utils.h @@ -46,11 +46,8 @@ struct options_t Uint8 player1Input; // Modo de control para el jugador 1 (teclado o mando) Uint8 player2Input; // Modo de control para el jugador 2 (teclado o mando) Uint8 language; // Idioma usado en el juego - Uint8 languagePrevious; // Usado por si se cancelan los cambios en el menu de opciones Uint32 fullScreenMode; // Contiene el valor del modo de pantalla completa - Uint32 fullScreenModePrevious; // Usado por si se cancelan los cambios en el menu de opciones Uint8 windowSize; // Contiene el valor del tamaño de la ventana - Uint8 windowSizePrevious; // Usado por si se cancelan los cambios en el menu de opciones Uint32 filter; // Filtro usado para el escalado de la imagen bool vSync; // Indica si se quiere usar vsync o no };