|
|
@ -3,17 +3,24 @@ |
|
|
|
|
|
|
|
|
package org.yuzu.yuzu_emu.utils |
|
|
package org.yuzu.yuzu_emu.utils |
|
|
|
|
|
|
|
|
|
|
|
import android.view.InputDevice |
|
|
import android.view.KeyEvent |
|
|
import android.view.KeyEvent |
|
|
import android.view.MotionEvent |
|
|
import android.view.MotionEvent |
|
|
import kotlin.math.sqrt |
|
|
import kotlin.math.sqrt |
|
|
import org.yuzu.yuzu_emu.NativeLibrary |
|
|
import org.yuzu.yuzu_emu.NativeLibrary |
|
|
|
|
|
|
|
|
object InputHandler { |
|
|
object InputHandler { |
|
|
|
|
|
private var controllerIds = getGameControllerIds() |
|
|
|
|
|
|
|
|
fun initialize() { |
|
|
fun initialize() { |
|
|
// Connect first controller |
|
|
// Connect first controller |
|
|
NativeLibrary.onGamePadConnectEvent(getPlayerNumber(NativeLibrary.Player1Device)) |
|
|
NativeLibrary.onGamePadConnectEvent(getPlayerNumber(NativeLibrary.Player1Device)) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun updateControllerIds() { |
|
|
|
|
|
controllerIds = getGameControllerIds() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
fun dispatchKeyEvent(event: KeyEvent): Boolean { |
|
|
fun dispatchKeyEvent(event: KeyEvent): Boolean { |
|
|
val button: Int = when (event.device.vendorId) { |
|
|
val button: Int = when (event.device.vendorId) { |
|
|
0x045E -> getInputXboxButtonKey(event.keyCode) |
|
|
0x045E -> getInputXboxButtonKey(event.keyCode) |
|
|
@ -35,7 +42,7 @@ object InputHandler { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return NativeLibrary.onGamePadButtonEvent( |
|
|
return NativeLibrary.onGamePadButtonEvent( |
|
|
getPlayerNumber(event.device.controllerNumber), |
|
|
|
|
|
|
|
|
getPlayerNumber(event.device.controllerNumber, event.deviceId), |
|
|
button, |
|
|
button, |
|
|
action |
|
|
action |
|
|
) |
|
|
) |
|
|
@ -58,9 +65,14 @@ object InputHandler { |
|
|
return true |
|
|
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. |
|
|
// TODO: Joycons are handled as different controllers. Find a way to merge them. |
|
|
return when (index) { |
|
|
|
|
|
|
|
|
return when (deviceIndex) { |
|
|
2 -> NativeLibrary.Player2Device |
|
|
2 -> NativeLibrary.Player2Device |
|
|
3 -> NativeLibrary.Player3Device |
|
|
3 -> NativeLibrary.Player3Device |
|
|
4 -> NativeLibrary.Player4Device |
|
|
4 -> NativeLibrary.Player4Device |
|
|
@ -238,7 +250,7 @@ object InputHandler { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private fun setGenericAxisInput(event: MotionEvent, axis: Int) { |
|
|
private fun setGenericAxisInput(event: MotionEvent, axis: Int) { |
|
|
val playerNumber = getPlayerNumber(event.device.controllerNumber) |
|
|
|
|
|
|
|
|
val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId) |
|
|
|
|
|
|
|
|
when (axis) { |
|
|
when (axis) { |
|
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> |
|
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> |
|
|
@ -297,7 +309,7 @@ object InputHandler { |
|
|
|
|
|
|
|
|
private fun setJoyconAxisInput(event: MotionEvent, axis: Int) { |
|
|
private fun setJoyconAxisInput(event: MotionEvent, axis: Int) { |
|
|
// Joycon support is half dead. Right joystick doesn't work |
|
|
// 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) { |
|
|
when (axis) { |
|
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> |
|
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> |
|
|
@ -325,7 +337,7 @@ object InputHandler { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private fun setRazerAxisInput(event: MotionEvent, axis: Int) { |
|
|
private fun setRazerAxisInput(event: MotionEvent, axis: Int) { |
|
|
val playerNumber = getPlayerNumber(event.device.controllerNumber) |
|
|
|
|
|
|
|
|
val playerNumber = getPlayerNumber(event.device.controllerNumber, event.deviceId) |
|
|
|
|
|
|
|
|
when (axis) { |
|
|
when (axis) { |
|
|
MotionEvent.AXIS_X, MotionEvent.AXIS_Y -> |
|
|
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 |
|
|
|
|
|
} |
|
|
} |
|
|
} |