diff --git a/core/input/input.cpp b/core/input/input.cpp index 50e6abaea2c..d85f1a8c2b1 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -599,6 +599,9 @@ void Input::joy_connection_changed(int p_idx, bool p_connected, const String &p_ } } } + // We don't want this setting to be exposed to the user, because it's not very useful outside of this method. + js.info.erase("mapping_handled"); + _set_joypad_mapping(js, mapping); } else { js.connected = false; diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index 436215305b5..8ec159c01a3 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -130,16 +130,14 @@ Returns a dictionary with extra platform-specific information about the device, e.g. the raw gamepad name from the OS or the Steam Input index. - On Windows, the dictionary contains the following fields: - [code]xinput_index[/code]: The index of the controller in the XInput system. Undefined for DirectInput devices. - [code]vendor_id[/code]: The USB vendor ID of the device. - [code]product_id[/code]: The USB product ID of the device. - On Linux: - [code]raw_name[/code]: The name of the controller as it came from the OS, before getting renamed by the godot controller database. + On Windows, Linux, and macOS, the dictionary contains the following fields: + [code]raw_name[/code]: The name of the controller as it came from the OS, before getting renamed by the controller database. [code]vendor_id[/code]: The USB vendor ID of the device. [code]product_id[/code]: The USB product ID of the device. [code]steam_input_index[/code]: The Steam Input gamepad index, if the device is not a Steam Input device this key won't be present. - [b]Note:[/b] The returned dictionary is always empty on Web, iOS, Android, and macOS. + On Windows, the dictionary can have an additional field: + [code]xinput_index[/code]: The index of the controller in the XInput system. This key won't be present for devices not handled by XInput. + [b]Note:[/b] The returned dictionary is always empty on Android, iOS, visionOS, and Web. diff --git a/drivers/sdl/joypad_sdl.cpp b/drivers/sdl/joypad_sdl.cpp index 693b4a21694..53e4366ebf7 100644 --- a/drivers/sdl/joypad_sdl.cpp +++ b/drivers/sdl/joypad_sdl.cpp @@ -128,11 +128,12 @@ void JoypadSDL::process_events() { print_error("A new joypad was attached but couldn't allocate a new id for it because joypad limit was reached."); } else { SDL_Joystick *joy = nullptr; + SDL_Gamepad *gamepad = nullptr; String device_name; // Gamepads must be opened with SDL_OpenGamepad to get their special remapped events if (SDL_IsGamepad(sdl_event.jdevice.which)) { - SDL_Gamepad *gamepad = SDL_OpenGamepad(sdl_event.jdevice.which); + gamepad = SDL_OpenGamepad(sdl_event.jdevice.which); ERR_CONTINUE_MSG(!gamepad, vformat("Error opening gamepad at index %d: %s", sdl_event.jdevice.which, SDL_GetError())); @@ -164,9 +165,22 @@ void JoypadSDL::process_events() { sdl_instance_id_to_joypad_id.insert(sdl_event.jdevice.which, joy_id); - // Skip Godot's mapping system because SDL already handles the joypad's mapping Dictionary joypad_info; - joypad_info["mapping_handled"] = true; + joypad_info["mapping_handled"] = true; // Skip Godot's mapping system because SDL already handles the joypad's mapping. + joypad_info["raw_name"] = String(SDL_GetJoystickName(joy)); + joypad_info["vendor_id"] = itos(SDL_GetJoystickVendor(joy)); + joypad_info["product_id"] = itos(SDL_GetJoystickProduct(joy)); + + const uint64_t steam_handle = SDL_GetGamepadSteamHandle(gamepad); + if (steam_handle != 0) { + joypad_info["steam_input_index"] = itos(steam_handle); + } + + const int player_index = SDL_GetJoystickPlayerIndex(joy); + if (player_index >= 0) { + // For XInput controllers SDL_GetJoystickPlayerIndex returns the XInput user index. + joypad_info["xinput_index"] = itos(player_index); + } Input::get_singleton()->joy_connection_changed( joy_id,