feat(ui): tria del mando per jugador al menú de servei
This commit is contained in:
1 parent
a725b76684
commit
e5b8d7731b
2 files changed
+75
-5
No files matched your search
@@ -47,6 +47,7 @@ menu:
|
|||||||
system: "Sistema"
|
system: "Sistema"
|
||||||
labels:
|
labels:
|
||||||
player_1: "Jugador 1"
|
player_1: "Jugador 1"
|
||||||
|
player_2: "Jugador 2"
|
||||||
gamepad_unavailable: "No disponible"
|
gamepad_unavailable: "No disponible"
|
||||||
items:
|
items:
|
||||||
video_submenu: "Vídeo"
|
video_submenu: "Vídeo"
|
||||||
@@ -59,6 +60,8 @@ menu:
|
|||||||
move_down: "Avall"
|
move_down: "Avall"
|
||||||
move_left: "Esquerra"
|
move_left: "Esquerra"
|
||||||
move_right: "Dreta"
|
move_right: "Dreta"
|
||||||
|
gamepad_p1: "Comandament P1"
|
||||||
|
gamepad_p2: "Comandament P2"
|
||||||
zoom: "Zoom"
|
zoom: "Zoom"
|
||||||
screen: "Pantalla completa"
|
screen: "Pantalla completa"
|
||||||
vsync: "VSync"
|
vsync: "VSync"
|
||||||
@@ -88,3 +91,5 @@ menu:
|
|||||||
render_info_off: "Apagat"
|
render_info_off: "Apagat"
|
||||||
render_info_top: "Dalt"
|
render_info_top: "Dalt"
|
||||||
render_info_bottom: "Baix"
|
render_info_bottom: "Baix"
|
||||||
|
gamepad_none: "Cap"
|
||||||
|
gamepad_disconnected: "Desconnectat"
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "core/audio/audio.hpp"
|
#include "core/audio/audio.hpp"
|
||||||
|
#include "core/input/gamepad_manager.hpp"
|
||||||
#include "core/input/input_state.hpp"
|
#include "core/input/input_state.hpp"
|
||||||
#include "core/input/key_config.hpp"
|
#include "core/input/key_config.hpp"
|
||||||
#include "core/locale/locale.hpp"
|
#include "core/locale/locale.hpp"
|
||||||
@@ -752,14 +753,78 @@ auto ServiceMenu::buildKeyboardControls() -> Page {
|
|||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Índex del cycle per a un jugador donat. 0 = "Cap" (desassignat o
|
||||||
|
// sense coincidència amb cap mando connectat); 1..N = mando `idx-1`
|
||||||
|
// de la llista actual de `GamepadManager::getAll()`. La coincidència
|
||||||
|
// es fa primer per ruta (estable entre sessions) i si no, per nom.
|
||||||
|
auto currentPadIndex(int player_id) -> std::size_t {
|
||||||
|
const auto PADS = GamepadManager::get().getAll();
|
||||||
|
const auto& slot = (player_id == 0) ? Options::controls().gamepad_p1
|
||||||
|
: Options::controls().gamepad_p2;
|
||||||
|
if (slot.name.empty() && slot.path.empty()) { return 0; }
|
||||||
|
for (std::size_t i = 0; i < PADS.size(); ++i) {
|
||||||
|
if (!slot.path.empty() && PADS[i].path == slot.path) { return i + 1; }
|
||||||
|
}
|
||||||
|
for (std::size_t i = 0; i < PADS.size(); ++i) {
|
||||||
|
if (!slot.name.empty() && PADS[i].name == slot.name) { return i + 1; }
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text visible per a cada índex del cycle. 0 → "Cap"; altrament
|
||||||
|
// el nom del mando. Si l'índex queda fora de rang (p.ex. un mando
|
||||||
|
// desenchufat just abans que es repinte el label) mostrem el nom
|
||||||
|
// persistit amb un sufix "(desconnectat)" per no deixar l'usuari
|
||||||
|
// sense feedback.
|
||||||
|
auto padLabel(int player_id, std::size_t idx) -> std::string {
|
||||||
|
if (idx == 0) { return Locale::get().text("menu.values.gamepad_none"); }
|
||||||
|
const auto PADS = GamepadManager::get().getAll();
|
||||||
|
const std::size_t POS = idx - 1;
|
||||||
|
if (POS < PADS.size()) { return PADS[POS].name; }
|
||||||
|
const auto& slot = (player_id == 0) ? Options::controls().gamepad_p1
|
||||||
|
: Options::controls().gamepad_p2;
|
||||||
|
return slot.name + " (" + Locale::get().text("menu.values.gamepad_disconnected") + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Aplica la selecció del cycle: 0 desassigna, altres índexs vinculen
|
||||||
|
// el mando corresponent. Options persisteix i crida el GamepadManager.
|
||||||
|
void applyPadSelection(int player_id, std::size_t idx) {
|
||||||
|
if (idx == 0) {
|
||||||
|
Options::setGamepadAssignment(player_id, "", "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto PADS = GamepadManager::get().getAll();
|
||||||
|
const std::size_t POS = idx - 1;
|
||||||
|
if (POS >= PADS.size()) { return; }
|
||||||
|
Options::setGamepadAssignment(player_id, PADS[POS].name, PADS[POS].path);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
auto ServiceMenu::buildGamepadControls() -> Page {
|
auto ServiceMenu::buildGamepadControls() -> Page {
|
||||||
Page page;
|
Page page;
|
||||||
page.title_key = "menu.titles.gamepad";
|
page.title_key = "menu.titles.gamepad";
|
||||||
page.center_items = true;
|
|
||||||
// Placeholder: un sol LABEL que indica que la pàgina encara no té
|
// Un cycle per jugador. L'opció 0 és sempre "Cap"; la resta es
|
||||||
// contingut real. Quan s'afegeixi el suport de gamepad, aquesta
|
// generen dinàmicament a partir de `GamepadManager::getAll()` cada
|
||||||
// pàgina es substituirà pel llistat real de botons mapejables.
|
// frame, així que un mando acabat de connectar ja apareix sense
|
||||||
page.items.push_back(makeLabel(Locale::get().text("menu.labels.gamepad_unavailable")));
|
// haver de tornar a obrir el submenú.
|
||||||
|
page.items.push_back(makeCycle(
|
||||||
|
"menu.items.gamepad_p1",
|
||||||
|
[]() { return currentPadIndex(0); },
|
||||||
|
[]() { return GamepadManager::get().getAll().size() + 1; },
|
||||||
|
[](std::size_t idx) { applyPadSelection(0, idx); },
|
||||||
|
[](std::size_t idx) { return padLabel(0, idx); }));
|
||||||
|
|
||||||
|
page.items.push_back(makeCycle(
|
||||||
|
"menu.items.gamepad_p2",
|
||||||
|
[]() { return currentPadIndex(1); },
|
||||||
|
[]() { return GamepadManager::get().getAll().size() + 1; },
|
||||||
|
[](std::size_t idx) { applyPadSelection(1, idx); },
|
||||||
|
[](std::size_t idx) { return padLabel(1, idx); }));
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user