diff --git a/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt index ba3856d9f..2d33d5cf7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt @@ -34,6 +34,7 @@ import org.citra.citra_emu.databinding.ActivityEmulationBinding import org.citra.citra_emu.display.ScreenAdjustmentUtil import org.citra.citra_emu.features.hotkeys.HotkeyUtility 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 import org.citra.citra_emu.features.settings.model.view.InputBindingSetting import org.citra.citra_emu.fragments.EmulationFragment @@ -75,7 +76,7 @@ class EmulationActivity : AppCompatActivity() { NativeLibrary.enableAdrenoTurboMode(BooleanSetting.ADRENO_GPU_BOOST.boolean) binding = ActivityEmulationBinding.inflate(layoutInflater) - screenAdjustmentUtil = ScreenAdjustmentUtil(windowManager, settingsViewModel.settings) + screenAdjustmentUtil = ScreenAdjustmentUtil(this, windowManager, settingsViewModel.settings) hotkeyUtility = HotkeyUtility(screenAdjustmentUtil, this) setContentView(binding.root) @@ -105,6 +106,8 @@ class EmulationActivity : AppCompatActivity() { isEmulationRunning = true instance = this + + applyOrientationSettings() // Check for orientation settings at startup } // On some devices, the system bars will not disappear on first boot or after some @@ -113,6 +116,7 @@ class EmulationActivity : AppCompatActivity() { override fun onResume() { super.onResume() enableFullscreenImmersive() + applyOrientationSettings() // Check for orientation settings changes on runtime } override fun onWindowFocusChanged(hasFocus: Boolean) { @@ -204,6 +208,11 @@ class EmulationActivity : AppCompatActivity() { } } + private fun applyOrientationSettings() { + val orientationOption = IntSetting.ORIENTATION_OPTION.int + screenAdjustmentUtil.changeActivityOrientation(orientationOption) + } + // Gets button presses @Suppress("DEPRECATION") @SuppressLint("GestureBackNavigation") 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 624363729..c80e79ec6 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 @@ -4,8 +4,12 @@ package org.citra.citra_emu.display +import android.content.Context +import android.content.pm.ActivityInfo +import android.app.Activity import android.view.WindowManager import org.citra.citra_emu.NativeLibrary +import org.citra.citra_emu.R 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.Settings @@ -13,8 +17,9 @@ import org.citra.citra_emu.features.settings.utils.SettingsFile import org.citra.citra_emu.utils.EmulationMenuSettings class ScreenAdjustmentUtil( + private val context: Context, private val windowManager: WindowManager, - private val settings: Settings + private val settings: Settings, ) { fun swapScreen() { val isEnabled = !EmulationMenuSettings.swapScreens @@ -27,21 +32,20 @@ class ScreenAdjustmentUtil( settings.saveSetting(BooleanSetting.SWAP_SCREEN, SettingsFile.FILE_NAME_CONFIG) } fun cycleLayouts() { - // TODO: figure out how to pull these from R.array - val landscape_values = intArrayOf(2,1,3,4,0,5); - val portrait_values = intArrayOf(0,1); - if (NativeLibrary.isPortraitMode) { - val current_layout = IntSetting.PORTRAIT_SCREEN_LAYOUT.int - val pos = portrait_values.indexOf(current_layout) - val layout_option = portrait_values[(pos + 1) % portrait_values.size] - changePortraitOrientation(layout_option) - } else { - val current_layout = IntSetting.SCREEN_LAYOUT.int - val pos = landscape_values.indexOf(current_layout) - val layout_option = landscape_values[(pos + 1) % landscape_values.size] - changeScreenOrientation(layout_option) - } + val landscapeValues = context.resources.getIntArray(R.array.landscapeValues) + val portraitValues = context.resources.getIntArray(R.array.portraitValues) + if (NativeLibrary.isPortraitMode) { + val currentLayout = IntSetting.PORTRAIT_SCREEN_LAYOUT.int + val pos = portraitValues.indexOf(currentLayout) + val layoutOption = portraitValues[(pos + 1) % portraitValues.size] + changePortraitOrientation(layoutOption) + } else { + val currentLayout = IntSetting.SCREEN_LAYOUT.int + val pos = landscapeValues.indexOf(currentLayout) + val layoutOption = landscapeValues[(pos + 1) % landscapeValues.size] + changeScreenOrientation(layoutOption) + } } fun changePortraitOrientation(layoutOption: Int) { @@ -57,4 +61,11 @@ class ScreenAdjustmentUtil( NativeLibrary.reloadSettings() NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) } + + fun changeActivityOrientation(orientationOption: Int) { + val activity = context as? Activity ?: return + IntSetting.ORIENTATION_OPTION.int = orientationOption + settings.saveSetting(IntSetting.ORIENTATION_OPTION, SettingsFile.FILE_NAME_CONFIG) + activity.requestedOrientation = orientationOption + } } 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 32483ad80..1a39c7c09 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 @@ -61,8 +61,8 @@ enum class IntSetting( TEXTURE_FILTER("texture_filter", Settings.SECTION_RENDERER, 0), USE_FRAME_LIMIT("use_frame_limit", Settings.SECTION_RENDERER, 1), DELAY_RENDER_THREAD_US("delay_game_render_thread_us", Settings.SECTION_RENDERER, 0), - USE_ARTIC_BASE_CONTROLLER("use_artic_base_controller", Settings.SECTION_CONTROLS, 0); - + USE_ARTIC_BASE_CONTROLLER("use_artic_base_controller", Settings.SECTION_CONTROLS, 0), + ORIENTATION_OPTION("screen_orientation", Settings.SECTION_LAYOUT, 2); override var int: Int = defaultValue override val valueAsString: String 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 265910036..76cbe0a0c 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 @@ -929,6 +929,17 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) private fun addLayoutSettings(sl: ArrayList) { settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_layout)) sl.apply { + add( + SingleChoiceSetting( + IntSetting.ORIENTATION_OPTION, + R.string.layout_screen_orientation, + 0, + R.array.screenOrientations, + R.array.screenOrientationValues, + IntSetting.ORIENTATION_OPTION.key, + IntSetting.ORIENTATION_OPTION.defaultValue + ) + ) add( SingleChoiceSetting( IntSetting.SCREEN_LAYOUT, 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 e989baec4..866940e66 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 @@ -146,8 +146,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram retainInstance = true emulationState = EmulationState(game.path) emulationActivity = requireActivity() as EmulationActivity - screenAdjustmentUtil = - ScreenAdjustmentUtil(emulationActivity.windowManager, settingsViewModel.settings) + screenAdjustmentUtil = ScreenAdjustmentUtil(requireContext(), requireActivity().windowManager, settingsViewModel.settings) EmulationLifecycleUtil.addShutdownHook(hook = { emulationState.stop() }) EmulationLifecycleUtil.addPauseResumeHook(hook = { togglePause() }) } diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h index 01242e978..455e3106f 100644 --- a/src/android/app/src/main/jni/default_ini.h +++ b/src/android/app/src/main/jni/default_ini.h @@ -206,6 +206,14 @@ custom_bottom_y = custom_bottom_width = custom_bottom_height = +# Orientation option for the emulator +# 2 (default): Automatic +# 0: Landscape +# 8: Landscape (Flipped) +# 1: Portrait +# 9: Portrait (Flipped) +screen_orientation = + # Layout for the portrait mode # 0 (default): Top and bottom screens at top, full width # 1: Custom Layout diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index c6baf68a2..a732ca920 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -530,4 +530,32 @@ 12 + + 2 + 1 + 3 + 4 + 0 + 5 + + + 0 + 1 + + + + @string/layout_screen_orientation_auto_sensor + @string/layout_screen_orientation_landscape + @string/layout_screen_orientation_landscape_reverse + @string/layout_screen_orientation_portrait + @string/layout_screen_orientation_portrait_reverse + + + 2 + 0 + 8 + 1 + 9 + + diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index f0f8c20fe..d87c217e4 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -291,6 +291,14 @@ Audio Input Device Sound Output Mode + + Screen Orientation + Automatic + Landscape + Reverse Landscape + Portrait + Reverse Portrait + Clear Default @@ -338,6 +346,7 @@ Debug Theme and Color Layout + Your ROM is Encrypted Invalid ROM format