mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-01 01:05:08 +01:00
Implement fixed aspect ratio surface
Adds a setting to letterbox the surface with black bars to 16:9 or 21:9 aspect ratio to avoid stretching out the rendered image
This commit is contained in:
parent
6cf9bc5729
commit
0ceecbba4f
@ -12,6 +12,7 @@ import android.content.res.AssetManager
|
||||
import android.graphics.PointF
|
||||
import android.os.*
|
||||
import android.util.Log
|
||||
import android.util.Rational
|
||||
import android.view.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.isGone
|
||||
@ -221,9 +222,6 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
returnFromEmulation()
|
||||
}
|
||||
|
||||
/**
|
||||
* This makes the window fullscreen, sets up the performance statistics and finally calls [executeApplication] for executing the application
|
||||
*/
|
||||
@SuppressLint("SetTextI18n", "ClickableViewAccessibility")
|
||||
override fun onCreate(savedInstanceState : Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -237,6 +235,14 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
|
||||
|
||||
binding.gameView.holder.addCallback(this)
|
||||
|
||||
binding.gameView.setAspectRatio(
|
||||
when (settings.aspectRatio) {
|
||||
0 -> Rational(16, 9)
|
||||
1 -> Rational(21, 9)
|
||||
else -> null
|
||||
}
|
||||
)
|
||||
|
||||
if (settings.perfStats) {
|
||||
binding.perfStats.apply {
|
||||
postDelayed(object : Runnable {
|
||||
|
@ -38,5 +38,7 @@ class Settings @Inject constructor(@ApplicationContext private val context : Con
|
||||
|
||||
var maxRefreshRate by sharedPreferences(context, false)
|
||||
|
||||
var aspectRatio by sharedPreferences(context, 0)
|
||||
|
||||
var systemLanguage by sharedPreferences(context, 1)
|
||||
}
|
||||
|
39
app/src/main/java/emu/skyline/views/FixedRatioSurfaceView.kt
Normal file
39
app/src/main/java/emu/skyline/views/FixedRatioSurfaceView.kt
Normal file
@ -0,0 +1,39 @@
|
||||
package emu.skyline.views
|
||||
|
||||
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, attrs : AttributeSet? = null, defStyleAttr : Int = 0) : SurfaceView(context, attrs, defStyleAttr) {
|
||||
private var aspectRatio : Float = 0f // (width / height), 0f is a special value for stretch
|
||||
|
||||
/**
|
||||
* Sets the desired aspect ratio for this view
|
||||
* @param ratio the ratio to force the view to, or null to stretch to fit
|
||||
*/
|
||||
fun setAspectRatio(ratio : Rational?) {
|
||||
aspectRatio = ratio?.toFloat() ?: 0f
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec : Int, heightMeasureSpec : Int) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
val width = MeasureSpec.getSize(widthMeasureSpec)
|
||||
val height = MeasureSpec.getSize(heightMeasureSpec)
|
||||
if (aspectRatio != 0f) {
|
||||
val newWidth : Int
|
||||
val newHeight : Int
|
||||
if (height * aspectRatio < width) {
|
||||
newWidth = (height * aspectRatio).roundToInt()
|
||||
newHeight = height
|
||||
} else {
|
||||
newWidth = width
|
||||
newHeight = (width / aspectRatio).roundToInt()
|
||||
}
|
||||
setMeasuredDimension(newWidth, newHeight)
|
||||
} else {
|
||||
setMeasuredDimension(width, height)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,39 +1,39 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true"
|
||||
android:background="@android:color/black"
|
||||
tools:context=".EmulationActivity">
|
||||
|
||||
<emu.skyline.views.FixedRatioSurfaceView
|
||||
android:id="@+id/game_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true"
|
||||
tools:background="@android:color/black"
|
||||
tools:context=".EmulationActivity">
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/game_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:visibility="invisible" />
|
||||
android:layout_gravity="center" />
|
||||
|
||||
<emu.skyline.input.onscreen.OnScreenControllerView
|
||||
android:id="@+id/on_screen_controller_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
android:id="@+id/on_screen_controller_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/perf_stats"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textColor="#9fffff00" />
|
||||
android:id="@+id/perf_stats"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:textColor="#9fffff00" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/on_screen_controller_toggle"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_show"
|
||||
app:tint="#40FFFFFF"
|
||||
tools:ignore="ContentDescription" />
|
||||
android:id="@+id/on_screen_controller_toggle"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:src="@drawable/ic_show"
|
||||
app:tint="#40FFFFFF"
|
||||
tools:ignore="ContentDescription" />
|
||||
</FrameLayout>
|
||||
|
@ -74,4 +74,9 @@
|
||||
<item>7</item>
|
||||
<item>11</item>
|
||||
</integer-array>
|
||||
<string-array name="aspect_ratios">
|
||||
<item>16:9 (Switch, Recommended)</item>
|
||||
<item>21:9 (Ultrawide Mods)</item>
|
||||
<item>Device Aspect Ratio (Stretch to fit)</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
|
@ -61,6 +61,7 @@
|
||||
<string name="max_refresh_rate">Use Maximum Display Refresh Rate</string>
|
||||
<string name="max_refresh_rate_enabled">Sets the display refresh rate as high as possible (Will break most games)</string>
|
||||
<string name="max_refresh_rate_disabled">Sets the display refresh rate to 60Hz</string>
|
||||
<string name="aspect_ratio">Aspect Ratio</string>
|
||||
<!-- Input -->
|
||||
<string name="input">Input</string>
|
||||
<string name="osc">On-Screen Controls</string>
|
||||
|
@ -103,6 +103,12 @@
|
||||
android:summaryOn="@string/max_refresh_rate_enabled"
|
||||
app:key="max_refresh_rate"
|
||||
app:title="@string/max_refresh_rate" />
|
||||
<emu.skyline.preference.IntegerListPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/aspect_ratios"
|
||||
app:key="aspect_ratio"
|
||||
app:title="@string/aspect_ratio"
|
||||
app:useSimpleSummaryProvider="true" />
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:key="category_input"
|
||||
|
Loading…
Reference in New Issue
Block a user