diff --git a/CMakeModules/GenerateSettingKeys.cmake b/CMakeModules/GenerateSettingKeys.cmake
index 7aff65db5..8054e9afc 100644
--- a/CMakeModules/GenerateSettingKeys.cmake
+++ b/CMakeModules/GenerateSettingKeys.cmake
@@ -238,6 +238,7 @@ if (ANDROID)
"android_hide_images"
"screen_orientation"
"performance_overlay_position"
+ "enable_secondary_display"
)
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/display/ScreenAdjustmentUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt
index cf18a175c..d717e87e6 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt
@@ -78,6 +78,17 @@ class ScreenAdjustmentUtil(
NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode)
}
+ fun enableSecondaryDisplay(layoutOption: Int) {
+ BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean = true
+ settings.saveSetting(BooleanSetting.ENABLE_SECONDARY_DISPLAY, SettingsFile.FILE_NAME_CONFIG)
+ changeSecondaryOrientation(layoutOption)
+ }
+
+ fun disableSecondaryDisplay() {
+ BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean = false
+ settings.saveSetting(BooleanSetting.ENABLE_SECONDARY_DISPLAY, SettingsFile.FILE_NAME_CONFIG)
+ }
+
fun changeActivityOrientation(orientationOption: Int) {
val activity = context as? Activity ?: return
IntSetting.ORIENTATION_OPTION.int = orientationOption
diff --git a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt
index c705c2104..9e72f3894 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt
@@ -53,6 +53,8 @@ enum class PortraitScreenLayout(val int: Int) {
enum class SecondaryDisplayLayout(val int: Int) {
// These must match what is defined in src/common/settings.h
+ // NONE is no longer selectable in the interface, having been replaced with
+ // the boolean ENABLE_SECONDARY_DISPLAY setting, but is left here for backwards compatibility
NONE(0),
TOP_SCREEN(1),
BOTTOM_SCREEN(2),
diff --git a/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt
index 5796cb4b0..0a3eee316 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt
@@ -17,6 +17,7 @@ import android.view.SurfaceView
import android.view.WindowManager
import org.citra.citra_emu.features.settings.model.IntSetting
import org.citra.citra_emu.NativeLibrary
+import org.citra.citra_emu.features.settings.model.BooleanSetting
import org.citra.citra_emu.utils.Log
class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener {
@@ -84,7 +85,10 @@ class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener {
}
val displayToUse = if (availableDisplays.isEmpty() ||
- IntSetting.SECONDARY_DISPLAY_LAYOUT.int == SecondaryDisplayLayout.NONE.int
+ // Theoretically, the NONE option is no longer selectable, but
+ // I am leaving this in for backwards compatibility
+ IntSetting.SECONDARY_DISPLAY_LAYOUT.int == SecondaryDisplayLayout.NONE.int ||
+ ! BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean
) {
currentDisplayId = -1
vd.display
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 56ffb6789..f9ff306f8 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
@@ -141,4 +141,5 @@ object SettingKeys {
external fun android_hide_images(): String
external fun screen_orientation(): String
external fun performance_overlay_position(): String
+ external fun enable_secondary_display(): String
}
\ No newline at end of file
diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt
index 0e88dacf3..cda0a5f2f 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt
@@ -59,6 +59,7 @@ enum class BooleanSetting(
ANDROID_HIDE_IMAGES(SettingKeys.android_hide_images(), Settings.SECTION_MISC, false),
APPLY_REGION_FREE_PATCH(SettingKeys.apply_region_free_patch(), Settings.SECTION_SYSTEM, true),
USE_INTEGER_SCALING(SettingKeys.use_integer_scaling(), Settings.SECTION_RENDERER, false),
+ ENABLE_SECONDARY_DISPLAY(SettingKeys.enable_secondary_display(), Settings.SECTION_LAYOUT, true),
SIMULATE_3DS_GPU_TIMINGS(SettingKeys.simulate_3ds_gpu_timings(), Settings.SECTION_RENDERER, true);
override var boolean: Boolean = defaultValue
diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt
index eb1a880a5..5eb8944d5 100644
--- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt
+++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt
@@ -37,7 +37,7 @@ enum class IntSetting(
LANDSCAPE_BOTTOM_HEIGHT(SettingKeys.custom_bottom_height(),Settings.SECTION_LAYOUT,480),
SCREEN_GAP(SettingKeys.screen_gap(),Settings.SECTION_LAYOUT,0),
PORTRAIT_SCREEN_LAYOUT(SettingKeys.portrait_layout_option(),Settings.SECTION_LAYOUT,0),
- SECONDARY_DISPLAY_LAYOUT(SettingKeys.secondary_display_layout(),Settings.SECTION_LAYOUT,0),
+ SECONDARY_DISPLAY_LAYOUT(SettingKeys.secondary_display_layout(),Settings.SECTION_LAYOUT,4),
PORTRAIT_TOP_X(SettingKeys.custom_portrait_top_x(),Settings.SECTION_LAYOUT,0),
PORTRAIT_TOP_Y(SettingKeys.custom_portrait_top_y(),Settings.SECTION_LAYOUT,0),
PORTRAIT_TOP_WIDTH(SettingKeys.custom_portrait_top_width(),Settings.SECTION_LAYOUT,800),
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 94bfe78a9..ad3f9cb8c 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
@@ -1201,6 +1201,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
IntSetting.PORTRAIT_SCREEN_LAYOUT.defaultValue
)
)
+ add (
+ SwitchSetting(
+ BooleanSetting.ENABLE_SECONDARY_DISPLAY,
+ R.string.emulation_secondary_display_enable,
+ R.string.emulation_secondary_display_enable_description,
+ BooleanSetting.ENABLE_SECONDARY_DISPLAY.key,
+ BooleanSetting.ENABLE_SECONDARY_DISPLAY.defaultValue
+ )
+ )
add(
SingleChoiceSetting(
IntSetting.SECONDARY_DISPLAY_LAYOUT,
@@ -1209,7 +1218,8 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
R.array.secondaryLayouts,
R.array.secondaryLayoutValues,
IntSetting.SECONDARY_DISPLAY_LAYOUT.key,
- IntSetting.SECONDARY_DISPLAY_LAYOUT.defaultValue
+ IntSetting.SECONDARY_DISPLAY_LAYOUT.defaultValue,
+ BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean
)
)
add(
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 d3e6546fc..979e5131b 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
@@ -1065,26 +1065,27 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
var selectedLayout = IntSetting.SECONDARY_DISPLAY_LAYOUT.int
val chooserMenu = popupMenu.menu.findItem(R.id.menu_secondary_choose)
- val enableSecondaryCheckbox = popupMenu.menu.findItem(R.id.menu_secondary_layout_none)
+ val enableSecondaryCheckbox = popupMenu.menu.findItem(R.id.menu_enable_secondary_layout)
chooserMenu?.subMenu?.removeGroup(R.id.menu_secondary_management_display_group)
val displays =
emulationActivity.secondaryDisplayManager.availableDisplays
- if (selectedLayout == SecondaryDisplayLayout.NONE.int) {
+ if (selectedLayout == SecondaryDisplayLayout.NONE.int || !BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean) {
+ BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean = false
enableSecondaryCheckbox.isChecked = false
chooserMenu.isVisible = false
popupMenu.menu.setGroupEnabled(R.id.menu_secondary_layout_group, false)
- selectedLayout = SecondaryDisplayLayout.REVERSE_PRIMARY.int
+
} else {
popupMenu.menu.setGroupEnabled(R.id.menu_secondary_layout_group, true)
chooserMenu.isVisible = (displays.size > 1)
}
val layoutOptionMenuItem = when (selectedLayout) {
SecondaryDisplayLayout.NONE.int ->
- R.id.menu_secondary_layout_opposite
+ R.id.menu_secondary_layout_reverse_primary
SecondaryDisplayLayout.REVERSE_PRIMARY.int ->
- R.id.menu_secondary_layout_opposite
+ R.id.menu_secondary_layout_reverse_primary
SecondaryDisplayLayout.TOP_SCREEN.int ->
R.id.menu_secondary_layout_top
@@ -1130,18 +1131,18 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram
popupMenu.setOnMenuItemClickListener {
when (it.itemId) {
- R.id.menu_secondary_layout_none -> {
+ R.id.menu_enable_secondary_layout -> {
if (!it.isChecked) {
- screenAdjustmentUtil.changeSecondaryOrientation(selectedLayout)
+ screenAdjustmentUtil.enableSecondaryDisplay(selectedLayout)
} else {
- screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.NONE.int)
+ screenAdjustmentUtil.disableSecondaryDisplay()
}
emulationActivity.secondaryDisplayManager.updateDisplay()
showSecondaryScreenLayoutMenu() // reopen menu to get new behaviors
true
}
- R.id.menu_secondary_layout_opposite -> {
+ R.id.menu_secondary_layout_reverse_primary -> {
screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.REVERSE_PRIMARY.int)
true
}
diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h
index 6864d04b0..cc3d91ec5 100644
--- a/src/android/app/src/main/jni/default_ini.h
+++ b/src/android/app/src/main/jni/default_ini.h
@@ -354,6 +354,10 @@ static const char* android_config_default_file_content = (BOOST_HANA_STRING(R"(
# 0 (default): Off, 1: On
)") DECLARE_KEY(expand_to_cutout_area) BOOST_HANA_STRING(R"(
+# Allows Azahar to use externally connected displays
+# 0: Off, 1: On (default)
+)") DECLARE_KEY(enable_secondary_display) BOOST_HANA_STRING(R"(
+
# Secondary Display Layout
# What the game should do if a secondary display is connected physically or using
# Miracast / Chromecast screen mirroring
diff --git a/src/android/app/src/main/res/menu/menu_secondary_screen_layout.xml b/src/android/app/src/main/res/menu/menu_secondary_screen_layout.xml
index 148a1405d..0ed57b51d 100644
--- a/src/android/app/src/main/res/menu/menu_secondary_screen_layout.xml
+++ b/src/android/app/src/main/res/menu/menu_secondary_screen_layout.xml
@@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
@@ -24,8 +24,8 @@
android:checkableBehavior="single"
android:id="@+id/menu_secondary_layout_group">
+ android:id="@+id/menu_secondary_layout_reverse_primary"
+ android:title="@string/emulation_secondary_display_reverse_primary" />
-
-
- @string/emulation_secondary_display_default
- - @string/emulation_secondary_display_opposite
+ - @string/emulation_secondary_display_reverse_primary
- @string/emulation_top_screen
- @string/emulation_bottom_screen
- @string/emulation_screen_layout_sidebyside
@@ -54,7 +53,6 @@
- - 0
- 4
- 1
- 2
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 7c35ed749..c326fdb39 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -501,6 +501,7 @@
Landscape Screen Layout
Portrait Screen Layout
Enable Secondary Display
+ If disabled, Azahar will let Android manage connected displays. If this is enabled and multiple displays are connected, you can select which one Azahar will use in the Emulation Quick Menu
Secondary Display Layout
Secondary Display
Choose Display
@@ -513,7 +514,7 @@
Original
Default
None (system default)
- Opposite Screen
+ Opposite Screen
Custom Layout
Background Color
The color which appears behind the screens during emulation, represented as an RGB value.
diff --git a/src/common/settings.h b/src/common/settings.h
index f4b29ee10..8de6ea457 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -62,7 +62,7 @@ enum class SecondaryDisplayLayout : u32 {
TopScreenOnly,
BottomScreenOnly,
SideBySide,
- OppositeScreenOnly,
+ ReversePrimaryScreen,
Original,
Hybrid,
LargeScreen
@@ -558,7 +558,7 @@ struct Values {
SwitchableSetting swap_screen{false, Keys::swap_screen};
SwitchableSetting upright_screen{false, Keys::upright_screen};
SwitchableSetting secondary_display_layout{
- SecondaryDisplayLayout::None, Keys::secondary_display_layout};
+ SecondaryDisplayLayout::ReversePrimaryScreen, Keys::secondary_display_layout};
SwitchableSetting> layouts_to_cycle{
{LayoutOption::Default, LayoutOption::SingleScreen, LayoutOption::LargeScreen,
LayoutOption::SideScreen,
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp
index 52ac1cfd9..948886aff 100644
--- a/src/core/frontend/framebuffer_layout.cpp
+++ b/src/core/frontend/framebuffer_layout.cpp
@@ -324,8 +324,8 @@ FramebufferLayout AndroidSecondaryLayout(u32 width, u32 height) {
return HybridScreenLayout(width, height, false, Settings::values.upright_screen.GetValue());
case Settings::SecondaryDisplayLayout::None:
// this should never happen - if "none" is set this method shouldn't run - but if it does,
- // somehow, use OppositeScreenOnly
- case Settings::SecondaryDisplayLayout::OppositeScreenOnly:
+ // somehow, use ReversePrimaryScreen
+ case Settings::SecondaryDisplayLayout::ReversePrimaryScreen:
default:
return SingleFrameLayout(width, height, !Settings::values.swap_screen.GetValue(),
Settings::values.upright_screen.GetValue());