diff --git a/CMakeModules/GenerateSettingKeys.cmake b/CMakeModules/GenerateSettingKeys.cmake index b5b02888e..b7be40f51 100644 --- a/CMakeModules/GenerateSettingKeys.cmake +++ b/CMakeModules/GenerateSettingKeys.cmake @@ -241,6 +241,7 @@ if (ANDROID) "screen_orientation" "performance_overlay_position" "enable_secondary_display" + "combo_button_buttons" ) string(REPLACE "_" "_1" KEY_JNI_ESCAPED ${KEY}) set(SETTING_KEY_LIST "${SETTING_KEY_LIST}\n\"${KEY}\",") diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt index ac649d2b5..92ec8a10c 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt @@ -12,5 +12,6 @@ enum class Hotkey(val button: Int) { QUICKSAVE(10005), QUICKLOAD(10006), TURBO_LIMIT(10007), - ENABLE(10008) + ENABLE(10008), + COMBO_BUTTON(10009) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt index 80fd4e2eb..8d4e1031f 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt @@ -14,6 +14,7 @@ import org.citra.citra_emu.R import org.citra.citra_emu.display.ScreenAdjustmentUtil import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.features.settings.model.view.InputBindingSetting +import org.citra.citra_emu.utils.ComboHelper import org.citra.citra_emu.utils.EmulationLifecycleUtil import org.citra.citra_emu.utils.TurboHelper @@ -71,12 +72,17 @@ class HotkeyUtility( var handled = false val buttonSet = InputBindingSetting.getButtonSet(keyEvent) val thisKeyIsEnableButton = buttonSet.contains(Hotkey.ENABLE.button) + val thisKeyIsComboButton = buttonSet.contains(Hotkey.COMBO_BUTTON.button) val thisKeyIsHotkey = !thisKeyIsEnableButton && Hotkey.entries.any { buttonSet.contains(it.button) } if (thisKeyIsEnableButton) { handled = true hotkeyIsEnabled = false } + if (thisKeyIsComboButton) { + ComboHelper.comboActivate(NativeLibrary.ButtonState.RELEASED) + handled = true + } for (button in buttonSet) { // this is a hotkey button @@ -142,6 +148,10 @@ class HotkeyUtility( ).show() } + Hotkey.COMBO_BUTTON.button -> { + ComboHelper.comboActivate(NativeLibrary.ButtonState.PRESSED) + } + else -> {} } hotkeyIsPressed = true diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt index 8e8312fde..955ece959 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt @@ -143,4 +143,5 @@ object SettingKeys { external fun screen_orientation(): String external fun performance_overlay_position(): String external fun enable_secondary_display(): String + external fun combo_button_buttons(): String } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt index 427193542..aa58bfb28 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt @@ -18,6 +18,16 @@ enum class IntListSetting( Settings.SECTION_LAYOUT, listOf(0, 1, 2, 3, 4, 5), canBeEmpty = false + ), + + /** + * Combo Buttons will be given options on MultiChoice setting initialization. This just makes selections empty by default. + */ + COMBO_BUTTON_BUTTONS( + SettingKeys.combo_button_buttons(), + Settings.SECTION_CONTROLS, + listOf(), + canBeEmpty = true ); private var backingList: List = defaultValue diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt index abf406ba5..ccd4e8744 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt @@ -142,6 +142,7 @@ class Settings { const val HOTKEY_QUICKSAVE = "hotkey_quickload" const val HOTKEY_QUICKLOAD = "hotkey_quickpause" const val HOTKEY_TURBO_LIMIT = "hotkey_turbo_limit" + const val HOTKEY_BUTTON_COMBO = "hotkey_button_combo" val buttonKeys = listOf( KEY_BUTTON_A, @@ -209,7 +210,8 @@ class Settings { HOTKEY_PAUSE_OR_RESUME, HOTKEY_QUICKSAVE, HOTKEY_QUICKLOAD, - HOTKEY_TURBO_LIMIT + HOTKEY_TURBO_LIMIT, + HOTKEY_BUTTON_COMBO ) val hotkeyTitles = listOf( R.string.controller_hotkey_enable_button, @@ -219,7 +221,8 @@ class Settings { R.string.emulation_toggle_pause, R.string.emulation_quicksave, R.string.emulation_quickload, - R.string.turbo_limit_hotkey + R.string.turbo_limit_hotkey, + R.string.button_combo ) // TODO: Move these in with the other setting keys in GenerateSettingKeys.cmake diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt index 764a734fa..e999e0706 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt @@ -127,6 +127,7 @@ class InputBindingSetting(val abstractSetting: AbstractSetting, titleId: Int) : Settings.HOTKEY_QUICKSAVE -> Hotkey.QUICKSAVE.button Settings.HOTKEY_QUICKLOAD -> Hotkey.QUICKLOAD.button Settings.HOTKEY_TURBO_LIMIT -> Hotkey.TURBO_LIMIT.button + Settings.HOTKEY_BUTTON_COMBO -> Hotkey.COMBO_BUTTON.button else -> -1 } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt index 2cf912ff1..6472f9c5c 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -799,6 +799,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) private fun addControlsSettings(sl: ArrayList) { settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_controls)) + sl.apply { add( RunnableSetting( @@ -810,6 +811,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) onLongClick = { settingsAdapter.onLongClickAutoMap() } ) ) + add(HeaderSetting(R.string.generic_buttons)) Settings.buttonKeys.forEachIndexed { i: Int, key: String -> val button = getInputObject(key) @@ -860,6 +862,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) val button = getInputObject(key) add(InputBindingSetting(button, Settings.hotkeyTitles[i])) } + add(HeaderSetting(R.string.miscellaneous)) add( SwitchSetting( @@ -870,6 +873,18 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) BooleanSetting.USE_ARTIC_BASE_CONTROLLER.defaultValue ) ) + + add( + MultiChoiceSetting( + IntListSetting.COMBO_BUTTON_BUTTONS, + R.string.combo_button_settings, + R.string.combo_button_settings_description, + R.array.comboOptions, + R.array.comboOptionValues, + IntListSetting.COMBO_BUTTON_BUTTONS.key, + IntListSetting.COMBO_BUTTON_BUTTONS.defaultValue + ) + ) } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt index f1280f917..66e6c35ae 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt @@ -69,6 +69,7 @@ import org.citra.citra_emu.display.PortraitScreenLayout import org.citra.citra_emu.display.ScreenAdjustmentUtil import org.citra.citra_emu.display.ScreenLayout import org.citra.citra_emu.display.SecondaryDisplayLayout +import org.citra.citra_emu.features.hotkeys.Hotkey import org.citra.citra_emu.features.settings.model.BooleanSetting import org.citra.citra_emu.features.settings.model.IntSetting import org.citra.citra_emu.features.settings.model.SettingsViewModel @@ -862,6 +863,11 @@ class EmulationFragment : true } + R.id.menu_emulation_adjust_scale_button_combo -> { + showAdjustScaleDialog("controlScale-" + Hotkey.COMBO_BUTTON.button) + true + } + R.id.menu_emulation_adjust_opacity -> { showAdjustOpacityDialog() true @@ -1241,13 +1247,13 @@ class EmulationFragment : private fun showToggleControlsDialog() { val editor = preferences.edit() - val enabledButtons = BooleanArray(16) + val enabledButtons = BooleanArray(17) enabledButtons.forEachIndexed { i: Int, _: Boolean -> // Buttons that are disabled by default var defaultValue = true when (i) { // TODO: Remove these magic numbers - 6, 7, 12, 13, 14, 15 -> defaultValue = false + 6, 7, 12, 13, 14, 15, 16 -> defaultValue = false } enabledButtons[i] = preferences.getBoolean("buttonToggle$i", defaultValue) } @@ -1415,6 +1421,7 @@ class EmulationFragment : resetScale("controlScale-" + NativeLibrary.ButtonType.STICK_C) resetScale("controlScale-" + NativeLibrary.ButtonType.BUTTON_HOME) resetScale("controlScale-" + NativeLibrary.ButtonType.BUTTON_SWAP) + resetScale("controlScale-" + Hotkey.COMBO_BUTTON.button) binding.surfaceInputOverlay.refreshControls() } @@ -1442,10 +1449,11 @@ class EmulationFragment : .apply() val editor = preferences.edit() - for (i in 0 until 16) { + // TODO: This code sucks balls. We need to do this differently. -OS + for (i in 0 until 17) { var defaultValue = true when (i) { - 6, 7, 12, 13, 14, 15 -> defaultValue = false + 6, 7, 12, 13, 14, 15, 16 -> defaultValue = false } editor.putBoolean("buttonToggle$i", defaultValue) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt index c22fb0c89..a71061f7b 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt @@ -26,6 +26,8 @@ import kotlin.math.min import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R +import org.citra.citra_emu.features.hotkeys.Hotkey +import org.citra.citra_emu.utils.ComboHelper import org.citra.citra_emu.utils.EmulationMenuSettings import org.citra.citra_emu.utils.TurboHelper @@ -184,6 +186,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : button.status == NativeLibrary.ButtonState.PRESSED ) { TurboHelper.toggleTurbo(true) + } else if (button.id == Hotkey.COMBO_BUTTON.button) { + ComboHelper.comboActivate(button.status) } NativeLibrary.onGamePadEvent( @@ -593,6 +597,18 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : ) ) } + + if (preferences.getBoolean("buttonToggle16", false)) { + overlayButtons.add( + initializeOverlayButton( + context, + R.drawable.button_combo, + R.drawable.button_combo_pressed, + Hotkey.COMBO_BUTTON.button, + orientation + ) + ) + } } fun refreshControls() { @@ -806,6 +822,14 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : NativeLibrary.ButtonType.BUTTON_TURBO.toString() + "-Y", resources.getInteger(R.integer.N3DS_BUTTON_TURBO_Y).toFloat() / 1000 * maxY ) + .putFloat( + Hotkey.COMBO_BUTTON.button.toString() + "-X", + resources.getInteger(R.integer.N3DS_BUTTON_COMBO_X).toFloat() / 1000 * maxX + ) + .putFloat( + Hotkey.COMBO_BUTTON.button.toString() + "-Y", + resources.getInteger(R.integer.N3DS_BUTTON_COMBO_Y).toFloat() / 1000 * maxY + ) .apply() } @@ -957,6 +981,14 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : NativeLibrary.ButtonType.BUTTON_TURBO.toString() + portrait + "-Y", resources.getInteger(R.integer.N3DS_BUTTON_TURBO_PORTRAIT_Y).toFloat() / 1000 * maxY ) + .putFloat( + Hotkey.COMBO_BUTTON.button.toString() + portrait + "-X", + resources.getInteger(R.integer.N3DS_BUTTON_COMBO_PORTRAIT_X).toFloat() / 1000 * maxX + ) + .putFloat( + Hotkey.COMBO_BUTTON.button.toString() + portrait + "-Y", + resources.getInteger(R.integer.N3DS_BUTTON_COMBO_PORTRAIT_Y).toFloat() / 1000 * maxY + ) .apply() } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/ComboHelper.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/ComboHelper.kt new file mode 100644 index 000000000..38473e4f4 --- /dev/null +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/ComboHelper.kt @@ -0,0 +1,26 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +package org.citra.citra_emu.utils + +import org.citra.citra_emu.NativeLibrary +import org.citra.citra_emu.features.settings.model.IntListSetting + +object ComboHelper { + fun comboActivate(buttonStatus: Int) { + val comboArray = IntListSetting.COMBO_BUTTON_BUTTONS.list + for (nativeButton in comboArray) { + if (nativeButton == -1) { + // We don't want to parse any bad inputs here so we continue loop + continue + } else { + NativeLibrary.onGamePadEvent( + NativeLibrary.TOUCHSCREEN_DEVICE, + nativeButton, + buttonStatus + ) + } + } + } +} diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index 97f7b98d6..5721c2040 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -80,6 +80,9 @@ static const char* android_config_default_file_content = (BOOST_HANA_STRING(R"( # Use Artic Controller when connected to Artic Base Server. (Default 0) )") DECLARE_KEY(use_artic_base_controller) BOOST_HANA_STRING(R"( +# List of buttons which will be triggered by the combo button. (Default [] or empty) +)") DECLARE_KEY(combo_button_buttons) BOOST_HANA_STRING(R"( + [Core] # Whether to use the Just-In-Time (JIT) compiler for CPU emulation # 0: Interpreter (slow), 1 (default): JIT (fast) diff --git a/src/android/app/src/main/res/drawable/button_combo.xml b/src/android/app/src/main/res/drawable/button_combo.xml new file mode 100644 index 000000000..fdd9a79a4 --- /dev/null +++ b/src/android/app/src/main/res/drawable/button_combo.xml @@ -0,0 +1,32 @@ + + + + + + + + diff --git a/src/android/app/src/main/res/drawable/button_combo_pressed.xml b/src/android/app/src/main/res/drawable/button_combo_pressed.xml new file mode 100644 index 000000000..d8825692d --- /dev/null +++ b/src/android/app/src/main/res/drawable/button_combo_pressed.xml @@ -0,0 +1,28 @@ + + + + diff --git a/src/android/app/src/main/res/menu/menu_overlay_options.xml b/src/android/app/src/main/res/menu/menu_overlay_options.xml index 8bb19ee26..34589ebc3 100644 --- a/src/android/app/src/main/res/menu/menu_overlay_options.xml +++ b/src/android/app/src/main/res/menu/menu_overlay_options.xml @@ -79,6 +79,9 @@ + diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 867e0379a..ba7c35dd9 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -188,8 +188,37 @@ @string/button_home @string/button_swap @string/button_turbo + @string/button_combo + + @string/button_a + @string/button_b + @string/button_x + @string/button_y + @string/button_l + @string/button_r + @string/button_zl + @string/button_zr + @string/button_start + @string/button_select + + + + + 700 + 701 + 702 + 703 + 773 + 774 + 707 + 708 + 704 + 705 + + + @string/blank @string/still_image diff --git a/src/android/app/src/main/res/values/integers.xml b/src/android/app/src/main/res/values/integers.xml index 1f19c2373..4567863e0 100644 --- a/src/android/app/src/main/res/values/integers.xml +++ b/src/android/app/src/main/res/values/integers.xml @@ -35,6 +35,8 @@ 850 630 850 + 740 + 480 810 @@ -69,5 +71,7 @@ 675 453 720 + 450 + 925 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 1184f9274..c71ae2cf7 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -156,6 +156,7 @@ HOME Swap Screens Turbo + Combo Button X Y L @@ -167,6 +168,8 @@ Turbo Speed Turbo Speed Enabled Turbo Speed Disabled + Configure Combo Button + Select which buttons are triggered by the Combo Button. System Files