From 3bb5e5d6046c625b4a815ce7bfcb1a66c2a543bb Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Tue, 5 Aug 2025 13:12:48 +0200 Subject: [PATCH] Service Menu: afegides opcions per als mandos --- source/input.cpp | 18 +++++++++++++ source/input.h | 3 ++- source/ui/menu_renderer.h | 2 +- source/ui/service_menu.cpp | 52 +++++++++++++++++++++++++++++++++++++- source/ui/service_menu.h | 5 +++- source/utils.cpp | 12 +++++++++ source/utils.h | 1 + 7 files changed, 89 insertions(+), 4 deletions(-) diff --git a/source/input.cpp b/source/input.cpp index 0ab3173..cae33f3 100644 --- a/source/input.cpp +++ b/source/input.cpp @@ -138,6 +138,15 @@ auto Input::gameControllerFound() const -> bool { return !gamepads_.empty(); } // Obten el nombre de un mando de juego auto Input::getControllerName(std::shared_ptr gamepad) const -> std::string { return gamepad == nullptr ? std::string() : gamepad->name; } +// Obtiene la lista de nombres de mandos +auto Input::getControllerNames() const -> std::vector { + std::vector names; + for (const auto &gamepad : gamepads_) { + names.push_back(gamepad->name); + } + return names; +} + // Obten el número de mandos conectados auto Input::getNumGamepads() const -> int { return gamepads_.size(); } @@ -151,6 +160,15 @@ std::shared_ptr Input::getGamepad(SDL_JoystickID id) const { return nullptr; } +std::shared_ptr Input::getGamepadByName(const std::string &name) const { + for (const auto &gamepad : gamepads_) { + if (gamepad && gamepad->name == name) { + return gamepad; + } + } + return nullptr; +} + // Obtiene el SDL_GamepadButton asignado a un input auto Input::getControllerBinding(std::shared_ptr gamepad, Action input) const -> SDL_GamepadButton { return gamepad->bindings[input].button; diff --git a/source/input.h b/source/input.h index 1677c09..1aafad9 100644 --- a/source/input.h +++ b/source/input.h @@ -153,8 +153,10 @@ class Input { // --- Métodos de gestión de mandos --- [[nodiscard]] auto gameControllerFound() const -> bool; auto getControllerName(std::shared_ptr gamepad) const -> std::string; + auto getControllerNames() const -> std::vector; [[nodiscard]] auto getNumGamepads() const -> int; std::shared_ptr getGamepad(SDL_JoystickID id) const; + std::shared_ptr getGamepadByName(const std::string &name) const; const Gamepads &getGamepads() const { return gamepads_; } // --- Métodos de consulta y utilidades --- @@ -170,7 +172,6 @@ class Input { void printConnectedGamepads() const; - //[[nodiscard]] auto getGamepads() const -> const Gamepads & { return gamepads_; } std::shared_ptr findAvailableGamepadByName(const std::string &gamepad_name); void saveGamepadConfigFromGamepad(std::shared_ptr gamepad); diff --git a/source/ui/menu_renderer.h b/source/ui/menu_renderer.h index 461104c..f9ed3e3 100644 --- a/source/ui/menu_renderer.h +++ b/source/ui/menu_renderer.h @@ -57,7 +57,7 @@ class MenuRenderer { bool resizing_ = false; // --- Anchos precalculados --- - std::array group_menu_widths_ = {}; + std::array group_menu_widths_ = {}; // --- Métodos privados de la vista --- void setAnchors(const ServiceMenu *menu_state); diff --git a/source/ui/service_menu.cpp b/source/ui/service_menu.cpp index 786911c..5c38e06 100644 --- a/source/ui/service_menu.cpp +++ b/source/ui/service_menu.cpp @@ -176,6 +176,9 @@ void ServiceMenu::updateMenu() { } void ServiceMenu::applySettings() { + if (current_settings_group_ == SettingsGroup::CONTROLS) { + applyControlsSettings(); + } if (current_settings_group_ == SettingsGroup::VIDEO) { applyVideoSettings(); } @@ -190,6 +193,8 @@ void ServiceMenu::applySettings() { updateOptionPairs(); } +void ServiceMenu::applyControlsSettings() {} + void ServiceMenu::applyVideoSettings() { Screen::get()->applySettings(); setHiddenOptions(); @@ -216,6 +221,7 @@ auto ServiceMenu::getOptionByCaption(const std::string &caption) const -> MenuOp auto ServiceMenu::getCurrentGroupAlignment() const -> ServiceMenu::GroupAlignment { switch (current_settings_group_) { + case SettingsGroup::CONTROLS: case SettingsGroup::VIDEO: case SettingsGroup::AUDIO: case SettingsGroup::SETTINGS: @@ -239,6 +245,43 @@ auto ServiceMenu::countOptionsInGroup(SettingsGroup group) const -> size_t { void ServiceMenu::initializeOptions() { options_.clear(); + // CONTROLS + options_.push_back(std::make_unique( + "Mando Jugador 1", + SettingsGroup::CONTROLS, + Input::get()->getControllerNames(), + []() { + return Options::gamepad_manager.getGamepad(Player::Id::PLAYER1).name; + }, + [](const std::string &val) { + Options::gamepad_manager.assignGamepadToPlayer(Player::Id::PLAYER1, Input::get()->getGamepadByName(val), val); + })); + + options_.push_back(std::make_unique( + "Mando Jugador 2", + SettingsGroup::CONTROLS, + Input::get()->getControllerNames(), + []() { + return Options::gamepad_manager.getGamepad(Player::Id::PLAYER2).name; + }, + [](const std::string &val) { + Options::gamepad_manager.assignGamepadToPlayer(Player::Id::PLAYER2, Input::get()->getGamepadByName(val), val); + })); + + options_.push_back(std::make_unique( + "Teclat", + SettingsGroup::CONTROLS, + std::vector{ + "Jugador 1", + "Jugador 2"}, + []() { + return Lang::getNameFromCode(Options::pending_changes.new_language); + }, + [](const std::string &val) { + Options::pending_changes.new_language = Lang::getCodeFromName(val); + Options::checkPendingChanges(); + })); + // VIDEO options_.push_back(std::make_unique( Lang::getText("[SERVICE_MENU] FULLSCREEN"), @@ -366,6 +409,11 @@ void ServiceMenu::initializeOptions() { !Options::settings.shutdown_enabled)); // MAIN MENU + options_.push_back(std::make_unique( + "Controls", + SettingsGroup::MAIN, + SettingsGroup::CONTROLS)); + options_.push_back(std::make_unique( Lang::getText("[SERVICE_MENU] VIDEO"), SettingsGroup::MAIN, @@ -410,8 +458,10 @@ auto ServiceMenu::settingsGroupToString(SettingsGroup group) -> std::string { switch (group) { case SettingsGroup::MAIN: return Lang::getText("[SERVICE_MENU] TITLE"); + case SettingsGroup::CONTROLS: + return Lang::getText("[SERVICE_MENU] TITLE"); case SettingsGroup::VIDEO: - return Lang::getText("[SERVICE_MENU] VIDEO"); + return "Controls"; case SettingsGroup::AUDIO: return Lang::getText("[SERVICE_MENU] AUDIO"); case SettingsGroup::SETTINGS: diff --git a/source/ui/service_menu.h b/source/ui/service_menu.h index 044902b..5168622 100644 --- a/source/ui/service_menu.h +++ b/source/ui/service_menu.h @@ -9,11 +9,12 @@ #include "ui_message.h" // Para UIMessage class MenuOption; -class MenuRenderer; // <-- Nuevo +class MenuRenderer; class ServiceMenu { public: enum class SettingsGroup { + CONTROLS, VIDEO, AUDIO, SETTINGS, @@ -30,6 +31,7 @@ class ServiceMenu { static constexpr size_t OPTIONS_HORIZONTAL_PADDING = 20; static constexpr size_t MIN_WIDTH = 240; static constexpr size_t MIN_GAP_OPTION_VALUE = 30; + static constexpr size_t SETTINGS_GROUP_SIZE = 6; // --- Métodos de singleton --- static void init(); @@ -88,6 +90,7 @@ class ServiceMenu { void initializeOptions(); void updateMenu(); void applySettings(); + void applyControlsSettings(); void applyVideoSettings(); static void applyAudioSettings(); void applySettingsSettings(); diff --git a/source/utils.cpp b/source/utils.cpp index 5de8c3c..f936d4b 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -383,4 +383,16 @@ auto getFileName(const std::string &path) -> std::string { auto getPath(const std::string &full_path) -> std::string { std::filesystem::path path(full_path); return path.parent_path().string(); +} + +// Trunca un string y le añade puntos suspensivos +auto truncateWithEllipsis(const std::string &input, size_t length) -> std::string { + if (input.size() <= length) { + return input; + } + if (length <= 3) { + // Not enough space for any content plus ellipsis + return std::string(length, '.'); + } + return input.substr(0, length) + "..."; } \ No newline at end of file diff --git a/source/utils.h b/source/utils.h index de85b13..4ba7a90 100644 --- a/source/utils.h +++ b/source/utils.h @@ -116,6 +116,7 @@ auto easeInCubic(double time) -> double; // Utilidades varias auto stringInVector(const std::vector &vec, const std::string &str) -> bool; // Comprueba si un vector contiene una cadena void printWithDots(const std::string &text1, const std::string &text2, const std::string &text3); // Imprime una línea con puntos +auto truncateWithEllipsis(const std::string &input, size_t length) -> std::string; // Trunca un string y le añade puntos suspensivos // Demo auto loadDemoDataFromFile(const std::string &file_path) -> DemoData;