diff --git a/app/src/main/java/emu/skyline/input/HostEvent.kt b/app/src/main/java/emu/skyline/input/HostEvent.kt index 66287519..54a2b552 100644 --- a/app/src/main/java/emu/skyline/input/HostEvent.kt +++ b/app/src/main/java/emu/skyline/input/HostEvent.kt @@ -44,6 +44,8 @@ data class MotionHostEvent(override val descriptor : String = "", val axis : Int MotionEvent.AXIS_Y, MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, + MotionEvent.AXIS_HAT_X, + MotionEvent.AXIS_HAT_Y, MotionEvent.AXIS_LTRIGGER, MotionEvent.AXIS_RTRIGGER, MotionEvent.AXIS_THROTTLE, diff --git a/app/src/main/java/emu/skyline/input/InputHandler.kt b/app/src/main/java/emu/skyline/input/InputHandler.kt index a9e050f1..a25462ea 100644 --- a/app/src/main/java/emu/skyline/input/InputHandler.kt +++ b/app/src/main/java/emu/skyline/input/InputHandler.kt @@ -5,7 +5,6 @@ package emu.skyline.input -import android.graphics.PointF import android.view.InputDevice import android.view.KeyEvent import android.view.MotionEvent @@ -120,58 +119,47 @@ class InputHandler(private val inputManager : InputManager, private val preferen */ private val axesHistory = arrayOfNulls(MotionHostEvent.axes.size) - /** - * The last value of the HAT axes so it can be ignored in [onGenericMotionEvent] so they are handled by [dispatchKeyEvent] instead - */ - private var oldHat = PointF() - /** * Handles translating any [MotionHostEvent]s to a [GuestEvent] that is passed into libskyline */ fun handleMotionEvent(event : MotionEvent) : Boolean { if ((event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK) || event.isFromSource(InputDevice.SOURCE_CLASS_BUTTON)) && event.action == MotionEvent.ACTION_MOVE) { - val hat = PointF(event.getAxisValue(MotionEvent.AXIS_HAT_X), event.getAxisValue(MotionEvent.AXIS_HAT_Y)) + for (axisItem in MotionHostEvent.axes.withIndex()) { + val axis = axisItem.value + var value = event.getAxisValue(axis) - if (hat == oldHat) { - for (axisItem in MotionHostEvent.axes.withIndex()) { - val axis = axisItem.value - var value = event.getAxisValue(axis) + if ((event.historySize != 0 && value != event.getHistoricalAxisValue(axis, 0)) || (axesHistory[axisItem.index]?.let { it == value } == false)) { + var polarity = value > 0 || (value == 0f && axesHistory[axisItem.index]?.let { it >= 0 } == true) - if ((event.historySize != 0 && value != event.getHistoricalAxisValue(axis, 0)) || (axesHistory[axisItem.index]?.let { it == value } == false)) { - var polarity = value > 0 || (value == 0f && axesHistory[axisItem.index]?.let { it >= 0 } == true) - - val guestEvent = MotionHostEvent(event.device.descriptor, axis, polarity).let { hostEvent -> - inputManager.eventMap[hostEvent] ?: if (value == 0f) { - polarity = false - inputManager.eventMap[hostEvent.copy(polarity = false)] - } else { - null - } - } - - when (guestEvent) { - is ButtonGuestEvent -> { - if (guestEvent.button != ButtonId.Menu) - setButtonState(guestEvent.id, guestEvent.button.value(), if (abs(value) >= guestEvent.threshold) ButtonState.Pressed.state else ButtonState.Released.state) - } - - is AxisGuestEvent -> { - value = guestEvent.value(value) - value = if (polarity) abs(value) else -abs(value) - value = if (guestEvent.axis == AxisId.LX || guestEvent.axis == AxisId.RX) value else -value - - setAxisValue(guestEvent.id, guestEvent.axis.ordinal, (value * Short.MAX_VALUE).toInt()) - } + val guestEvent = MotionHostEvent(event.device.descriptor, axis, polarity).let { hostEvent -> + inputManager.eventMap[hostEvent] ?: if (value == 0f) { + polarity = false + inputManager.eventMap[hostEvent.copy(polarity = false)] + } else { + null } } - axesHistory[axisItem.index] = value + when (guestEvent) { + is ButtonGuestEvent -> { + val action = if (abs(value) >= guestEvent.threshold) ButtonState.Pressed.state else ButtonState.Released.state + if (guestEvent.button != ButtonId.Menu) + setButtonState(guestEvent.id, guestEvent.button.value(), action) + } + + is AxisGuestEvent -> { + value = guestEvent.value(value) + value = if (polarity) abs(value) else -abs(value) + value = if (guestEvent.axis == AxisId.LX || guestEvent.axis == AxisId.RX) value else -value + setAxisValue(guestEvent.id, guestEvent.axis.ordinal, (value * Short.MAX_VALUE).toInt()) + } + } } - return true - } else { - oldHat = hat + axesHistory[axisItem.index] = value } + + return true } return false diff --git a/app/src/main/java/emu/skyline/input/dialog/ButtonDialog.kt b/app/src/main/java/emu/skyline/input/dialog/ButtonDialog.kt index 1b2bea87..bd5ca4d4 100644 --- a/app/src/main/java/emu/skyline/input/dialog/ButtonDialog.kt +++ b/app/src/main/java/emu/skyline/input/dialog/ButtonDialog.kt @@ -101,10 +101,6 @@ class ButtonDialog @JvmOverloads constructor(private val item : ControllerButton var axisRunnable : Runnable? = null // The Runnable that is used for counting down till an axis is selected val axisHandler = Handler(Looper.getMainLooper()) // The handler responsible for handling posting [axisRunnable] - // The last values of the HAT axes so that they can be ignored in [View.OnGenericMotionListener] so they are passed onto [DialogInterface.OnKeyListener] as [KeyEvent]s - var oldDpadX = 0.0f - var oldDpadY = 0.0f - dialog?.setOnKeyListener { _, _, event -> // We want all input events from Joysticks and Buttons except for [KeyEvent.KEYCODE_BACK] as that will should be processed elsewhere if (((event.isFromSource(InputDevice.SOURCE_CLASS_BUTTON) && event.keyCode != KeyEvent.KEYCODE_BACK) || event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK)) && event.repeatCount == 0) { @@ -155,23 +151,18 @@ class ButtonDialog @JvmOverloads constructor(private val item : ControllerButton } } - val axes = arrayOf(MotionEvent.AXIS_X, MotionEvent.AXIS_Y, MotionEvent.AXIS_Z, MotionEvent.AXIS_RZ, MotionEvent.AXIS_HAT_X, MotionEvent.AXIS_HAT_Y, MotionEvent.AXIS_LTRIGGER, MotionEvent.AXIS_RTRIGGER, MotionEvent.AXIS_THROTTLE, MotionEvent.AXIS_RUDDER, MotionEvent.AXIS_WHEEL, MotionEvent.AXIS_GAS, MotionEvent.AXIS_BRAKE).plus(IntRange(MotionEvent.AXIS_GENERIC_1, MotionEvent.AXIS_GENERIC_16).toList()) - + val axes = MotionHostEvent.axes val axesHistory = arrayOfNulls(axes.size) // The last recorded value of an axis, this is used to eliminate any stagnant axes view.setOnGenericMotionListener { _, event -> - // We retrieve the value of the HAT axes so that we can check for change and ignore any input from them so it'll be passed onto the [KeyEvent] handler - val dpadX = event.getAxisValue(MotionEvent.AXIS_HAT_X) - val dpadY = event.getAxisValue(MotionEvent.AXIS_HAT_Y) - // We want all input events from Joysticks and Buttons that are [MotionEvent.ACTION_MOVE] and not from the D-pad - if ((event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK) || event.isFromSource(InputDevice.SOURCE_CLASS_BUTTON)) && event.action == MotionEvent.ACTION_MOVE && dpadX == oldDpadX && dpadY == oldDpadY) { + if ((event.isFromSource(InputDevice.SOURCE_CLASS_JOYSTICK) || event.isFromSource(InputDevice.SOURCE_CLASS_BUTTON)) && event.action == MotionEvent.ACTION_MOVE) { // We iterate over every axis to check if any of them pass the selection threshold and if they do then select them by setting [deviceId], [inputId] and [axisPolarity] for (axisItem in axes.withIndex()) { val axis = axisItem.value val value = event.getAxisValue(axis) - // This checks the history of the axis so it we can ignore any stagnant axis + // This checks the history of the axis so we can ignore any stagnant axis if ((event.historySize == 0 || value == event.getHistoricalAxisValue(axis, 0)) && (axesHistory[axisItem.index]?.let { it == value } != false)) { axesHistory[axisItem.index] = value continue @@ -246,9 +237,6 @@ class ButtonDialog @JvmOverloads constructor(private val item : ControllerButton true } else { - oldDpadX = dpadX - oldDpadY = dpadY - false } }