soport de gamepad per a wasm
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "core/rendering/render_info.hpp" // Para RenderInfo
|
||||
#include "core/rendering/screen.hpp" // Para Screen
|
||||
#include "core/system/global_events.hpp" // Para GlobalEvents::consumeGamepadButtonPressed
|
||||
#include "game/options.hpp" // Para Options, options, OptionsVideo, Section
|
||||
#include "game/scene_manager.hpp" // Para SceneManager
|
||||
#include "game/ui/console.hpp" // Para Console
|
||||
@@ -152,6 +153,12 @@ namespace GlobalInputs {
|
||||
|
||||
// Detecta qué acción global ha sido presionada (si alguna)
|
||||
auto getPressedAction() -> InputAction { // NOLINT(readability-function-cognitive-complexity)
|
||||
// Qualsevol botó del comandament actua com a ACCEPT (saltar escenes
|
||||
// d'attract mode: logo, loading, credits, demo, ending...). Es prioritza
|
||||
// sobre EXIT perquè s'envia com a flag d'event, no com a check d'acció.
|
||||
if (GlobalEvents::consumeGamepadButtonPressed()) {
|
||||
return InputAction::ACCEPT;
|
||||
}
|
||||
if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||
return InputAction::EXIT;
|
||||
}
|
||||
|
||||
@@ -421,7 +421,13 @@ auto Input::addGamepad(int device_index) -> std::string { // NOLINT(readability
|
||||
auto name = gamepad->name;
|
||||
std::cout << "Gamepad connected (" << name << ")" << '\n';
|
||||
gamepads_.push_back(std::move(gamepad));
|
||||
return name + " CONNECTED";
|
||||
|
||||
// Aplica els bindings d'Options al nou gamepad (en hot-plug/wasm el ctor
|
||||
// ja ha cridat applyGamepadBindingsFromOptions però llavors gamepads_
|
||||
// estava buit i no s'ha fet res).
|
||||
applyGamepadBindingsFromOptions();
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
auto Input::removeGamepad(SDL_JoystickID id) -> std::string { // NOLINT(readability-convert-member-functions-to-static)
|
||||
@@ -433,7 +439,7 @@ auto Input::removeGamepad(SDL_JoystickID id) -> std::string { // NOLINT(readabi
|
||||
std::string name = (*it)->name;
|
||||
std::cout << "Gamepad disconnected (" << name << ")" << '\n';
|
||||
gamepads_.erase(it);
|
||||
return name + " DISCONNECTED";
|
||||
return name;
|
||||
}
|
||||
std::cerr << "No se encontró el gamepad con ID " << id << '\n';
|
||||
return {};
|
||||
|
||||
@@ -11,19 +11,19 @@
|
||||
#include <iterator> // Para istreambuf_iterator, operator==
|
||||
#include <string> // Para char_traits, string, operator+, operator==
|
||||
|
||||
#include "core/input/mouse.hpp" // Para updateCursorVisibility
|
||||
#include "core/rendering/render_info.hpp" // Para RenderInfo
|
||||
#include "core/input/mouse.hpp" // Para updateCursorVisibility
|
||||
#include "core/rendering/render_info.hpp" // Para RenderInfo
|
||||
#ifndef __EMSCRIPTEN__
|
||||
#include "core/rendering/sdl3gpu/sdl3gpu_shader.hpp" // Para SDL3GPUShader (no suportat a WebGL2)
|
||||
#endif
|
||||
#include "core/rendering/surface.hpp" // Para Surface, readPalFile
|
||||
#include "core/rendering/text.hpp" // Para Text
|
||||
#include "core/resources/resource_cache.hpp" // Para Resource
|
||||
#include "core/resources/resource_helper.hpp" // Para ResourceHelper
|
||||
#include "core/resources/resource_list.hpp" // Para Asset, AssetType
|
||||
#include "game/options.hpp" // Para Options, options, OptionsVideo, Border
|
||||
#include "game/ui/console.hpp" // Para Console
|
||||
#include "game/ui/notifier.hpp" // Para Notifier
|
||||
#include "core/rendering/surface.hpp" // Para Surface, readPalFile
|
||||
#include "core/rendering/text.hpp" // Para Text
|
||||
#include "core/resources/resource_cache.hpp" // Para Resource
|
||||
#include "core/resources/resource_helper.hpp" // Para ResourceHelper
|
||||
#include "core/resources/resource_list.hpp" // Para Asset, AssetType
|
||||
#include "game/options.hpp" // Para Options, options, OptionsVideo, Border
|
||||
#include "game/ui/console.hpp" // Para Console
|
||||
#include "game/ui/notifier.hpp" // Para Notifier
|
||||
|
||||
// [SINGLETON]
|
||||
Screen* Screen::screen = nullptr;
|
||||
|
||||
@@ -152,7 +152,9 @@ Director::Director() {
|
||||
// i desactivem el borde per aprofitar al màxim l'espai del canvas.
|
||||
Options::video.fullscreen = false;
|
||||
Options::window.zoom = 4;
|
||||
Options::video.border.enabled = false;
|
||||
Options::video.border.enabled = true;
|
||||
Options::video.border.height = 8;
|
||||
Options::video.border.width = 8;
|
||||
#endif
|
||||
|
||||
// Configura la ruta y carga los presets de PostFX
|
||||
@@ -197,9 +199,15 @@ Director::Director() {
|
||||
|
||||
#ifdef _DEBUG
|
||||
Debug::init();
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// A wasm el debug.yaml viu a SYSTEM_FOLDER (MEMFS no persistent) i no està
|
||||
// disponible. Saltem el loadFromFile i entrem directament a la GAME.
|
||||
SceneManager::current = SceneManager::Scene::GAME;
|
||||
#else
|
||||
Debug::get()->setDebugFile(Resource::List::get()->get("debug.yaml"));
|
||||
Debug::get()->loadFromFile();
|
||||
SceneManager::current = Debug::get()->getInitialScene();
|
||||
#endif
|
||||
MapEditor::init();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ class Director {
|
||||
std::string executable_path_; // Path del ejecutable
|
||||
std::string system_folder_; // Carpeta del sistema donde guardar datos
|
||||
|
||||
std::unique_ptr<Scene> active_scene_; // Escena activa
|
||||
SceneManager::Scene current_scene_{SceneManager::Scene::LOGO}; // Tipus d'escena activa
|
||||
std::unique_ptr<Scene> active_scene_; // Escena activa
|
||||
SceneManager::Scene current_scene_{SceneManager::Scene::LOGO}; // Tipus d'escena activa
|
||||
|
||||
// --- Funciones ---
|
||||
void createSystemFolder(const std::string& folder); // Crea la carpeta del sistema donde guardar datos
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
#include "core/system/global_events.hpp"
|
||||
|
||||
#include "core/input/input.hpp" // Para Input (gamepad add/remove)
|
||||
#include "core/input/mouse.hpp"
|
||||
#include "game/options.hpp" // Para Options, options, OptionsGame, OptionsAudio
|
||||
#include "game/ui/console.hpp" // Para Console
|
||||
#include "core/locale/locale.hpp" // Para Locale
|
||||
#include "game/options.hpp" // Para Options, options, OptionsGame, OptionsAudio
|
||||
#include "game/ui/console.hpp" // Para Console
|
||||
#include "game/ui/notifier.hpp" // Para Notifier
|
||||
|
||||
namespace GlobalEvents {
|
||||
|
||||
namespace {
|
||||
// Flag per saber si en aquest frame s'ha rebut un button down del gamepad.
|
||||
// El consumeix GlobalInputs perquè un botó del comandament salti escenes.
|
||||
bool gamepad_button_pressed_ = false;
|
||||
} // namespace
|
||||
|
||||
// Comprueba los eventos que se pueden producir en cualquier sección del juego.
|
||||
// Nota: SDL_EVENT_QUIT el gestiona Director::handleEvent() directament.
|
||||
void handle(const SDL_Event& event) {
|
||||
@@ -12,6 +22,28 @@ namespace GlobalEvents {
|
||||
// reLoadTextures();
|
||||
}
|
||||
|
||||
// Connexió/desconnexió de gamepads: cal enrutar-los a Input perquè
|
||||
// afegisca el dispositiu a gamepads_. Sense això, en wasm els gamepads
|
||||
// mai es detecten (la Gamepad API del navegador només els exposa
|
||||
// després que l'usuari els active, més tard que el discoverGamepads
|
||||
// inicial). En desktop també arregla la connexió en calent.
|
||||
if (event.type == SDL_EVENT_GAMEPAD_ADDED || event.type == SDL_EVENT_GAMEPAD_REMOVED) {
|
||||
if (Input::get() != nullptr) {
|
||||
std::string name = Input::get()->handleEvent(event);
|
||||
if (!name.empty() && Notifier::get() != nullptr && Locale::get() != nullptr) {
|
||||
const std::string KEY = (event.type == SDL_EVENT_GAMEPAD_ADDED)
|
||||
? "ui.gamepad_connected"
|
||||
: "ui.gamepad_disconnected";
|
||||
Notifier::get()->show({name + " " + Locale::get()->get(KEY)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Marcar polsació de qualsevol botó del comandament (els consumirà GlobalInputs).
|
||||
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
|
||||
gamepad_button_pressed_ = true;
|
||||
}
|
||||
|
||||
// Enrutar eventos de texto a la consola cuando está activa
|
||||
if (Console::get() != nullptr && Console::get()->isActive()) {
|
||||
if (event.type == SDL_EVENT_TEXT_INPUT || event.type == SDL_EVENT_KEY_DOWN) {
|
||||
@@ -22,4 +54,10 @@ namespace GlobalEvents {
|
||||
|
||||
Mouse::handleEvent(event);
|
||||
}
|
||||
|
||||
auto consumeGamepadButtonPressed() -> bool {
|
||||
const bool RESULT = gamepad_button_pressed_;
|
||||
gamepad_button_pressed_ = false;
|
||||
return RESULT;
|
||||
}
|
||||
} // namespace GlobalEvents
|
||||
@@ -5,4 +5,9 @@
|
||||
namespace GlobalEvents {
|
||||
// Comprueba los eventos que se pueden producir en cualquier sección del juego
|
||||
void handle(const SDL_Event& event);
|
||||
|
||||
// True si en aquest frame s'ha rebut un SDL_EVENT_GAMEPAD_BUTTON_DOWN.
|
||||
// Es consumeix (i es reseteja) per GlobalInputs::getPressedAction perquè
|
||||
// qualsevol botó del comandament actuï com a "ACCEPT" (saltar escena).
|
||||
auto consumeGamepadButtonPressed() -> bool;
|
||||
} // namespace GlobalEvents
|
||||
Reference in New Issue
Block a user