android: Add settings for variable orientation
This commit is contained in:
parent
4c3d0b9c23
commit
1afc9f2093
9 changed files with 123 additions and 51 deletions
|
@ -31,7 +31,6 @@ import android.view.View
|
|||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
|
@ -45,11 +44,11 @@ import org.yuzu.yuzu_emu.NativeLibrary
|
|||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel
|
||||
import org.yuzu.yuzu_emu.fragments.EmulationFragment
|
||||
import org.yuzu.yuzu_emu.model.Game
|
||||
import org.yuzu.yuzu_emu.utils.ControllerMappingHelper
|
||||
import org.yuzu.yuzu_emu.utils.EmulationMenuSettings
|
||||
import org.yuzu.yuzu_emu.utils.ForegroundService
|
||||
import org.yuzu.yuzu_emu.utils.InputHandler
|
||||
import org.yuzu.yuzu_emu.utils.NfcReader
|
||||
|
@ -163,8 +162,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
|||
startMotionSensorListener()
|
||||
|
||||
NativeLibrary.notifyOrientationChange(
|
||||
EmulationMenuSettings.landscapeScreenLayout,
|
||||
getAdjustedRotation()
|
||||
Settings.LayoutOption_MobileLandscape,
|
||||
Surface.ROTATION_90
|
||||
)
|
||||
|
||||
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
|
||||
|
@ -288,23 +287,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
|||
|
||||
override fun onAccuracyChanged(sensor: Sensor, i: Int) {}
|
||||
|
||||
private fun getAdjustedRotation():Int {
|
||||
val rotation = getSystemService<DisplayManager>()!!.getDisplay(Display.DEFAULT_DISPLAY).rotation
|
||||
val config: Configuration = resources.configuration
|
||||
|
||||
if ((config.screenLayout and Configuration.SCREENLAYOUT_LONG_YES) != 0 ||
|
||||
(config.screenLayout and Configuration.SCREENLAYOUT_LONG_NO) == 0) {
|
||||
return rotation
|
||||
}
|
||||
when (rotation) {
|
||||
Surface.ROTATION_0 -> return Surface.ROTATION_90
|
||||
Surface.ROTATION_90 -> return Surface.ROTATION_0
|
||||
Surface.ROTATION_180 -> return Surface.ROTATION_270
|
||||
Surface.ROTATION_270 -> return Surface.ROTATION_180
|
||||
}
|
||||
return rotation
|
||||
}
|
||||
|
||||
private fun restoreState(savedInstanceState: Bundle) {
|
||||
game = savedInstanceState.parcelable(EXTRA_SELECTED_GAME)!!
|
||||
}
|
||||
|
@ -354,15 +336,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
|
|||
return this.apply { setActions(pictureInPictureActions) }
|
||||
}
|
||||
|
||||
fun setPictureInPictureParamsExternal() {
|
||||
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
|
||||
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
pictureInPictureParamsBuilder.setAutoEnterEnabled(BooleanSetting.PICTURE_IN_PICTURE.boolean)
|
||||
}
|
||||
setPictureInPictureParams(pictureInPictureParamsBuilder.build())
|
||||
}
|
||||
|
||||
private var pictureInPictureReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context : Context?, intent : Intent) {
|
||||
if (intent.action == actionPlay) {
|
||||
|
|
|
@ -88,6 +88,11 @@ enum class IntSetting(
|
|||
Settings.SECTION_RENDERER,
|
||||
0
|
||||
),
|
||||
RENDERER_SCREEN_LAYOUT(
|
||||
"screen_layout",
|
||||
Settings.SECTION_RENDERER,
|
||||
Settings.LayoutOption_MobileLandscape
|
||||
),
|
||||
RENDERER_ASPECT_RATIO(
|
||||
"aspect_ratio",
|
||||
Settings.SECTION_RENDERER,
|
||||
|
|
|
@ -133,7 +133,6 @@ class Settings {
|
|||
const val PREF_MENU_SETTINGS_JOYSTICK_REL_CENTER = "EmulationMenuSettings_JoystickRelCenter"
|
||||
const val PREF_MENU_SETTINGS_DPAD_SLIDE = "EmulationMenuSettings_DpadSlideEnable"
|
||||
const val PREF_MENU_SETTINGS_HAPTICS = "EmulationMenuSettings_Haptics"
|
||||
const val PREF_MENU_SETTINGS_LANDSCAPE = "EmulationMenuSettings_LandscapeScreenLayout"
|
||||
const val PREF_MENU_SETTINGS_SHOW_FPS = "EmulationMenuSettings_ShowFps"
|
||||
const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay"
|
||||
|
||||
|
@ -144,6 +143,14 @@ class Settings {
|
|||
|
||||
private val configFileSectionsMap: MutableMap<String, List<String>> = HashMap()
|
||||
|
||||
// These must match what is defined in src/core/settings.h
|
||||
const val LayoutOption_Default = 0
|
||||
const val LayoutOption_SingleScreen = 1
|
||||
const val LayoutOption_LargeScreen = 2
|
||||
const val LayoutOption_SideScreen = 3
|
||||
const val LayoutOption_MobilePortrait = 4
|
||||
const val LayoutOption_MobileLandscape = 5
|
||||
|
||||
init {
|
||||
configFileSectionsMap[SettingsFile.FILE_NAME_CONFIG] =
|
||||
listOf(
|
||||
|
|
|
@ -16,6 +16,7 @@ import androidx.core.view.WindowCompat
|
|||
import androidx.core.view.WindowInsetsCompat
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.core.view.updatePadding
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
|
@ -239,5 +240,12 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
|||
settings.putExtra(ARG_GAME_ID, gameId)
|
||||
context.startActivity(settings)
|
||||
}
|
||||
|
||||
fun launch(context: Context, launcher: ActivityResultLauncher<Intent>, menuTag: String?, gameId: String?) {
|
||||
val settings = Intent(context, SettingsActivity::class.java)
|
||||
settings.putExtra(ARG_MENU_TAG, menuTag)
|
||||
settings.putExtra(ARG_GAME_ID, gameId)
|
||||
launcher.launch(settings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -292,6 +292,17 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
IntSetting.RENDERER_ANTI_ALIASING.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_SCREEN_LAYOUT,
|
||||
R.string.renderer_screen_layout,
|
||||
0,
|
||||
R.array.rendererScreenLayoutNames,
|
||||
R.array.rendererScreenLayoutValues,
|
||||
IntSetting.RENDERER_SCREEN_LAYOUT.key,
|
||||
IntSetting.RENDERER_SCREEN_LAYOUT.defaultValue
|
||||
)
|
||||
)
|
||||
add(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_ASPECT_RATIO,
|
||||
|
|
|
@ -7,10 +7,13 @@ import android.annotation.SuppressLint
|
|||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.hardware.display.DisplayManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
|
@ -18,7 +21,10 @@ import android.util.TypedValue
|
|||
import android.view.*
|
||||
import android.widget.TextView
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.ViewCompat
|
||||
|
@ -37,6 +43,7 @@ import org.yuzu.yuzu_emu.YuzuApplication
|
|||
import org.yuzu.yuzu_emu.activities.EmulationActivity
|
||||
import org.yuzu.yuzu_emu.databinding.DialogOverlayAdjustBinding
|
||||
import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
|
||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||
|
@ -55,11 +62,19 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
|
||||
private lateinit var game: Game
|
||||
|
||||
private lateinit var onReturnFromSettings: ActivityResultLauncher<Intent>
|
||||
|
||||
override fun onAttach(context: Context) {
|
||||
super.onAttach(context)
|
||||
if (context is EmulationActivity) {
|
||||
emulationActivity = context
|
||||
NativeLibrary.setEmulationActivity(context)
|
||||
|
||||
onReturnFromSettings = context.activityResultRegistry.register(
|
||||
"SettingsResult", ActivityResultContracts.StartActivityForResult()
|
||||
) {
|
||||
updateScreenLayout()
|
||||
}
|
||||
} else {
|
||||
throw IllegalStateException("EmulationFragment must have EmulationActivity parent")
|
||||
}
|
||||
|
@ -124,7 +139,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
}
|
||||
|
||||
R.id.menu_settings -> {
|
||||
SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "")
|
||||
SettingsActivity.launch(
|
||||
requireContext(), onReturnFromSettings, SettingsFile.FILE_NAME_CONFIG, ""
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -179,6 +196,38 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
super.onDetach()
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
|
||||
val emulatorLayout = when (newConfig.orientation) {
|
||||
Configuration.ORIENTATION_LANDSCAPE -> { Settings.LayoutOption_MobileLandscape }
|
||||
Configuration.ORIENTATION_PORTRAIT -> { Settings.LayoutOption_MobilePortrait }
|
||||
else -> { Settings.LayoutOption_MobilePortrait }
|
||||
}
|
||||
|
||||
emulationActivity?.let {
|
||||
var rotation = it.getSystemService<DisplayManager>()!!
|
||||
.getDisplay(Display.DEFAULT_DISPLAY).rotation
|
||||
if (it.isInPictureInPictureMode) {
|
||||
NativeLibrary.notifyOrientationChange(
|
||||
Settings.LayoutOption_MobileLandscape,
|
||||
Surface.ROTATION_90
|
||||
)
|
||||
} else {
|
||||
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
|
||||
rotation = when (rotation) {
|
||||
Surface.ROTATION_0 -> Surface.ROTATION_90
|
||||
Surface.ROTATION_90 -> Surface.ROTATION_0
|
||||
Surface.ROTATION_180 -> Surface.ROTATION_270
|
||||
Surface.ROTATION_270 -> Surface.ROTATION_180
|
||||
else -> { rotation }
|
||||
}
|
||||
}
|
||||
NativeLibrary.notifyOrientationChange(emulatorLayout, rotation)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun isEmulationStatePaused() : Boolean {
|
||||
return this::emulationState.isInitialized && emulationState.isPaused
|
||||
}
|
||||
|
@ -249,6 +298,25 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressLint("SourceLockedOrientationActivity")
|
||||
private fun updateScreenLayout() {
|
||||
emulationActivity?.let {
|
||||
when (IntSetting.RENDERER_SCREEN_LAYOUT.int) {
|
||||
Settings.LayoutOption_MobileLandscape -> {
|
||||
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE
|
||||
}
|
||||
Settings.LayoutOption_MobilePortrait -> {
|
||||
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT
|
||||
}
|
||||
Settings.LayoutOption_Default -> {
|
||||
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
|
||||
}
|
||||
else -> { it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE }
|
||||
}
|
||||
onConfigurationChanged(resources.configuration)
|
||||
}
|
||||
}
|
||||
|
||||
private val Number.toPx get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), Resources.getSystem().displayMetrics).toInt()
|
||||
|
||||
fun updateCurrentLayout(emulationActivity: EmulationActivity, newLayoutInfo: WindowLayoutInfo) {
|
||||
|
@ -269,7 +337,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
binding.inGameMenu.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
binding.overlayContainer.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
binding.overlayContainer.updatePadding(0, 0, 0, 0)
|
||||
emulationActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
||||
updateScreenLayout()
|
||||
}
|
||||
binding.surfaceInputOverlay.requestLayout()
|
||||
binding.inGameMenu.requestLayout()
|
||||
|
|
|
@ -11,14 +11,6 @@ object EmulationMenuSettings {
|
|||
private val preferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
|
||||
// These must match what is defined in src/core/settings.h
|
||||
const val LayoutOption_Default = 0
|
||||
const val LayoutOption_SingleScreen = 1
|
||||
const val LayoutOption_LargeScreen = 2
|
||||
const val LayoutOption_SideScreen = 3
|
||||
const val LayoutOption_MobilePortrait = 4
|
||||
const val LayoutOption_MobileLandscape = 5
|
||||
|
||||
var joystickRelCenter: Boolean
|
||||
get() = preferences.getBoolean(Settings.PREF_MENU_SETTINGS_JOYSTICK_REL_CENTER, true)
|
||||
set(value) {
|
||||
|
@ -41,16 +33,6 @@ object EmulationMenuSettings {
|
|||
.apply()
|
||||
}
|
||||
|
||||
var landscapeScreenLayout: Int
|
||||
get() = preferences.getInt(
|
||||
Settings.PREF_MENU_SETTINGS_LANDSCAPE,
|
||||
LayoutOption_MobileLandscape
|
||||
)
|
||||
set(value) {
|
||||
preferences.edit()
|
||||
.putInt(Settings.PREF_MENU_SETTINGS_LANDSCAPE, value)
|
||||
.apply()
|
||||
}
|
||||
var showFps: Boolean
|
||||
get() = preferences.getBoolean(Settings.PREF_MENU_SETTINGS_SHOW_FPS, false)
|
||||
set(value) {
|
||||
|
|
|
@ -119,6 +119,18 @@
|
|||
<item>3</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="rendererScreenLayoutNames">
|
||||
<item>@string/screen_layout_landscape</item>
|
||||
<item>@string/screen_layout_portrait</item>
|
||||
<item>@string/screen_layout_auto</item>
|
||||
</string-array>
|
||||
|
||||
<integer-array name="rendererScreenLayoutValues">
|
||||
<item>5</item>
|
||||
<item>4</item>
|
||||
<item>0</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="rendererAspectRatioNames">
|
||||
<item>@string/ratio_default</item>
|
||||
<item>@string/ratio_force_four_three</item>
|
||||
|
|
|
@ -156,6 +156,7 @@
|
|||
<string name="renderer_accuracy">Accuracy level</string>
|
||||
<string name="renderer_resolution">Resolution (Handheld/Docked)</string>
|
||||
<string name="renderer_vsync">VSync mode</string>
|
||||
<string name="renderer_screen_layout">Orientation</string>
|
||||
<string name="renderer_aspect_ratio">Aspect ratio</string>
|
||||
<string name="renderer_scaling_filter">Window adapting filter</string>
|
||||
<string name="renderer_anti_aliasing">Anti-aliasing method</string>
|
||||
|
@ -318,6 +319,11 @@
|
|||
<string name="anti_aliasing_fxaa">FXAA</string>
|
||||
<string name="anti_aliasing_smaa">SMAA</string>
|
||||
|
||||
<!-- Screen Layouts -->
|
||||
<string name="screen_layout_landscape">Landscape</string>
|
||||
<string name="screen_layout_portrait">Portrait</string>
|
||||
<string name="screen_layout_auto">Auto</string>
|
||||
|
||||
<!-- Aspect Ratios -->
|
||||
<string name="ratio_default">Default (16:9)</string>
|
||||
<string name="ratio_force_four_three">Force 4:3</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue