diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt
index 8ad871a57d..def62eb7ec 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt
@@ -439,6 +439,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
MENU_ACTION_EDIT_CONTROLS_PLACEMENT -> editControlsPlacement()
MENU_ACTION_RESET_OVERLAY -> resetOverlay()
MENU_ACTION_TOGGLE_CONTROLS -> toggleControls()
+ MENU_ACTION_LATCHING_CONTROLS -> latchingControls()
MENU_ACTION_ADJUST_SCALE -> adjustScale()
MENU_ACTION_CHOOSE_CONTROLLER -> chooseController()
MENU_ACTION_REFRESH_WIIMOTES -> NativeLibrary.RefreshWiimotes()
@@ -514,6 +515,85 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
return super.dispatchKeyEvent(event)
}
+ private fun latchingControls() {
+ val builder = MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.emulation_latching_controls)
+
+ when (InputOverlay.configuredControllerType) {
+ InputOverlay.OVERLAY_GAMECUBE -> {
+ val gcLatchingButtons = BooleanArray(8)
+ val gcSettingBase = "MAIN_BUTTON_LATCHING_GC_"
+
+ for (i in gcLatchingButtons.indices) {
+ gcLatchingButtons[i] = BooleanSetting.valueOf(gcSettingBase + i).boolean
+ }
+
+ builder.setMultiChoiceItems(
+ R.array.gcpadLatchableButtons, gcLatchingButtons
+ ) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
+ BooleanSetting.valueOf(gcSettingBase + indexSelected)
+ .setBoolean(settings, isChecked)
+ }
+ }
+ InputOverlay.OVERLAY_WIIMOTE_CLASSIC -> {
+ val wiiClassicLatchingButtons = BooleanArray(11)
+ val classicSettingBase = "MAIN_BUTTON_LATCHING_CLASSIC_"
+
+ for (i in wiiClassicLatchingButtons.indices) {
+ wiiClassicLatchingButtons[i] = BooleanSetting.valueOf(classicSettingBase + i).boolean
+ }
+ builder.setMultiChoiceItems(
+ R.array.classicLatchableButtons, wiiClassicLatchingButtons
+ ) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
+ BooleanSetting.valueOf(classicSettingBase + indexSelected)
+ .setBoolean(settings, isChecked)
+ }
+ }
+ InputOverlay.OVERLAY_WIIMOTE_NUNCHUK -> {
+ val nunchukLatchingButtons = BooleanArray(9)
+ val nunchukSettingBase = "MAIN_BUTTON_LATCHING_WII_"
+
+ // For OVERLAY_WIIMOTE_NUNCHUK, settings index 7 is the D-Pad (which cannot be
+ // latching). C and Z (settings indices 8 and 9) need to map to multichoice array
+ // indices 7 and 8 to avoid a gap.
+ fun translateToSettingsIndex(idx: Int): Int = if (idx >= 7) idx + 1 else idx
+
+ for (i in nunchukLatchingButtons.indices) {
+ nunchukLatchingButtons[i] = BooleanSetting
+ .valueOf(nunchukSettingBase + translateToSettingsIndex(i)).boolean
+ }
+
+ builder.setMultiChoiceItems(
+ R.array.nunchukLatchableButtons, nunchukLatchingButtons
+ ) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
+ BooleanSetting.valueOf(nunchukSettingBase + translateToSettingsIndex(indexSelected))
+ .setBoolean(settings, isChecked)
+ }
+ }
+ else -> {
+ val wiimoteLatchingButtons = BooleanArray(7)
+ val wiimoteSettingBase = "MAIN_BUTTON_LATCHING_WII_"
+
+ for (i in wiimoteLatchingButtons.indices) {
+ wiimoteLatchingButtons[i] = BooleanSetting.valueOf(wiimoteSettingBase + i).boolean
+ }
+
+ builder.setMultiChoiceItems(
+ R.array.wiimoteLatchableButtons, wiimoteLatchingButtons
+ ) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
+ BooleanSetting.valueOf(wiimoteSettingBase + indexSelected)
+ .setBoolean(settings, isChecked)
+ }
+ }
+ }
+
+ builder
+ .setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
+ emulationFragment?.refreshInputOverlay()
+ }
+ .show()
+ }
+
private fun toggleControls() {
val builder = MaterialAlertDialogBuilder(this)
.setTitle(R.string.emulation_toggle_controls)
@@ -968,11 +1048,13 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
const val MENU_ACTION_SETTINGS = 35
const val MENU_ACTION_SKYLANDERS = 36
const val MENU_ACTION_INFINITY_BASE = 37
+ const val MENU_ACTION_LATCHING_CONTROLS = 38
init {
buttonsActionsMap.apply {
append(R.id.menu_emulation_edit_layout, MENU_ACTION_EDIT_CONTROLS_PLACEMENT)
append(R.id.menu_emulation_toggle_controls, MENU_ACTION_TOGGLE_CONTROLS)
+ append(R.id.menu_emulation_latching_controls, MENU_ACTION_LATCHING_CONTROLS)
append(R.id.menu_emulation_adjust_scale, MENU_ACTION_ADJUST_SCALE)
append(R.id.menu_emulation_choose_controller, MENU_ACTION_CHOOSE_CONTROLLER)
append(R.id.menu_emulation_joystick_rel_center, MENU_ACTION_JOYSTICK_REL_CENTER)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt
index 60042ceb8e..e32bd1f465 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt
@@ -320,6 +320,54 @@ enum class BooleanSetting(
"ButtonToggleGCStickC",
true
),
+ MAIN_BUTTON_LATCHING_GC_0(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCButtonA",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_GC_1(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCButtonB",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_GC_2(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCButtonX",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_GC_3(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCButtonY",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_GC_4(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCButtonZ",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_GC_5(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCButtonStart",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_GC_6(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCTriggerL",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_GC_7(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingGCTriggerR",
+ false
+ ),
MAIN_BUTTON_TOGGLE_CLASSIC_0(
Settings.FILE_DOLPHIN,
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
@@ -404,6 +452,72 @@ enum class BooleanSetting(
"ButtonToggleClassicStickRight",
true
),
+ MAIN_BUTTON_LATCHING_CLASSIC_0(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonA",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_1(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonB",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_2(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonX",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_3(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonY",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_4(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonPlus",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_5(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonMinus",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_6(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonHome",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_7(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicTriggerL",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_8(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicTriggerR",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_9(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonZL",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_CLASSIC_10(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingClassicButtonZR",
+ false
+ ),
MAIN_BUTTON_TOGGLE_WII_0(
Settings.FILE_DOLPHIN,
Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
@@ -470,6 +584,60 @@ enum class BooleanSetting(
"ButtonToggleNunchukStick",
true
),
+ MAIN_BUTTON_LATCHING_WII_0(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingWiimoteButtonA",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_1(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingWiimoteButtonB",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_2(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingWiimoteButton1",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_3(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingWiimoteButton2",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_4(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingWiimoteButtonPlus",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_5(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingWiimoteButtonMinus",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_6(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingWiimoteButtonHome",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_8(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingNunchukC",
+ false
+ ),
+ MAIN_BUTTON_LATCHING_WII_9(
+ Settings.FILE_DOLPHIN,
+ Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS,
+ "ButtonLatchingNunchukZ",
+ false
+ ),
SYSCONF_SCREENSAVER(Settings.FILE_SYSCONF, "IPL", "SSV", false),
SYSCONF_WIDESCREEN(Settings.FILE_SYSCONF, "IPL", "AR", true),
SYSCONF_PROGRESSIVE_SCAN(Settings.FILE_SYSCONF, "IPL", "PGS", true),
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.kt
index cc974a89df..dfe557e712 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.kt
@@ -154,10 +154,10 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
event.getY(pointerIndex).toInt()
)
) {
- button.setPressedState(true)
+ button.setPressedState(if (button.latching) !button.getPressedState() else true)
button.trackId = event.getPointerId(pointerIndex)
pressed = true
- InputOverrider.setControlState(controllerIndex, button.control, 1.0)
+ InputOverrider.setControlState(controllerIndex, button.control, if (button.getPressedState()) 1.0 else 0.0)
val analogControl = getAnalogControlForTrigger(button.control)
if (analogControl >= 0)
@@ -173,8 +173,9 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
MotionEvent.ACTION_POINTER_UP -> {
// If a pointer ends, release the button it was pressing.
if (button.trackId == event.getPointerId(pointerIndex)) {
- button.setPressedState(false)
- InputOverrider.setControlState(controllerIndex, button.control, 0.0)
+ if (!button.latching)
+ button.setPressedState(false)
+ InputOverrider.setControlState(controllerIndex, button.control, if (button.getPressedState()) 1.0 else 0.0)
val analogControl = getAnalogControlForTrigger(button.control)
if (analogControl >= 0)
@@ -497,7 +498,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_a_pressed,
ButtonType.BUTTON_A,
ControlId.GCPAD_A_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_0.boolean
)
)
}
@@ -509,7 +511,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_b_pressed,
ButtonType.BUTTON_B,
ControlId.GCPAD_B_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_1.boolean
)
)
}
@@ -521,7 +524,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_x_pressed,
ButtonType.BUTTON_X,
ControlId.GCPAD_X_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_2.boolean
)
)
}
@@ -533,7 +537,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_y_pressed,
ButtonType.BUTTON_Y,
ControlId.GCPAD_Y_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_3.boolean
)
)
}
@@ -545,7 +550,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_z_pressed,
ButtonType.BUTTON_Z,
ControlId.GCPAD_Z_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_4.boolean
)
)
}
@@ -557,7 +563,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_start_pressed,
ButtonType.BUTTON_START,
ControlId.GCPAD_START_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_5.boolean
)
)
}
@@ -569,7 +576,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_l_pressed,
ButtonType.TRIGGER_L,
ControlId.GCPAD_L_DIGITAL,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_6.boolean
)
)
}
@@ -581,7 +589,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.gcpad_r_pressed,
ButtonType.TRIGGER_R,
ControlId.GCPAD_R_DIGITAL,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_GC_7.boolean
)
)
}
@@ -640,7 +649,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_a_pressed,
ButtonType.WIIMOTE_BUTTON_A,
ControlId.WIIMOTE_A_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_0.boolean
)
)
}
@@ -652,7 +662,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_b_pressed,
ButtonType.WIIMOTE_BUTTON_B,
ControlId.WIIMOTE_B_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_1.boolean
)
)
}
@@ -664,7 +675,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_one_pressed,
ButtonType.WIIMOTE_BUTTON_1,
ControlId.WIIMOTE_ONE_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_2.boolean
)
)
}
@@ -676,7 +688,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_two_pressed,
ButtonType.WIIMOTE_BUTTON_2,
ControlId.WIIMOTE_TWO_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_3.boolean
)
)
}
@@ -688,7 +701,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_plus_pressed,
ButtonType.WIIMOTE_BUTTON_PLUS,
ControlId.WIIMOTE_PLUS_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_4.boolean
)
)
}
@@ -700,7 +714,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_minus_pressed,
ButtonType.WIIMOTE_BUTTON_MINUS,
ControlId.WIIMOTE_MINUS_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_5.boolean
)
)
}
@@ -712,7 +727,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_home_pressed,
ButtonType.WIIMOTE_BUTTON_HOME,
ControlId.WIIMOTE_HOME_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_6.boolean
)
)
}
@@ -743,7 +759,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.nunchuk_c_pressed,
ButtonType.NUNCHUK_BUTTON_C,
ControlId.NUNCHUK_C_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_8.boolean
)
)
}
@@ -755,7 +772,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.nunchuk_z_pressed,
ButtonType.NUNCHUK_BUTTON_Z,
ControlId.NUNCHUK_Z_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_WII_9.boolean
)
)
}
@@ -784,7 +802,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_a_pressed,
ButtonType.CLASSIC_BUTTON_A,
ControlId.CLASSIC_A_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_0.boolean
)
)
}
@@ -796,7 +815,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_b_pressed,
ButtonType.CLASSIC_BUTTON_B,
ControlId.CLASSIC_B_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_1.boolean
)
)
}
@@ -808,7 +828,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_x_pressed,
ButtonType.CLASSIC_BUTTON_X,
ControlId.CLASSIC_X_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_2.boolean
)
)
}
@@ -820,7 +841,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_y_pressed,
ButtonType.CLASSIC_BUTTON_Y,
ControlId.CLASSIC_Y_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_3.boolean
)
)
}
@@ -832,7 +854,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_plus_pressed,
ButtonType.CLASSIC_BUTTON_PLUS,
ControlId.CLASSIC_PLUS_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_4.boolean
)
)
}
@@ -844,7 +867,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_minus_pressed,
ButtonType.CLASSIC_BUTTON_MINUS,
ControlId.CLASSIC_MINUS_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_5.boolean
)
)
}
@@ -856,7 +880,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.wiimote_home_pressed,
ButtonType.CLASSIC_BUTTON_HOME,
ControlId.CLASSIC_HOME_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_6.boolean
)
)
}
@@ -868,7 +893,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_l_pressed,
ButtonType.CLASSIC_TRIGGER_L,
ControlId.CLASSIC_L_DIGITAL,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_7.boolean
)
)
}
@@ -880,7 +906,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_r_pressed,
ButtonType.CLASSIC_TRIGGER_R,
ControlId.CLASSIC_R_DIGITAL,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_8.boolean
)
)
}
@@ -892,7 +919,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_zl_pressed,
ButtonType.CLASSIC_BUTTON_ZL,
ControlId.CLASSIC_ZL_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_9.boolean
)
)
}
@@ -904,7 +932,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
R.drawable.classic_zr_pressed,
ButtonType.CLASSIC_BUTTON_ZR,
ControlId.CLASSIC_ZR_BUTTON,
- orientation
+ orientation,
+ BooleanSetting.MAIN_BUTTON_LATCHING_CLASSIC_10.boolean
)
)
}
@@ -1094,11 +1123,17 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
* @param pressedResId The resource ID of the [Drawable] to get the [Bitmap] of (Pressed State).
* @param legacyId Legacy identifier for the button the InputOverlayDrawableButton represents.
* @param control Control identifier for the button the InputOverlayDrawableButton represents.
+ * @param latching Whether the button is latching.
* @return An [InputOverlayDrawableButton] with the correct drawing bounds set.
*/
private fun initializeOverlayButton(
context: Context,
- defaultResId: Int, pressedResId: Int, legacyId: Int, control: Int, orientation: String
+ defaultResId: Int,
+ pressedResId: Int,
+ legacyId: Int,
+ control: Int,
+ orientation: String,
+ latching: Boolean
): InputOverlayDrawableButton {
// Decide scale based on button ID and user preference
var scale = when (legacyId) {
@@ -1140,12 +1175,14 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex
resizeBitmap(context, BitmapFactory.decodeResource(resources, defaultResId), scale)
val pressedStateBitmap =
resizeBitmap(context, BitmapFactory.decodeResource(resources, pressedResId), scale)
+
val overlayDrawable = InputOverlayDrawableButton(
resources,
defaultStateBitmap,
pressedStateBitmap,
legacyId,
- control
+ control,
+ latching
)
// The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay.
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.kt
index 220eb836d5..643d65fe14 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.kt
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlayDrawableButton.kt
@@ -18,13 +18,15 @@ import android.view.MotionEvent
* @param pressedStateBitmap [Bitmap] to use with the pressed state Drawable.
* @param legacyId Legacy identifier (ButtonType) for this type of button.
* @param control Control ID for this type of button.
+ * @param latching Whether this button is latching.
*/
class InputOverlayDrawableButton(
res: Resources,
defaultStateBitmap: Bitmap,
pressedStateBitmap: Bitmap,
val legacyId: Int,
- val control: Int
+ val control: Int,
+ var latching: Boolean
) {
var trackId: Int = -1
private var previousTouchX = 0
@@ -94,4 +96,8 @@ class InputOverlayDrawableButton(
fun setPressedState(isPressed: Boolean) {
pressedState = isPressed
}
+
+ fun getPressedState(): Boolean {
+ return pressedState;
+ }
}
diff --git a/Source/Android/app/src/main/res/menu/menu_overlay_controls_gc.xml b/Source/Android/app/src/main/res/menu/menu_overlay_controls_gc.xml
index fc33d4639f..e4ef459487 100644
--- a/Source/Android/app/src/main/res/menu/menu_overlay_controls_gc.xml
+++ b/Source/Android/app/src/main/res/menu/menu_overlay_controls_gc.xml
@@ -10,6 +10,10 @@
android:id="@+id/menu_emulation_toggle_controls"
android:title="@string/emulation_toggle_controls"/>
+
+
diff --git a/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml b/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml
index 4c1281f644..066889493f 100644
--- a/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml
+++ b/Source/Android/app/src/main/res/menu/menu_overlay_controls_wii.xml
@@ -10,6 +10,10 @@
android:id="@+id/menu_emulation_toggle_controls"
android:title="@string/emulation_toggle_controls"/>
+
+
diff --git a/Source/Android/app/src/main/res/values/arrays.xml b/Source/Android/app/src/main/res/values/arrays.xml
index fd2618af70..3821c0b22d 100644
--- a/Source/Android/app/src/main/res/values/arrays.xml
+++ b/Source/Android/app/src/main/res/values/arrays.xml
@@ -400,6 +400,17 @@
- @string/gamepad_c_stick
+
+ - A
+ - B
+ - X
+ - Y
+ - Z
+ - @string/gamepad_start
+ - L
+ - R
+
+
- A
- B
@@ -411,6 +422,16 @@
- @string/gamepad_d_pad
+
+ - A
+ - B
+ - 1
+ - 2
+ - +
+ - -
+ - @string/gamepad_home
+
+
- A
- B
@@ -425,6 +446,18 @@
- @string/gamepad_nunchuk_stick
+
+ - A
+ - B
+ - 1
+ - 2
+ - +
+ - -
+ - @string/gamepad_home
+ - C
+ - Z
+
+
- a
- b
@@ -442,6 +475,20 @@
- @string/gamepad_right_stick
+
+ - a
+ - b
+ - x
+ - y
+ - +
+ - -
+ - @string/gamepad_home
+ - L
+ - R
+ - ZL
+ - ZR
+
+
- @string/ir_disabled
- @string/ir_follow
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 9145d10af0..059375a344 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -571,6 +571,7 @@ It can efficiently compress both junk data and encrypted Wii data.
Edit Layout
Done
Toggle Controls
+ Latching Controls
Toggle All
Scale
Opacity