Недавно я хотел добавить поддержку контроллера геймпада для моего приложения , однако обнаружил, что отображение клавиш Sony Dualshock сильно отличается от того, что указано в документации .Я сделал отображение в зависимости от поставщика, но я понятия не имею, так ли это для всех контроллеров Dualshock ps4 и как я могу быть уверен, что не будет проблем с другими контроллерами.Как вы, люди, справляетесь с этим дерьмом?
class KeyMapping(context: Context) {
private val preferences = Preferences(context)
companion object {
private const val SONY = 1356
}
fun key(event: KeyEvent): Event? {
return if (Dpad.isDpadDevice(event)) {
when (Dpad().getDirectionPressed(event)) {
Dpad.UP -> Event.UP
Dpad.DOWN -> Event.DOWN
Dpad.LEFT -> Event.BACK
Dpad.RIGHT -> Event.FORWARD
else -> getEvent(event, getDefault(event))
}
} else {
null
}
}
private fun getDefault(event: KeyEvent): Event {
val isSony = if (Build.VERSION.SDK_INT >= 19) {
event.device.vendorId == SONY
} else {
false
}
return when (event.keyCode) {
KeyEvent.KEYCODE_BUTTON_A -> if (isSony) Event.SQUARE else Event.X
KeyEvent.KEYCODE_BUTTON_X -> if (isSony) Event.TRIANGLE else Event.SQUARE
KeyEvent.KEYCODE_BUTTON_Y -> if (isSony) Event.EXTRA else Event.TRIANGLE
KeyEvent.KEYCODE_BUTTON_B -> if (isSony) Event.X else Event.CIRCLE
KeyEvent.KEYCODE_BUTTON_R1 -> Event.AMPLIFY
KeyEvent.KEYCODE_BUTTON_R2 -> Event.AMPLIFY
KeyEvent.KEYCODE_BUTTON_L1 -> Event.EXTRA
KeyEvent.KEYCODE_BUTTON_L2 -> Event.EXTRA
KeyEvent.KEYCODE_BUTTON_C -> Event.CIRCLE
KeyEvent.KEYCODE_BUTTON_Z -> Event.AMPLIFY
else -> Event.X
}
}
private fun getEvent(event: KeyEvent, defaultEvent: Event): Event {
return preferences.key(event.keyCode, defaultEvent)
}
}
class Dpad {
private var directionPressed = -1 // initialized to -1
fun getDirectionPressed(event: InputEvent): Int {
if (!isDpadDevice(event)) {
return -1
}
// If the input event is a MotionEvent, check its hat axis values.
(event as? MotionEvent)?.apply {
// Use the hat axis value to find the D-pad direction
val xaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_X)
val yaxis: Float = event.getAxisValue(MotionEvent.AXIS_HAT_Y)
directionPressed = when {
// Check if the AXIS_HAT_X value is -1 or 1, and set the D-pad
// LEFT and RIGHT direction accordingly.
xaxis.compareTo(-1.0f) == 0 -> Dpad.LEFT
xaxis.compareTo(1.0f) == 0 -> Dpad.RIGHT
// Check if the AXIS_HAT_Y value is -1 or 1, and set the D-pad
// UP and DOWN direction accordingly.
yaxis.compareTo(-1.0f) == 0 -> Dpad.UP
yaxis.compareTo(1.0f) == 0 -> Dpad.DOWN
else -> directionPressed
}
}
// If the input event is a KeyEvent, check its key code.
(event as? KeyEvent)?.apply {
// Use the key code to find the D-pad direction.
directionPressed = when (event.keyCode) {
KeyEvent.KEYCODE_DPAD_LEFT -> Dpad.LEFT
KeyEvent.KEYCODE_DPAD_RIGHT -> Dpad.RIGHT
KeyEvent.KEYCODE_DPAD_UP -> Dpad.UP
KeyEvent.KEYCODE_DPAD_DOWN -> Dpad.DOWN
KeyEvent.KEYCODE_DPAD_CENTER -> Dpad.CENTER
else -> directionPressed
}
}
return directionPressed
}
companion object {
internal const val UP = 0
internal const val LEFT = 1
internal const val RIGHT = 2
internal const val DOWN = 3
internal const val CENTER = 4
fun isDpadDevice(event: InputEvent): Boolean =
// Check that input comes from a device with directional pads.
event.source and InputDevice.SOURCE_DPAD != InputDevice.SOURCE_DPAD
}
}