soport de gamepad per a wasm
This commit is contained in:
19
Makefile
19
Makefile
@@ -302,6 +302,22 @@ wasm:
|
|||||||
cp build/wasm/$(TARGET_NAME).data $(DIST_DIR)/wasm/
|
cp build/wasm/$(TARGET_NAME).data $(DIST_DIR)/wasm/
|
||||||
@echo "Output: $(DIST_DIR)/wasm/"
|
@echo "Output: $(DIST_DIR)/wasm/"
|
||||||
|
|
||||||
|
# Versió Debug del build wasm: arrenca directament a la GAME (sense logo/loading/title)
|
||||||
|
# i activa l'editor i la consola. Sortida a dist/wasm_debug/.
|
||||||
|
wasm_debug:
|
||||||
|
@echo "Compilando WebAssembly Debug - Version: $(VERSION)"
|
||||||
|
docker run --rm \
|
||||||
|
-v $(DIR_ROOT):/src \
|
||||||
|
-w /src \
|
||||||
|
emscripten/emsdk:latest \
|
||||||
|
bash -c "emcmake cmake -S . -B build/wasm_debug -DCMAKE_BUILD_TYPE=Debug && cmake --build build/wasm_debug"
|
||||||
|
$(MKDIR) "$(DIST_DIR)/wasm_debug"
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).html $(DIST_DIR)/wasm_debug/
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).js $(DIST_DIR)/wasm_debug/
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).wasm $(DIST_DIR)/wasm_debug/
|
||||||
|
cp build/wasm_debug/$(TARGET_NAME).data $(DIST_DIR)/wasm_debug/
|
||||||
|
@echo "Output: $(DIST_DIR)/wasm_debug/"
|
||||||
|
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
# REGLAS ESPECIALES
|
# REGLAS ESPECIALES
|
||||||
# ==============================================================================
|
# ==============================================================================
|
||||||
@@ -324,6 +340,7 @@ help:
|
|||||||
@echo " make linux_release - Crear release para Linux"
|
@echo " make linux_release - Crear release para Linux"
|
||||||
@echo " make macos_release - Crear release para macOS"
|
@echo " make macos_release - Crear release para macOS"
|
||||||
@echo " make wasm - Crear release per a WebAssembly (requereix Docker)"
|
@echo " make wasm - Crear release per a WebAssembly (requereix Docker)"
|
||||||
|
@echo " make wasm_debug - Crear build Debug per a WebAssembly (entra directe a la GAME)"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo " Herramientas:"
|
@echo " Herramientas:"
|
||||||
@echo " make compile_shaders - Compilar shaders SPIR-V"
|
@echo " make compile_shaders - Compilar shaders SPIR-V"
|
||||||
@@ -334,4 +351,4 @@ help:
|
|||||||
@echo " make show_version - Mostrar version actual ($(VERSION))"
|
@echo " make show_version - Mostrar version actual ($(VERSION))"
|
||||||
@echo " make help - Mostrar esta ayuda"
|
@echo " make help - Mostrar esta ayuda"
|
||||||
|
|
||||||
.PHONY: all debug release windows_release macos_release linux_release wasm compile_shaders pack_tool resources.pack show_version help
|
.PHONY: all debug release windows_release macos_release linux_release wasm wasm_debug compile_shaders pack_tool resources.pack show_version help
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ title:
|
|||||||
keyboard: "2. REDEFINIR TECLES"
|
keyboard: "2. REDEFINIR TECLES"
|
||||||
joystick: "3. REDEFINIR MANDO"
|
joystick: "3. REDEFINIR MANDO"
|
||||||
projects: "4. PROJECTES"
|
projects: "4. PROJECTES"
|
||||||
|
press_to_play: "PREM PER JUGAR"
|
||||||
keys:
|
keys:
|
||||||
prompt0: "PREM UNA TECLA PER A ESQUERRA"
|
prompt0: "PREM UNA TECLA PER A ESQUERRA"
|
||||||
prompt1: "PREM UNA TECLA PER A DRETA"
|
prompt1: "PREM UNA TECLA PER A DRETA"
|
||||||
@@ -103,6 +104,8 @@ achievements:
|
|||||||
ui:
|
ui:
|
||||||
press_again_menu: "PREM DE NOU PER TORNAR AL MENÚ"
|
press_again_menu: "PREM DE NOU PER TORNAR AL MENÚ"
|
||||||
press_again_exit: "PREM DE NOU PER EIXIR"
|
press_again_exit: "PREM DE NOU PER EIXIR"
|
||||||
|
gamepad_connected: "CONNECTAT"
|
||||||
|
gamepad_disconnected: "DESCONNECTAT"
|
||||||
border_enabled: "VORA ACTIVADA"
|
border_enabled: "VORA ACTIVADA"
|
||||||
border_disabled: "VORA DESACTIVADA"
|
border_disabled: "VORA DESACTIVADA"
|
||||||
fullscreen_enabled: "PANTALLA COMPLETA ACTIVADA"
|
fullscreen_enabled: "PANTALLA COMPLETA ACTIVADA"
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ title:
|
|||||||
keyboard: "2. REDEFINE KEYBOARD"
|
keyboard: "2. REDEFINE KEYBOARD"
|
||||||
joystick: "3. REDEFINE JOYSTICK"
|
joystick: "3. REDEFINE JOYSTICK"
|
||||||
projects: "4. PROJECTS"
|
projects: "4. PROJECTS"
|
||||||
|
press_to_play: "PRESS TO PLAY"
|
||||||
keys:
|
keys:
|
||||||
prompt0: "PRESS KEY FOR LEFT"
|
prompt0: "PRESS KEY FOR LEFT"
|
||||||
prompt1: "PRESS KEY FOR RIGHT"
|
prompt1: "PRESS KEY FOR RIGHT"
|
||||||
@@ -103,6 +104,8 @@ achievements:
|
|||||||
ui:
|
ui:
|
||||||
press_again_menu: "PRESS AGAIN TO RETURN TO MENU"
|
press_again_menu: "PRESS AGAIN TO RETURN TO MENU"
|
||||||
press_again_exit: "PRESS AGAIN TO EXIT"
|
press_again_exit: "PRESS AGAIN TO EXIT"
|
||||||
|
gamepad_connected: "CONNECTED"
|
||||||
|
gamepad_disconnected: "DISCONNECTED"
|
||||||
border_enabled: "BORDER ENABLED"
|
border_enabled: "BORDER ENABLED"
|
||||||
border_disabled: "BORDER DISABLED"
|
border_disabled: "BORDER DISABLED"
|
||||||
fullscreen_enabled: "FULLSCREEN ENABLED"
|
fullscreen_enabled: "FULLSCREEN ENABLED"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "core/locale/locale.hpp" // Para Locale
|
#include "core/locale/locale.hpp" // Para Locale
|
||||||
#include "core/rendering/render_info.hpp" // Para RenderInfo
|
#include "core/rendering/render_info.hpp" // Para RenderInfo
|
||||||
#include "core/rendering/screen.hpp" // Para Screen
|
#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/options.hpp" // Para Options, options, OptionsVideo, Section
|
||||||
#include "game/scene_manager.hpp" // Para SceneManager
|
#include "game/scene_manager.hpp" // Para SceneManager
|
||||||
#include "game/ui/console.hpp" // Para Console
|
#include "game/ui/console.hpp" // Para Console
|
||||||
@@ -152,6 +153,12 @@ namespace GlobalInputs {
|
|||||||
|
|
||||||
// Detecta qué acción global ha sido presionada (si alguna)
|
// Detecta qué acción global ha sido presionada (si alguna)
|
||||||
auto getPressedAction() -> InputAction { // NOLINT(readability-function-cognitive-complexity)
|
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)) {
|
if (Input::get()->checkAction(InputAction::EXIT, Input::DO_NOT_ALLOW_REPEAT)) {
|
||||||
return InputAction::EXIT;
|
return InputAction::EXIT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -421,7 +421,13 @@ auto Input::addGamepad(int device_index) -> std::string { // NOLINT(readability
|
|||||||
auto name = gamepad->name;
|
auto name = gamepad->name;
|
||||||
std::cout << "Gamepad connected (" << name << ")" << '\n';
|
std::cout << "Gamepad connected (" << name << ")" << '\n';
|
||||||
gamepads_.push_back(std::move(gamepad));
|
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)
|
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::string name = (*it)->name;
|
||||||
std::cout << "Gamepad disconnected (" << name << ")" << '\n';
|
std::cout << "Gamepad disconnected (" << name << ")" << '\n';
|
||||||
gamepads_.erase(it);
|
gamepads_.erase(it);
|
||||||
return name + " DISCONNECTED";
|
return name;
|
||||||
}
|
}
|
||||||
std::cerr << "No se encontró el gamepad con ID " << id << '\n';
|
std::cerr << "No se encontró el gamepad con ID " << id << '\n';
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -152,7 +152,9 @@ Director::Director() {
|
|||||||
// i desactivem el borde per aprofitar al màxim l'espai del canvas.
|
// i desactivem el borde per aprofitar al màxim l'espai del canvas.
|
||||||
Options::video.fullscreen = false;
|
Options::video.fullscreen = false;
|
||||||
Options::window.zoom = 4;
|
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
|
#endif
|
||||||
|
|
||||||
// Configura la ruta y carga los presets de PostFX
|
// Configura la ruta y carga los presets de PostFX
|
||||||
@@ -197,9 +199,15 @@ Director::Director() {
|
|||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
Debug::init();
|
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()->setDebugFile(Resource::List::get()->get("debug.yaml"));
|
||||||
Debug::get()->loadFromFile();
|
Debug::get()->loadFromFile();
|
||||||
SceneManager::current = Debug::get()->getInitialScene();
|
SceneManager::current = Debug::get()->getInitialScene();
|
||||||
|
#endif
|
||||||
MapEditor::init();
|
MapEditor::init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
#include "core/system/global_events.hpp"
|
#include "core/system/global_events.hpp"
|
||||||
|
|
||||||
|
#include "core/input/input.hpp" // Para Input (gamepad add/remove)
|
||||||
#include "core/input/mouse.hpp"
|
#include "core/input/mouse.hpp"
|
||||||
|
#include "core/locale/locale.hpp" // Para Locale
|
||||||
#include "game/options.hpp" // Para Options, options, OptionsGame, OptionsAudio
|
#include "game/options.hpp" // Para Options, options, OptionsGame, OptionsAudio
|
||||||
#include "game/ui/console.hpp" // Para Console
|
#include "game/ui/console.hpp" // Para Console
|
||||||
|
#include "game/ui/notifier.hpp" // Para Notifier
|
||||||
|
|
||||||
namespace GlobalEvents {
|
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.
|
// Comprueba los eventos que se pueden producir en cualquier sección del juego.
|
||||||
// Nota: SDL_EVENT_QUIT el gestiona Director::handleEvent() directament.
|
// Nota: SDL_EVENT_QUIT el gestiona Director::handleEvent() directament.
|
||||||
void handle(const SDL_Event& event) {
|
void handle(const SDL_Event& event) {
|
||||||
@@ -12,6 +22,28 @@ namespace GlobalEvents {
|
|||||||
// reLoadTextures();
|
// 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
|
// Enrutar eventos de texto a la consola cuando está activa
|
||||||
if (Console::get() != nullptr && Console::get()->isActive()) {
|
if (Console::get() != nullptr && Console::get()->isActive()) {
|
||||||
if (event.type == SDL_EVENT_TEXT_INPUT || event.type == SDL_EVENT_KEY_DOWN) {
|
if (event.type == SDL_EVENT_TEXT_INPUT || event.type == SDL_EVENT_KEY_DOWN) {
|
||||||
@@ -22,4 +54,10 @@ namespace GlobalEvents {
|
|||||||
|
|
||||||
Mouse::handleEvent(event);
|
Mouse::handleEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto consumeGamepadButtonPressed() -> bool {
|
||||||
|
const bool RESULT = gamepad_button_pressed_;
|
||||||
|
gamepad_button_pressed_ = false;
|
||||||
|
return RESULT;
|
||||||
|
}
|
||||||
} // namespace GlobalEvents
|
} // namespace GlobalEvents
|
||||||
@@ -5,4 +5,9 @@
|
|||||||
namespace GlobalEvents {
|
namespace GlobalEvents {
|
||||||
// Comprueba los eventos que se pueden producir en cualquier sección del juego
|
// Comprueba los eventos que se pueden producir en cualquier sección del juego
|
||||||
void handle(const SDL_Event& event);
|
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
|
} // namespace GlobalEvents
|
||||||
@@ -92,6 +92,15 @@ void Title::handleEvent(const SDL_Event& event) {
|
|||||||
return; // No procesar más este evento
|
return; // No procesar más este evento
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Qualsevol botó del comandament al menú principal inicia partida directament
|
||||||
|
// (els bindings ja estan definits, no cal "pulsar 1" amb el teclat).
|
||||||
|
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN &&
|
||||||
|
state_ == State::MAIN_MENU &&
|
||||||
|
!is_remapping_keyboard_ && !is_remapping_joystick_) {
|
||||||
|
handleMainMenuKeyPress(SDLK_1); // PLAY
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event.type == SDL_EVENT_KEY_DOWN && !Console::get()->isActive()) {
|
if (event.type == SDL_EVENT_KEY_DOWN && !Console::get()->isActive()) {
|
||||||
// Si estamos en modo remap de teclado, capturar tecla
|
// Si estamos en modo remap de teclado, capturar tecla
|
||||||
if (is_remapping_keyboard_ && !remap_completed_) {
|
if (is_remapping_keyboard_ && !remap_completed_) {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
namespace Texts {
|
namespace Texts {
|
||||||
constexpr const char* WINDOW_CAPTION = "© 2022 JailDoctor's Dilemma — JailDesigner";
|
constexpr const char* WINDOW_CAPTION = "© 2022 JailDoctor's Dilemma — JailDesigner";
|
||||||
constexpr const char* COPYRIGHT = "@2022 JailDesigner";
|
constexpr const char* COPYRIGHT = "@2022 JailDesigner";
|
||||||
constexpr const char* VERSION = "1.13"; // Versión por defecto
|
constexpr const char* VERSION = "1.14"; // Versión por defecto
|
||||||
} // namespace Texts
|
} // namespace Texts
|
||||||
|
|
||||||
// Tamaño de bloque
|
// Tamaño de bloque
|
||||||
|
|||||||
Reference in New Issue
Block a user