mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-26 12:05:30 +03:00
Add separate L3 and R3 buttons to OSC
As part of this commit, a `defaultEnabled` property was added to `OnScreenButton` to determine the default visibility of buttons. This is required because L3 and R3 should be hidden by default and only enabled by the user on demand. Additionally, the buttons' mask values were added to `ButtonId` members, as adding entries in the middle of the class conflicted with the `ordinal` enum property, making it unfit to use for our purposes. Finally, the `ControllerType` class was extended with an array of optional buttons. Optional buttons represent buttons that are allowed to be displayed on screen, but shouldn't be included in the controller mapping activity.
This commit is contained in:
parent
acdf4e6823
commit
a799cb63f1
@ -557,7 +557,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
return inputHandler.handleTouchEvent(view, event)
|
||||
}
|
||||
|
||||
private fun onButtonStateChanged(buttonId : ButtonId, state : ButtonState) = InputHandler.setButtonState(0, buttonId.value(), state.state)
|
||||
private fun onButtonStateChanged(buttonId : ButtonId, state : ButtonState) = InputHandler.setButtonState(0, buttonId.value, state.state)
|
||||
|
||||
private fun onStickStateChanged(stickId : StickId, position : PointF) {
|
||||
InputHandler.setAxisValue(0, stickId.xAxis.ordinal, (position.x * Short.MAX_VALUE).toInt())
|
||||
|
@ -13,13 +13,56 @@ import java.io.Serializable
|
||||
*
|
||||
* @param stringRes The string resource of the controller's name
|
||||
* @param firstController If the type only applies to the first controller
|
||||
* @param optionalButtons Optional buttons that are allowed to be displayed on screen, but shouldn't be included in the controller mapping activity
|
||||
*/
|
||||
enum class ControllerType(val stringRes : Int, val firstController : Boolean, val sticks : Array<StickId> = arrayOf(), val buttons : Array<ButtonId> = arrayOf(), val id : Int) {
|
||||
enum class ControllerType(val stringRes : Int, val firstController : Boolean, val sticks : Array<StickId> = arrayOf(), val buttons : Array<ButtonId> = arrayOf(), val optionalButtons : Array<ButtonId> = arrayOf(), val id : Int) {
|
||||
None(R.string.none, false, id = 0b0),
|
||||
ProController(R.string.procon, false, arrayOf(StickId.Left, StickId.Right), arrayOf(ButtonId.A, ButtonId.B, ButtonId.X, ButtonId.Y, ButtonId.DpadUp, ButtonId.DpadDown, ButtonId.DpadLeft, ButtonId.DpadRight, ButtonId.L, ButtonId.R, ButtonId.ZL, ButtonId.ZR, ButtonId.Plus, ButtonId.Minus), 0b1),
|
||||
HandheldProController(R.string.handheld_procon, true, arrayOf(StickId.Left, StickId.Right), arrayOf(ButtonId.A, ButtonId.B, ButtonId.X, ButtonId.Y, ButtonId.DpadUp, ButtonId.DpadDown, ButtonId.DpadLeft, ButtonId.DpadRight, ButtonId.L, ButtonId.R, ButtonId.ZL, ButtonId.ZR, ButtonId.Plus, ButtonId.Minus), 0b10),
|
||||
JoyConLeft(R.string.ljoycon, false, arrayOf(StickId.Left), arrayOf(ButtonId.DpadUp, ButtonId.DpadDown, ButtonId.DpadLeft, ButtonId.DpadRight, ButtonId.L, ButtonId.ZL, ButtonId.Minus, ButtonId.LeftSL, ButtonId.LeftSR), 0b1000),
|
||||
JoyConRight(R.string.rjoycon, false, arrayOf(StickId.Right), arrayOf(ButtonId.A, ButtonId.B, ButtonId.X, ButtonId.Y, ButtonId.R, ButtonId.ZR, ButtonId.Plus, ButtonId.RightSL, ButtonId.RightSR), 0b10000),
|
||||
ProController(
|
||||
R.string.procon,
|
||||
false,
|
||||
arrayOf(StickId.Left, StickId.Right),
|
||||
arrayOf(
|
||||
ButtonId.A, ButtonId.B, ButtonId.X, ButtonId.Y,
|
||||
ButtonId.DpadUp, ButtonId.DpadDown, ButtonId.DpadLeft, ButtonId.DpadRight,
|
||||
ButtonId.L, ButtonId.R, ButtonId.ZL, ButtonId.ZR, ButtonId.Plus, ButtonId.Minus
|
||||
),
|
||||
arrayOf(ButtonId.L3, ButtonId.R3),
|
||||
0b1
|
||||
),
|
||||
HandheldProController(
|
||||
R.string.handheld_procon,
|
||||
true,
|
||||
arrayOf(StickId.Left, StickId.Right),
|
||||
arrayOf(
|
||||
ButtonId.A, ButtonId.B, ButtonId.X, ButtonId.Y,
|
||||
ButtonId.DpadUp, ButtonId.DpadDown, ButtonId.DpadLeft, ButtonId.DpadRight,
|
||||
ButtonId.L, ButtonId.R, ButtonId.ZL, ButtonId.ZR, ButtonId.Plus, ButtonId.Minus
|
||||
),
|
||||
arrayOf(ButtonId.L3, ButtonId.R3),
|
||||
0b10
|
||||
),
|
||||
JoyConLeft(
|
||||
R.string.ljoycon,
|
||||
false,
|
||||
arrayOf(StickId.Left),
|
||||
arrayOf(
|
||||
ButtonId.DpadUp, ButtonId.DpadDown, ButtonId.DpadLeft, ButtonId.DpadRight,
|
||||
ButtonId.L, ButtonId.ZL, ButtonId.Minus, ButtonId.LeftSL, ButtonId.LeftSR
|
||||
),
|
||||
arrayOf(ButtonId.L3),
|
||||
0b1000
|
||||
),
|
||||
JoyConRight(
|
||||
R.string.rjoycon,
|
||||
false,
|
||||
arrayOf(StickId.Right),
|
||||
arrayOf(
|
||||
ButtonId.A, ButtonId.B, ButtonId.X, ButtonId.Y,
|
||||
ButtonId.R, ButtonId.ZR, ButtonId.Plus, ButtonId.RightSL, ButtonId.RightSR
|
||||
),
|
||||
arrayOf(ButtonId.R3),
|
||||
0b10000
|
||||
),
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -7,49 +7,44 @@ package emu.skyline.input
|
||||
|
||||
import emu.skyline.R.string
|
||||
import java.io.Serializable
|
||||
import java.util.*
|
||||
import java.util.Objects
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* This enumerates all of the buttons that the emulator recognizes
|
||||
*/
|
||||
enum class ButtonId(val short : String? = null, val long : Int? = null) {
|
||||
A("A", string.a_button),
|
||||
B("B", string.b_button),
|
||||
X("X", string.x_button),
|
||||
Y("Y", string.y_button),
|
||||
LeftStick("L", string.left_stick),
|
||||
RightStick("R", string.right_stick),
|
||||
L("L", string.left_shoulder),
|
||||
R("R", string.right_shoulder),
|
||||
ZL("ZL", string.left_trigger),
|
||||
ZR("ZR", string.right_trigger),
|
||||
Plus("+", string.plus_button),
|
||||
Minus("-", string.minus_button),
|
||||
DpadLeft("◀︎", string.left),
|
||||
DpadUp("▲︎", string.up),
|
||||
DpadRight("▶︎", string.right),
|
||||
DpadDown("▼︎", string.down),
|
||||
LeftStickLeft,
|
||||
LeftStickUp,
|
||||
LeftStickRight,
|
||||
LeftStickDown,
|
||||
RightStickLeft,
|
||||
RightStickUp,
|
||||
RightStickRight,
|
||||
RightStickDown,
|
||||
LeftSL("SL", string.left_shoulder),
|
||||
LeftSR("SR", string.right_shoulder),
|
||||
RightSL("SL", string.left_shoulder),
|
||||
RightSR("SR", string.right_shoulder),
|
||||
Menu("⌂︎", string.emu_menu_button);
|
||||
|
||||
/**
|
||||
* This returns the value as setting the [ordinal]-th bit in a [Long]
|
||||
*/
|
||||
fun value() : Long {
|
||||
return (1.toLong()) shl ordinal
|
||||
}
|
||||
enum class ButtonId(val value : Long, val short : String? = null, val long : Int? = null) {
|
||||
A(1 shl 0, "A", string.a_button),
|
||||
B(1 shl 1, "B", string.b_button),
|
||||
X(1 shl 2, "X", string.x_button),
|
||||
Y(1 shl 3, "Y", string.y_button),
|
||||
LeftStick(1 shl 4, "L", string.left_stick),
|
||||
RightStick(1 shl 5, "R", string.right_stick),
|
||||
L3(1 shl 4, "L3", string.left_stick_button),
|
||||
R3(1 shl 5, "R3", string.right_stick_button),
|
||||
L(1 shl 6, "L", string.left_shoulder),
|
||||
R(1 shl 7, "R", string.right_shoulder),
|
||||
ZL(1 shl 8, "ZL", string.left_trigger),
|
||||
ZR(1 shl 9, "ZR", string.right_trigger),
|
||||
Plus(1 shl 10, "+", string.plus_button),
|
||||
Minus(1 shl 11, "-", string.minus_button),
|
||||
DpadLeft(1 shl 12, "◀︎", string.left),
|
||||
DpadUp(1 shl 13, "▲︎", string.up),
|
||||
DpadRight(1 shl 14, "▶︎", string.right),
|
||||
DpadDown(1 shl 15, "▼︎", string.down),
|
||||
LeftStickLeft(1 shl 16),
|
||||
LeftStickUp(1 shl 17),
|
||||
LeftStickRight(1 shl 18),
|
||||
LeftStickDown(1 shl 19),
|
||||
RightStickLeft(1 shl 20),
|
||||
RightStickUp(1 shl 21),
|
||||
RightStickRight(1 shl 22),
|
||||
RightStickDown(1 shl 23),
|
||||
LeftSL(1 shl 24, "SL", string.left_shoulder),
|
||||
LeftSR(1 shl 25, "SR", string.right_shoulder),
|
||||
RightSL(1 shl 26, "SL", string.left_shoulder),
|
||||
RightSR(1 shl 27, "SR", string.right_shoulder),
|
||||
Menu(1 shl 28, "⌂︎", string.emu_menu_button);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,7 +221,7 @@ class InputHandler(private val inputManager : InputManager, private val emulatio
|
||||
return when (val guestEvent = inputManager.eventMap[KeyHostEvent(event.device.descriptor, event.keyCode)]) {
|
||||
is ButtonGuestEvent -> {
|
||||
if (guestEvent.button != ButtonId.Menu)
|
||||
setButtonState(guestEvent.id, guestEvent.button.value(), action.state)
|
||||
setButtonState(guestEvent.id, guestEvent.button.value, action.state)
|
||||
true
|
||||
}
|
||||
|
||||
@ -274,7 +274,7 @@ class InputHandler(private val inputManager : InputManager, private val emulatio
|
||||
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)
|
||||
setButtonState(guestEvent.id, guestEvent.button.value, action)
|
||||
}
|
||||
|
||||
is AxisGuestEvent -> {
|
||||
|
@ -27,7 +27,8 @@ abstract class OnScreenButton(
|
||||
private val defaultRelativeY : Float,
|
||||
private val defaultRelativeWidth : Float,
|
||||
private val defaultRelativeHeight : Float,
|
||||
drawableId : Int
|
||||
drawableId : Int,
|
||||
private val defaultEnabled : Boolean
|
||||
) {
|
||||
companion object {
|
||||
/**
|
||||
@ -36,7 +37,7 @@ abstract class OnScreenButton(
|
||||
const val CONFIGURED_ASPECT_RATIO = 2074f / 874f
|
||||
}
|
||||
|
||||
val config = OnScreenConfiguration(onScreenControllerView.context, buttonId, defaultRelativeX, defaultRelativeY)
|
||||
val config = OnScreenConfiguration(onScreenControllerView.context, buttonId, defaultRelativeX, defaultRelativeY, defaultEnabled)
|
||||
|
||||
protected val drawable = ContextCompat.getDrawable(onScreenControllerView.context, drawableId)!!
|
||||
|
||||
@ -242,7 +243,7 @@ abstract class OnScreenButton(
|
||||
|
||||
open fun resetConfig() {
|
||||
resetRelativeValues()
|
||||
config.enabled = true
|
||||
config.enabled = defaultEnabled
|
||||
config.scale = OnScreenConfiguration.DefaultScale
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import emu.skyline.input.ButtonId
|
||||
import emu.skyline.utils.SwitchColors
|
||||
import emu.skyline.utils.sharedPreferences
|
||||
|
||||
class OnScreenConfiguration(private val context : Context, private val buttonId : ButtonId, defaultRelativeX : Float, defaultRelativeY : Float) {
|
||||
class OnScreenConfiguration(private val context : Context, private val buttonId : ButtonId, defaultRelativeX : Float, defaultRelativeY : Float, defaultEnabled : Boolean) {
|
||||
companion object {
|
||||
const val DefaultAlpha = 130
|
||||
const val DefaultGlobalScale = 1.15f
|
||||
@ -19,7 +19,7 @@ class OnScreenConfiguration(private val context : Context, private val buttonId
|
||||
|
||||
private inline fun <reified T> config(default : T, prefix : String = "${buttonId.name}_") = sharedPreferences(context, default, prefix, "controller_config")
|
||||
|
||||
var enabled by config(true)
|
||||
var enabled by config(defaultEnabled)
|
||||
|
||||
var alpha by config(DefaultAlpha, "")
|
||||
var textColor by config(SwitchColors.BLACK.color)
|
||||
|
@ -35,7 +35,7 @@ typealias OnStickStateChangedListener = (stickId : StickId, position : PointF) -
|
||||
class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs : AttributeSet? = null, defStyleAttr : Int = 0, defStyleRes : Int = 0) : View(context, attrs, defStyleAttr, defStyleRes) {
|
||||
companion object {
|
||||
private val controllerTypeMappings = mapOf(*ControllerType.values().map {
|
||||
it to (setOf(*it.buttons) to setOf(*it.sticks))
|
||||
it to (setOf(*it.buttons) + setOf(*it.optionalButtons) to setOf(*it.sticks))
|
||||
}.toTypedArray())
|
||||
|
||||
private const val SCALE_STEP = 0.05f
|
||||
|
@ -25,7 +25,8 @@ open class CircularButton(
|
||||
defaultRelativeX : Float,
|
||||
defaultRelativeY : Float,
|
||||
defaultRelativeRadiusToX : Float,
|
||||
drawableId : Int = R.drawable.ic_button
|
||||
drawableId : Int = R.drawable.ic_button,
|
||||
defaultEnabled : Boolean = true
|
||||
) : OnScreenButton(
|
||||
onScreenControllerView,
|
||||
buttonId,
|
||||
@ -33,7 +34,8 @@ open class CircularButton(
|
||||
defaultRelativeY,
|
||||
defaultRelativeRadiusToX * 2f,
|
||||
defaultRelativeRadiusToX * CONFIGURED_ASPECT_RATIO * 2f,
|
||||
drawableId
|
||||
drawableId,
|
||||
defaultEnabled
|
||||
) {
|
||||
val radius get() = itemWidth / 2f
|
||||
|
||||
@ -60,7 +62,7 @@ class JoystickButton(
|
||||
private val innerButton = CircularButton(onScreenControllerView, buttonId, config.relativeX, config.relativeY, defaultRelativeRadiusToX * 0.75f, R.drawable.ic_stick)
|
||||
|
||||
var recenterSticks = false
|
||||
private lateinit var initialTapPosition : PointF
|
||||
private var initialTapPosition = PointF()
|
||||
private var fingerDownTime = 0L
|
||||
private var fingerUpTime = 0L
|
||||
var shortDoubleTapped = false
|
||||
@ -156,7 +158,8 @@ open class RectangularButton(
|
||||
defaultRelativeY : Float,
|
||||
defaultRelativeWidth : Float,
|
||||
defaultRelativeHeight : Float,
|
||||
drawableId : Int = R.drawable.ic_rectangular_button
|
||||
drawableId : Int = R.drawable.ic_rectangular_button,
|
||||
defaultEnabled : Boolean = true
|
||||
) : OnScreenButton(
|
||||
onScreenControllerView,
|
||||
buttonId,
|
||||
@ -164,7 +167,8 @@ open class RectangularButton(
|
||||
defaultRelativeY,
|
||||
defaultRelativeWidth,
|
||||
defaultRelativeHeight,
|
||||
drawableId
|
||||
drawableId,
|
||||
defaultEnabled
|
||||
) {
|
||||
override fun isTouched(x : Float, y : Float) = currentBounds.contains(x.roundToInt(), y.roundToInt())
|
||||
}
|
||||
@ -209,13 +213,18 @@ class Controls(onScreenControllerView : OnScreenControllerView) {
|
||||
private val buttonZL = TriggerButton(onScreenControllerView, ZL, 0.1f, 0.1f, 0.09f, 0.1f)
|
||||
private val buttonZR = TriggerButton(onScreenControllerView, ZR, 0.9f, 0.1f, 0.09f, 0.1f)
|
||||
|
||||
private val buttonL3 = CircularButton(onScreenControllerView, L3, 0.35f, 0.87f, 0.025f, defaultEnabled = false)
|
||||
private val buttonR3 = CircularButton(onScreenControllerView, R3, 0.65f, 0.87f, 0.025f, defaultEnabled = false)
|
||||
|
||||
private val circularButtonPairs = listOf(setOf(buttonA, buttonB, buttonX, buttonY), setOf(buttonDpadLeft, buttonDpadUp, buttonDpadRight, buttonDpadDown))
|
||||
|
||||
private val triggerButtonPairs = listOf(setOf(buttonL, buttonZL), setOf(buttonR, buttonZR))
|
||||
|
||||
private val stickButtons = setOf(buttonL3, buttonR3)
|
||||
|
||||
val buttonPairs = circularButtonPairs + triggerButtonPairs
|
||||
|
||||
val circularButtons = circularButtonPairs.flatten() + listOf(
|
||||
val circularButtons = circularButtonPairs.flatten() + stickButtons + listOf(
|
||||
CircularButton(onScreenControllerView, Plus, 0.57f, 0.75f, 0.025f),
|
||||
CircularButton(onScreenControllerView, Minus, 0.43f, 0.75f, 0.025f),
|
||||
CircularButton(onScreenControllerView, Menu, 0.5f, 0.75f, 0.025f)
|
||||
|
@ -220,6 +220,8 @@
|
||||
<string name="dpad">D-pad</string>
|
||||
<string name="left_stick">Left Stick</string>
|
||||
<string name="right_stick">Right Stick</string>
|
||||
<string name="left_stick_button">Left Stick Button</string>
|
||||
<string name="right_stick_button">Right Stick Button</string>
|
||||
<string name="face_buttons">Face Buttons</string>
|
||||
<string name="shoulder_trigger">Shoulder & Trigger Buttons</string>
|
||||
<string name="shoulder_rail">Shoulder Buttons on Joy-Con Rail</string>
|
||||
|
Loading…
Reference in New Issue
Block a user