Explorar o código

android: Reorder controller indexes and only use controllers

Before we could ignore controller inputs by forwarding them to player two if a non-controller was connected before and recognized as an input device.
Charles Lombardo %!s(int64=2) %!d(string=hai) anos
pai
achega
f7755df2af

+ 3 - 0
src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt

@@ -64,6 +64,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
     private var motionTimestamp: Long = 0
     private var flipMotionOrientation: Boolean = false
 
+    private var controllerIds = InputHandler.getGameControllerIds()
+
     private val actionPause = "ACTION_EMULATOR_PAUSE"
     private val actionPlay = "ACTION_EMULATOR_PLAY"
     private val actionMute = "ACTION_EMULATOR_MUTE"
@@ -155,6 +157,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
         super.onResume()
         nfcReader.startScanning()
         startMotionSensorListener()
+        InputHandler.updateControllerIds()
 
         buildPictureInPictureParams()
     }

+ 47 - 6
src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InputHandler.kt

@@ -3,17 +3,24 @@
 
 package org.yuzu.yuzu_emu.utils
 
+import android.view.InputDevice
 import android.view.KeyEvent
 import android.view.MotionEvent
 import kotlin.math.sqrt
 import org.yuzu.yuzu_emu.NativeLibrary
 
 object InputHandler {
+    private var controllerIds = getGameControllerIds()
+
     fun initialize() {
         // Connect first controller
         NativeLibrary.onGamePadConnectEvent(getPlayerNumber(NativeLibrary.Player1Device))
     }
 
+    fun updateControllerIds() {
+        controllerIds = getGameControllerIds()
+    }
+
     fun dispatchKeyEvent(event: KeyEvent): Boolean {
         val button: Int = when (event.device.vendorId) {
             0x045E -> getInputXboxButtonKey(event.keyCode)
@@ -35,7 +42,7 @@ object InputHandler {
         }
 
         return NativeLibrary.onGamePadButtonEvent(
-            getPlayerNumber(event.device.controllerNumber),
+            getPlayerNumber(event.device.controllerNumber, event.deviceId),
             button,
             action
         )
@@ -58,9 +65,14 @@ object InputHandler {
         return true
     }
 
-    private fun getPlayerNumber(index: Int): Int {
+    private fun getPlayerNumber(index: Int, deviceId: Int = -1): Int {
+        var deviceIndex = index
+        if (deviceId != -1) {
+            deviceIndex = controllerIds[deviceId]!!
+        }
+
         // TODO: Joycons are handled as different controllers. Find a way to merge them.
-        return when (index) {
+        return when (deviceIndex) {
             2 -> NativeLibrary.Player2Device
             3 -> NativeLibrary.Player3Device
             4 -> NativeLibrary.Player4Device
@@ -238,7 +250,7 @@ object InputHandler {
     }
 
     private fun setGenericAxisInput(event: MotionEvent, axis: Int) {
-        val playerNumber = getPlayerNumber(event.device.controllerNumber)
+        val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
 
         when (axis) {
             MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
@@ -297,7 +309,7 @@ object InputHandler {
 
     private fun setJoyconAxisInput(event: MotionEvent, axis: Int) {
         // Joycon support is half dead. Right joystick doesn't work
-        val playerNumber = getPlayerNumber(event.device.controllerNumber)
+        val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
 
         when (axis) {
             MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
@@ -325,7 +337,7 @@ object InputHandler {
     }
 
     private fun setRazerAxisInput(event: MotionEvent, axis: Int) {
-        val playerNumber = getPlayerNumber(event.device.controllerNumber)
+        val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId)
 
         when (axis) {
             MotionEvent.AXIS_X, MotionEvent.AXIS_Y ->
@@ -362,4 +374,33 @@ object InputHandler {
                 )
         }
     }
+
+    fun getGameControllerIds(): Map<Int, Int> {
+        val gameControllerDeviceIds = mutableMapOf<Int, Int>()
+        val deviceIds = InputDevice.getDeviceIds()
+        var controllerSlot = 1
+        deviceIds.forEach { deviceId ->
+            InputDevice.getDevice(deviceId)?.apply {
+                // Don't over-assign controllers
+                if (controllerSlot >= 8) {
+                    return gameControllerDeviceIds
+                }
+
+                // Verify that the device has gamepad buttons, control sticks, or both.
+                if (sources and InputDevice.SOURCE_GAMEPAD == InputDevice.SOURCE_GAMEPAD ||
+                    sources and InputDevice.SOURCE_JOYSTICK == InputDevice.SOURCE_JOYSTICK
+                ) {
+                    // This device is a game controller. Store its device ID.
+                    if (deviceId and id and vendorId and productId != 0) {
+                        // Additionally filter out devices that have no ID
+                        gameControllerDeviceIds
+                            .takeIf { !it.contains(deviceId) }
+                            ?.put(deviceId, controllerSlot)
+                        controllerSlot++
+                    }
+                }
+            }
+        }
+        return gameControllerDeviceIds
+    }
 }