Răsfoiți Sursa

Fix Input.get_joy_info() regression

SDL input driver did not have the "xinput_index", "raw_name", "vendor_id" and "product_id" fields for this method and exposed an additional, essentially useless for the users "mapping_handled" field. This commit fixes these issues.
Nintorch 2 săptămâni în urmă
părinte
comite
f28acf97d0
3 a modificat fișierele cu 25 adăugiri și 10 ștergeri
  1. 3 0
      core/input/input.cpp
  2. 5 7
      doc/classes/Input.xml
  3. 17 3
      drivers/sdl/joypad_sdl.cpp

+ 3 - 0
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;

+ 5 - 7
doc/classes/Input.xml

@@ -130,16 +130,14 @@
 			<param index="0" name="device" type="int" />
 			<description>
 				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.
 			</description>
 		</method>
 		<method name="get_joy_name">

+ 17 - 3
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,