feat(menu): submenú Controls i bloqueig de polling amb menú obert

This commit is contained in:
JailDesigner committed 2026-04-22 19:05:36 +02:00
1 parent 350625dec0
commit fb40d0effb
8 files changed
+229 -7

No files matched your search

+31
View File
@@ -0,0 +1,31 @@
#include "core/input/input_state.hpp"
#include <array>
namespace InputState {
namespace {
bool blocked = false;
// Buffer retornat quan el bloqueig és actiu. `SDL_GetKeyboardState`
// retorna un pointer d'una mida igual a `SDL_SCANCODE_COUNT`; el
// nostre buffer ha de ser com a mínim igual de gran perquè els
// consumidors puguin indexar-lo amb qualsevol scancode sense
// llegir fora de rang.
auto zeroKeyboard() -> const bool* {
static const std::array<bool, SDL_SCANCODE_COUNT> ZEROS{};
return ZEROS.data();
}
} // namespace
void setBlocked(bool value) { blocked = value; }
auto isBlocked() -> bool { return blocked; }
auto getKeyboardState() -> const bool* {
return blocked ? zeroKeyboard() : SDL_GetKeyboardState(nullptr);
}
} // namespace InputState
+46
View File
@@ -0,0 +1,46 @@
#pragma once
// Wrapper de l'estat d'input (polling) amb gating de bloqueig.
//
// El service menu (i qualsevol UI modal futura) ha de poder "amagar" l'estat
// d'entrada als consumidors de polling — el jugador, entitats controlades
// per l'usuari, etc. — mentre la UI captura l'atenció, sense interrompre la
// resta del joc. Per això tots els consumidors de polling han de llegir a
// través d'aquest mòdul i no cridar `SDL_GetKeyboardState` directament. Si
// `setBlocked(true)` està actiu, el wrapper retorna un buffer tot-a-zero;
// altrament, la crida és transparent (mateix pointer que SDL).
//
// El menú NO passa per aquí: consumeix events (`SDL_EVENT_KEY_DOWN`) abans
// que l'escena els vegi, així que la seva navegació segueix funcionant per
// molt que el flag estigui posat.
//
// --- Nota per a l'extensió a gamepad (pròxima iteració) ---
// Quan s'afegeixi suport de comandament, el jugador haurà de llegir eixos
// i botons via polling (p.ex. `SDL_GetGamepadAxis`/`SDL_GetGamepadButton`).
// Aquest mòdul s'ha d'ampliar amb:
// [[nodiscard]] auto getGamepadAxis(SDL_Gamepad* gp, SDL_GamepadAxis ax)
// -> Sint16; // 0 si bloquejat
// [[nodiscard]] auto getGamepadButton(SDL_Gamepad* gp, SDL_GamepadButton b)
// -> bool; // false si bloquejat
// Mateix patró: zero/false quan `blocked_`, pass-through altrament. Així
// Player (i el que sigui) només ha de canviar el nom de la crida; el menú
// no ha de saber res del gamepad més enllà de processar els seus events.
#include <SDL3/SDL.h>
namespace InputState {
// Activa/desactiva el bloqueig global de polling. El ServiceMenu el
// crida a `toggle()`/`close()`. No es toca des de cap altre lloc.
void setBlocked(bool value);
[[nodiscard]] auto isBlocked() -> bool;
// Equivalent a `SDL_GetKeyboardState(nullptr)`: retorna un buffer de
// `SDL_SCANCODE_COUNT` bools. Si l'input està bloquejat, tots zero —
// el consumidor veu com si cap tecla estigués premuda, sense branques
// explícites. El buffer és estable mentre dura la sessió; no cal
// guardar-lo frame a frame.
[[nodiscard]] auto getKeyboardState() -> const bool*;
} // namespace InputState