diff --git a/source/core/input/input.cpp b/source/core/input/input.cpp index 1f2a006..b62982c 100644 --- a/source/core/input/input.cpp +++ b/source/core/input/input.cpp @@ -10,6 +10,40 @@ #include "game/options.hpp" // Para Options::controls +// Emscripten-only: SDL 3.4+ ja no casa el GUID dels mandos de Chrome Android +// amb gamecontrollerdb (el gamepad.id d'Android no porta Vendor/Product, el +// parser extreu valors escombraries, el GUID resultant no està a la db i el +// gamepad queda obert amb un mapping incorrecte). Com el W3C Gamepad API +// garanteix el layout estàndard quan el navegador reporta mapping=="standard", +// injectem un mapping SDL amb eixe layout per al GUID del joystick abans +// d'obrir-lo com gamepad. Fora d'Emscripten és un no-op. +static void installWebStandardMapping(SDL_JoystickID jid) { +#ifdef __EMSCRIPTEN__ + SDL_GUID guid = SDL_GetJoystickGUIDForID(jid); + char guidStr[33]; + SDL_GUIDToString(guid, guidStr, sizeof(guidStr)); + const char* name = SDL_GetJoystickNameForID(jid); + if (!name || !*name) name = "Standard Gamepad"; + + char mapping[512]; + SDL_snprintf(mapping, sizeof(mapping), + "%s,%s," + "a:b0,b:b1,x:b2,y:b3," + "leftshoulder:b4,rightshoulder:b5," + "lefttrigger:b6,righttrigger:b7," + "back:b8,start:b9," + "leftstick:b10,rightstick:b11," + "dpup:b12,dpdown:b13,dpleft:b14,dpright:b15," + "guide:b16," + "leftx:a0,lefty:a1,rightx:a2,righty:a3," + "platform:Emscripten", + guidStr, name); + SDL_AddGamepadMapping(mapping); +#else + (void)jid; +#endif +} + // Singleton Input* Input::instance = nullptr; @@ -420,6 +454,7 @@ auto Input::handleEvent(const SDL_Event& event) -> std::string { // NOLINT(read } auto Input::addGamepad(int device_index) -> std::string { // NOLINT(readability-convert-member-functions-to-static) + installWebStandardMapping(device_index); SDL_Gamepad* pad = SDL_OpenGamepad(device_index); if (pad == nullptr) { std::cerr << "Error al abrir el gamepad: " << SDL_GetError() << '\n';