From 338d6f29b112803f1c2fa8ce985c646e51ee76e8 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Sun, 27 Aug 2023 00:16:53 -0400 Subject: [PATCH] android: Properly adjust emulation surface aspect ratio Previously the emulation surface wouldn't respond properly to orientation changes. This would result in the screen appearing stretched when starting in one orientation and switching to another. The code for calculating the bounds of the view have been changed to match the expected behavior now. Before the view would just match parent in height and width. Now instead of using setLeftTopRightBottom (which is intended to be used for animations) we pass newly calculated bounds for the view into super. Now the view bounds match the emulation output. This also means that we don't need the overload for the SettingsActivity to launch it using an ActivityResultLauncher. We can just update the view in onResume. --- .../features/settings/ui/SettingsActivity.kt | 13 ----- .../yuzu_emu/fragments/EmulationFragment.kt | 17 +------ .../yuzu_emu/views/FixedRatioSurfaceView.kt | 48 ++++++++++++------- 3 files changed, 33 insertions(+), 45 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt index a5af5a7aec..e6fffc8328 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt @@ -11,7 +11,6 @@ import android.view.View import android.view.ViewGroup.MarginLayoutParams import android.widget.Toast import androidx.activity.OnBackPressedCallback -import androidx.activity.result.ActivityResultLauncher import androidx.activity.viewModels import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat @@ -246,17 +245,5 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { settings.putExtra(ARG_GAME_ID, gameId) context.startActivity(settings) } - - fun launch( - context: Context, - launcher: ActivityResultLauncher, - 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) - } } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt index 25b9d4018a..09e93a017e 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt @@ -7,7 +7,6 @@ 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 @@ -19,8 +18,6 @@ import android.util.Rational 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.res.ResourcesCompat import androidx.core.graphics.Insets @@ -66,8 +63,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { private var isInFoldableLayout = false - private lateinit var onReturnFromSettings: ActivityResultLauncher - override fun onAttach(context: Context) { super.onAttach(context) if (context is EmulationActivity) { @@ -81,11 +76,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { .collect { updateFoldableLayout(context, it) } } } - - onReturnFromSettings = context.activityResultRegistry.register( - "SettingsResult", - ActivityResultContracts.StartActivityForResult() - ) { updateScreenLayout() } } else { throw IllegalStateException("EmulationFragment must have EmulationActivity parent") } @@ -149,12 +139,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { } R.id.menu_settings -> { - SettingsActivity.launch( - requireContext(), - onReturnFromSettings, - SettingsFile.FILE_NAME_CONFIG, - "" - ) + SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "") true } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/FixedRatioSurfaceView.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/FixedRatioSurfaceView.kt index 685ccaa76e..2f0868c633 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/FixedRatioSurfaceView.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/views/FixedRatioSurfaceView.kt @@ -7,7 +7,6 @@ import android.content.Context import android.util.AttributeSet import android.util.Rational import android.view.SurfaceView -import kotlin.math.roundToInt class FixedRatioSurfaceView @JvmOverloads constructor( context: Context, @@ -22,27 +21,44 @@ class FixedRatioSurfaceView @JvmOverloads constructor( */ fun setAspectRatio(ratio: Rational?) { aspectRatio = ratio?.toFloat() ?: 0f + requestLayout() } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec) - val width = MeasureSpec.getSize(widthMeasureSpec) - val height = MeasureSpec.getSize(heightMeasureSpec) + val displayWidth: Float = MeasureSpec.getSize(widthMeasureSpec).toFloat() + val displayHeight: Float = MeasureSpec.getSize(heightMeasureSpec).toFloat() if (aspectRatio != 0f) { - val newWidth: Int - val newHeight: Int - if (height * aspectRatio < width) { - newWidth = (height * aspectRatio).roundToInt() - newHeight = height + val displayAspect = displayWidth / displayHeight + if (displayAspect < aspectRatio) { + // Max out width + val halfHeight = displayHeight / 2 + val surfaceHeight = displayWidth / aspectRatio + val newTop: Float = halfHeight - (surfaceHeight / 2) + val newBottom: Float = halfHeight + (surfaceHeight / 2) + super.onMeasure( + widthMeasureSpec, + MeasureSpec.makeMeasureSpec( + newBottom.toInt() - newTop.toInt(), + MeasureSpec.EXACTLY + ) + ) + return } else { - newWidth = width - newHeight = (width / aspectRatio).roundToInt() + // Max out height + val halfWidth = displayWidth / 2 + val surfaceWidth = displayHeight * aspectRatio + val newLeft: Float = halfWidth - (surfaceWidth / 2) + val newRight: Float = halfWidth + (surfaceWidth / 2) + super.onMeasure( + MeasureSpec.makeMeasureSpec( + newRight.toInt() - newLeft.toInt(), + MeasureSpec.EXACTLY + ), + heightMeasureSpec + ) + return } - val left = (width - newWidth) / 2 - val top = (height - newHeight) / 2 - setLeftTopRightBottom(left, top, left + newWidth, top + newHeight) - } else { - setLeftTopRightBottom(0, 0, width, height) } + super.onMeasure(widthMeasureSpec, heightMeasureSpec) } }