From 7ac0ce93547efb6667c43a15647536dd19928372 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 3 Jun 2025 09:56:41 +0200 Subject: [PATCH] arreglos estetics en ServiceMenu afegides noves fonts de text --- data/font/04b_25_flat.png | Bin 0 -> 2084 bytes data/font/04b_25_flat_2x.png | Bin 0 -> 5004 bytes data/font/04b_25_reversed.png | Bin 0 -> 2144 bytes data/font/04b_25_reversed_2x.png | Bin 0 -> 5141 bytes source/director.cpp | 4 ++ source/resource.cpp | 4 ++ source/screen.cpp | 1 + source/service_menu.cpp | 91 +++++++++++++++++++++++++++---- source/service_menu.h | 24 +++++++- source/utils.cpp | 4 ++ source/utils.h | 4 ++ 11 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 data/font/04b_25_flat.png create mode 100644 data/font/04b_25_flat_2x.png create mode 100644 data/font/04b_25_reversed.png create mode 100644 data/font/04b_25_reversed_2x.png diff --git a/data/font/04b_25_flat.png b/data/font/04b_25_flat.png new file mode 100644 index 0000000000000000000000000000000000000000..3f5f42bb49c10ad8f6045a6155e55ca6992d3c02 GIT binary patch literal 2084 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 literal 0 HcmV?d00001 diff --git a/data/font/04b_25_reversed.png b/data/font/04b_25_reversed.png new file mode 100644 index 0000000000000000000000000000000000000000..ff5cf4c6a88e2c0785bb37076e3a842c09a40850 GIT binary patch literal 2144 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%0A2}%*piuHG1c*N|a8wLc}1A!To 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 + "/data/font/04b_25_2x.txt", AssetType::FONT); Asset::get()->add(prefix + "/data/font/04b_25_metal.png", AssetType::BITMAP); Asset::get()->add(prefix + "/data/font/04b_25_grey.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/font/04b_25_flat.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/font/04b_25_reversed.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/font/04b_25_flat_2x.png", AssetType::BITMAP); + Asset::get()->add(prefix + "/data/font/04b_25_reversed_2x.png", AssetType::BITMAP); // Textos Asset::get()->add(prefix + "/data/lang/es_ES.txt", AssetType::LANG); diff --git a/source/resource.cpp b/source/resource.cpp index 1c4ddba..e46d157 100644 --- a/source/resource.cpp +++ b/source/resource.cpp @@ -329,6 +329,10 @@ void Resource::createText() {"04b_25_2x", "04b_25_2x.png", "04b_25_2x.txt"}, {"04b_25_metal", "04b_25_metal.png", "04b_25.txt"}, {"04b_25_grey", "04b_25_grey.png", "04b_25.txt"}, + {"04b_25_flat", "04b_25_flat.png", "04b_25.txt"}, + {"04b_25_reversed", "04b_25_reversed.png", "04b_25.txt"}, + {"04b_25_flat_2x", "04b_25_flat_2x.png", "04b_25_2x.txt"}, + {"04b_25_reversed_2x", "04b_25_reversed_2x.png", "04b_25_2x.txt"}, {"8bithud", "8bithud.png", "8bithud.txt"}, {"smb2", "smb2.gif", "smb2.txt"}}; diff --git a/source/screen.cpp b/source/screen.cpp index 2bbf967..fc384a2 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -173,6 +173,7 @@ void Screen::update() fps_.calculate(SDL_GetTicks()); shake_effect_.update(src_rect_, dst_rect_); flash_effect_.update(); + serviceMenu_->update(); notifier_->update(); Mouse::updateCursorVisibility(); } diff --git a/source/service_menu.cpp b/source/service_menu.cpp index e7e232b..7880308 100644 --- a/source/service_menu.cpp +++ b/source/service_menu.cpp @@ -20,10 +20,10 @@ ServiceMenu *ServiceMenu::get() { return ServiceMenu::instance_; } // Constructor ServiceMenu::ServiceMenu() - : text_(Resource::get()->getText("04b_25_metal")) + : elementText_(Resource::get()->getText("04b_25_flat")), + titleText_(Resource::get()->getText("04b_25_flat_2x")) { - constexpr float GAP = 30.0f; - rect_ = {GAP, GAP, param.game.width - GAP * 2, param.game.height - GAP * 2}; + setAnchors(); } void ServiceMenu::toggle() @@ -35,14 +35,15 @@ void ServiceMenu::render() { if (enabled_) { - constexpr int SEPARATION = 14; + int y = rect_.y; + constexpr int H_PADDING = 20; constexpr std::array MAIN_LIST = { "VIDEO", "AUDIO", "GAME", "SYSTEM"}; - constexpr std::array VIDEO_LIST = { + constexpr std::array VIDEO_LIST = { "VIDEO MODE", "WINDOW SIZE", "SHADERS", @@ -64,29 +65,95 @@ void ServiceMenu::render() "EXIT", "SHUTDOWN"}; + constexpr std::array OPTIONS_LIST = { + "FULLSCREEN", + "3", + "OFF", + "ON", + "ON"}; + + // SOMBRA + SDL_FRect shadowRect = {rect_.x + 5, rect_.y + 5, rect_.w, rect_.h}; + SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 64); + SDL_RenderFillRect(Screen::get()->getRenderer(), &shadowRect); + // FONDO - SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 0, 0, 0, 224); + SDL_SetRenderDrawColor(Screen::get()->getRenderer(), bgColor_.r, bgColor_.g, bgColor_.b, 255); SDL_RenderFillRect(Screen::get()->getRenderer(), &rect_); // BORDE - SDL_SetRenderDrawColor(Screen::get()->getRenderer(), 224, 224, 224, 255); + SDL_SetRenderDrawColor(Screen::get()->getRenderer(), titleColor_.r, titleColor_.g, titleColor_.b, 255); SDL_RenderRect(Screen::get()->getRenderer(), &rect_); // SERVICE MENU - text_->writeDX(TEXT_COLOR | TEXT_CENTER, param.game.game_area.center_x, rect_.y + SEPARATION, "SERVICE MENU", -2, BLUE_SKY_COLOR.lighten()); + y += lineHeight_; + titleText_->writeDX(TEXT_COLOR | TEXT_CENTER, param.game.game_area.center_x, y, "SERVICE MENU", -4, titleColor_); // LINEA - SDL_SetRenderDrawColor(Screen::get()->getRenderer(), BLUE_SKY_COLOR.lighten().r, BLUE_SKY_COLOR.lighten().g, BLUE_SKY_COLOR.lighten().b, 255); - SDL_RenderLine(Screen::get()->getRenderer(), rect_.x + 20, rect_.y + SEPARATION * 3, rect_.x + rect_.w - 20, rect_.y + SEPARATION * 3); + y += lineHeight_ * 2; + SDL_SetRenderDrawColor(Screen::get()->getRenderer(), titleColor_.r, titleColor_.g, titleColor_.b, 255); + SDL_RenderLine(Screen::get()->getRenderer(), rect_.x + H_PADDING, y, rect_.x + rect_.w - H_PADDING, y); // LIST - for (size_t i = 0; i < MAIN_LIST.size(); ++i) + for (size_t i = 0; i < VIDEO_LIST.size(); ++i) { - text_->writeColored(rect_.x + 20, rect_.y + (SEPARATION * 4) + (i * (SEPARATION + SEPARATION * 0.5f)), MAIN_LIST.at(i), BLUE_SKY_COLOR.lighten(100), -2); + y += lineHeight_; + elementText_->writeColored(rect_.x + H_PADDING, y, VIDEO_LIST.at(i), i == selected_ ? selectedColor_ : textColor_, -2); + elementText_->writeColored(rect_.x + H_PADDING + 100, y, ": " + std::string(OPTIONS_LIST.at(i)), i == selected_ ? selectedColor_ : textColor_, -2); } } } void ServiceMenu::update() { + if (enabled_) + { + updateCounter(); + selectedColor_ = getSelectedColor(); + } +} + +void ServiceMenu::setAnchors() +{ + width_ = 220; + height_ = 200; + lineHeight_ = elementText_->getCharacterSize() + 5; + rect_ = { + (param.game.width - width_) / 2, + (param.game.height - height_) / 2, + static_cast(width_), + static_cast(height_)}; +} + +void ServiceMenu::updateCounter() +{ + static Uint64 lastUpdate = SDL_GetTicks(); + Uint64 currentTicks = SDL_GetTicks(); + if (currentTicks - lastUpdate >= 50) + { + counter_++; + lastUpdate = currentTicks; + } +} + +Color ServiceMenu::getSelectedColor() +{ + static std::array colors = { + Color(0xFF, 0xFF, 0x00), // Amarillo brillante + Color(0xFF, 0xD7, 0x00), // Dorado claro + Color(0xFF, 0xEF, 0x7C), // Amarillo pastel + Color(0xFF, 0xCC, 0x00), // Amarillo anaranjado + Color(0xFF, 0xF7, 0x00), // Amarillo limón + Color(0xCC, 0x99, 0x00), // Mostaza + Color(0xFF, 0xF7, 0x00), // Amarillo limón (regreso) + Color(0xFF, 0xCC, 0x00), // Amarillo anaranjado (regreso) + Color(0xFF, 0xEF, 0x7C), // Amarillo pastel (regreso) + Color(0xFF, 0xD7, 0x00), // Dorado claro (regreso) + Color(0xFF, 0xFF, 0x00), // Amarillo brillante (regreso) + Color(0xCC, 0x99, 0x00) // Mostaza (regreso, cierre) + }; + + const size_t index = counter_ % colors.size(); + + return colors.at(index); } \ No newline at end of file diff --git a/source/service_menu.h b/source/service_menu.h index 38d2075..076e2a4 100644 --- a/source/service_menu.h +++ b/source/service_menu.h @@ -4,6 +4,7 @@ #include #include #include +#include "utils.h" class Text; @@ -22,9 +23,26 @@ public: private: // -- Variables internas --- - bool enabled_ = false; // Indica si el menú de servicio está activo - SDL_FRect rect_; // Rectangulo para definir el area del menú de servicio - std::shared_ptr text_; // Objeto para escribir texto; + bool enabled_ = false; // Indica si el menú de servicio está activo + SDL_FRect rect_; // Rectangulo para definir el area del menú de servicio + std::shared_ptr elementText_; // Objeto para escribir texto; + std::shared_ptr titleText_; // Objeto para escribir texto; + size_t selected_ = 2; // Elemento del menú seleccionado + Uint32 counter_ = 0; // Contador interno + + // -- Aspecto -- + Color bgColor_ = SERV_MENU_BG_COLOR; // Color de fondo + Color titleColor_ = SERV_MENU_TITLE_COLOR; // Color del título del menu + Color textColor_ = SERV_MENU_TEXT_COLOR; // Color para el texto de los elementos + Color selectedColor_ = SERV_MENU_SELECTED_COLOR; // Color para el elemento seleccionado + int width_; // Ancho del menú + int height_; // Alto del menu + int lineHeight_; // Espacio entre elementos del menu + + // -- Métodos internos --- + void setAnchors(); // Establece el valor de las variables de anclaje + void updateCounter(); // Actualiza el contador interno + Color getSelectedColor(); // Devuelve el color del elemento seleccionado // --- Patrón Singleton --- ServiceMenu(); // Constructor privado diff --git a/source/utils.cpp b/source/utils.cpp index a3170b9..58aa68f 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -32,6 +32,10 @@ const Color GREEN_COLOR = Color(0X5B, 0XEC, 0X95); const Color BLUE_SKY_COLOR = Color(0X02, 0X88, 0XD1); const Color PINK_SKY_COLOR = Color(0XFF, 0X6B, 0X97); const Color GREEN_SKY_COLOR = Color(0X00, 0X79, 0X6B); +const Color SERV_MENU_TITLE_COLOR = Color(0XFF, 0XFF, 0XFF); +const Color SERV_MENU_TEXT_COLOR = Color(0XFF, 0XFF, 0XFF); +const Color SERV_MENU_SELECTED_COLOR = Color(0XFF, 0XFF, 0X00);; +const Color SERV_MENU_BG_COLOR = Color(0x1E, 0x1E, 0x1E); // Obtiene un color del vector de colores imitando al Coche Fantástico Color getColorLikeKnightRider(const std::vector &colors, int counter_) diff --git a/source/utils.h b/source/utils.h index 63e81e1..844ce7c 100644 --- a/source/utils.h +++ b/source/utils.h @@ -127,6 +127,10 @@ extern const Color GREEN_COLOR; extern const Color BLUE_SKY_COLOR; extern const Color PINK_SKY_COLOR; extern const Color GREEN_SKY_COLOR; +extern const Color SERV_MENU_TITLE_COLOR; +extern const Color SERV_MENU_TEXT_COLOR; +extern const Color SERV_MENU_SELECTED_COLOR; +extern const Color SERV_MENU_BG_COLOR; // Colores y gráficos Color getColorLikeKnightRider(const std::vector &colors, int counter_);