Merge branch 'pr-25' into purple
This commit is contained in:
commit
a98ac705e4
15 changed files with 464 additions and 149 deletions
|
@ -31,9 +31,16 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
|||
SHOW_THERMAL_OVERLAY("show_thermal_overlay"),
|
||||
FRAME_INTERPOLATION("frame_interpolation"),
|
||||
FRAME_SKIPPING("frame_skipping");
|
||||
|
||||
external fun isFrameSkippingEnabled(): Boolean
|
||||
external fun isFrameInterpolationEnabled(): Boolean
|
||||
SHOW_FPS("show_fps"),
|
||||
SHOW_FRAMETIME("show_frame_time"),
|
||||
SHOW_SPEED("show_speed"),
|
||||
SHOW_APP_RAM_USAGE("show_app_ram_usage"),
|
||||
SHOW_SYSTEM_RAM_USAGE("show_system_ram_usage"),
|
||||
SHOW_BAT_TEMPERATURE("show_bat_temperature"),
|
||||
OVERLAY_BACKGROUND("overlay_background"),;
|
||||
|
||||
|
||||
override fun getBoolean(needsGlobal: Boolean): Boolean =
|
||||
NativeConfig.getBoolean(key, needsGlobal)
|
||||
|
|
|
@ -32,6 +32,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
|
|||
OVERLAY_OPACITY("control_opacity"),
|
||||
LOCK_DRAWER("lock_drawer"),
|
||||
VERTICAL_ALIGNMENT("vertical_alignment"),
|
||||
PERF_OVERLAY_POSITION("perf_overlay_position"),
|
||||
FSR_SHARPENING_SLIDER("fsr_sharpening_slider");
|
||||
|
||||
override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)
|
||||
|
|
|
@ -12,6 +12,7 @@ object Settings {
|
|||
SECTION_ROOT(R.string.advanced_settings),
|
||||
SECTION_SYSTEM(R.string.preferences_system),
|
||||
SECTION_RENDERER(R.string.preferences_graphics),
|
||||
SECTION_PERFORMANCE_STATS(R.string.show_stats_overlay),
|
||||
SECTION_AUDIO(R.string.preferences_audio),
|
||||
SECTION_INPUT(R.string.preferences_controls),
|
||||
SECTION_INPUT_PLAYER_ONE,
|
||||
|
@ -33,6 +34,7 @@ object Settings {
|
|||
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
|
||||
const val PREF_SHOULD_SHOW_PRE_ALPHA_WARNING = "ShouldShowPreAlphaWarning"
|
||||
const val PREF_MEMORY_WARNING_SHOWN = "MemoryWarningShown"
|
||||
const val SECTION_STATS_OVERLAY = "Stats Overlay"
|
||||
|
||||
// Deprecated input overlay preference keys
|
||||
const val PREF_CONTROL_SCALE = "controlScale"
|
||||
|
|
|
@ -337,6 +337,71 @@ abstract class SettingsItem(
|
|||
valuesId = R.array.rendererResolutionValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_PERFORMANCE_OVERLAY,
|
||||
R.string.enable_stats_overlay_,
|
||||
descriptionId = R.string.stats_overlay_options_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.OVERLAY_BACKGROUND,
|
||||
R.string.overlay_background,
|
||||
descriptionId = R.string.overlay_background_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.PERF_OVERLAY_POSITION,
|
||||
titleId = R.string.overlay_position,
|
||||
descriptionId = R.string.overlay_position_description,
|
||||
choicesId = R.array.statsPosition,
|
||||
valuesId = R.array.staticThemeValues
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_FPS,
|
||||
R.string.show_fps,
|
||||
descriptionId = R.string.show_fps_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_FRAMETIME,
|
||||
R.string.show_frametime,
|
||||
descriptionId = R.string.show_frametime_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_SPEED,
|
||||
R.string.show_speed,
|
||||
descriptionId = R.string.show_speed_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_APP_RAM_USAGE,
|
||||
R.string.show_app_ram_usage,
|
||||
descriptionId = R.string.show_app_ram_usage_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_SYSTEM_RAM_USAGE,
|
||||
R.string.show_system_ram_usage,
|
||||
descriptionId = R.string.show_system_ram_usage_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SwitchSetting(
|
||||
BooleanSetting.SHOW_BAT_TEMPERATURE,
|
||||
R.string.show_bat_temperature,
|
||||
descriptionId = R.string.show_bat_temperature_description
|
||||
)
|
||||
)
|
||||
put(
|
||||
SingleChoiceSetting(
|
||||
IntSetting.RENDERER_VSYNC,
|
||||
|
|
|
@ -88,6 +88,7 @@ class SettingsFragmentPresenter(
|
|||
MenuTag.SECTION_ROOT -> addConfigSettings(sl)
|
||||
MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
|
||||
MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
|
||||
MenuTag.SECTION_PERFORMANCE_STATS -> addPerfomanceOverlaySettings(sl)
|
||||
MenuTag.SECTION_AUDIO -> addAudioSettings(sl)
|
||||
MenuTag.SECTION_INPUT -> addInputSettings(sl)
|
||||
MenuTag.SECTION_INPUT_PLAYER_ONE -> addInputPlayer(sl, 0)
|
||||
|
@ -128,6 +129,15 @@ class SettingsFragmentPresenter(
|
|||
menuKey = MenuTag.SECTION_RENDERER
|
||||
)
|
||||
)
|
||||
if (!NativeConfig.isPerGameConfigLoaded())
|
||||
add(
|
||||
SubmenuSetting(
|
||||
titleId = R.string.stats_overlay_options,
|
||||
descriptionId = R.string.stats_overlay_options_description,
|
||||
iconId = R.drawable.ic_frames,
|
||||
menuKey = MenuTag.SECTION_PERFORMANCE_STATS
|
||||
)
|
||||
)
|
||||
add(
|
||||
SubmenuSetting(
|
||||
titleId = R.string.preferences_audio,
|
||||
|
@ -277,6 +287,23 @@ class SettingsFragmentPresenter(
|
|||
}
|
||||
}
|
||||
|
||||
private fun addPerfomanceOverlaySettings(sl: ArrayList<SettingsItem>) {
|
||||
sl.apply {
|
||||
add(HeaderSetting(R.string.stats_overlay_customization))
|
||||
add(BooleanSetting.SHOW_PERFORMANCE_OVERLAY.key)
|
||||
add(BooleanSetting.OVERLAY_BACKGROUND.key)
|
||||
add(IntSetting.PERF_OVERLAY_POSITION.key)
|
||||
add(HeaderSetting(R.string.stats_overlay_items))
|
||||
add(BooleanSetting.SHOW_FPS.key)
|
||||
add(BooleanSetting.SHOW_FRAMETIME.key)
|
||||
add(BooleanSetting.SHOW_SPEED.key)
|
||||
add(BooleanSetting.SHOW_APP_RAM_USAGE.key)
|
||||
add(BooleanSetting.SHOW_SYSTEM_RAM_USAGE.key)
|
||||
add(BooleanSetting.SHOW_BAT_TEMPERATURE.key)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun addAudioSettings(sl: ArrayList<SettingsItem>) {
|
||||
sl.apply {
|
||||
add(IntSetting.AUDIO_OUTPUT_ENGINE.key)
|
||||
|
|
|
@ -4,18 +4,29 @@
|
|||
package org.yuzu.yuzu_emu.fragments
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.ActivityManager
|
||||
import android.app.AlertDialog
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.ActivityInfo
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.BatteryManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.SystemClock
|
||||
import android.util.Rational
|
||||
import android.view.*
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.Surface
|
||||
import android.view.SurfaceHolder
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
|
@ -26,7 +37,6 @@ import androidx.core.graphics.Insets
|
|||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.drawerlayout.widget.DrawerLayout.DrawerListener
|
||||
import androidx.fragment.app.Fragment
|
||||
|
@ -36,6 +46,7 @@ import androidx.navigation.fragment.navArgs
|
|||
import androidx.window.layout.FoldingFeature
|
||||
import androidx.window.layout.WindowInfoTracker
|
||||
import androidx.window.layout.WindowLayoutInfo
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.slider.Slider
|
||||
import org.yuzu.yuzu_emu.HomeNavigationDirections
|
||||
|
@ -51,28 +62,28 @@ import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationOrientation
|
|||
import org.yuzu.yuzu_emu.features.settings.model.Settings.EmulationVerticalAlignment
|
||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||
import org.yuzu.yuzu_emu.model.DriverViewModel
|
||||
import org.yuzu.yuzu_emu.model.Game
|
||||
import org.yuzu.yuzu_emu.model.EmulationViewModel
|
||||
import org.yuzu.yuzu_emu.model.Game
|
||||
import org.yuzu.yuzu_emu.overlay.model.OverlayControl
|
||||
import org.yuzu.yuzu_emu.overlay.model.OverlayLayout
|
||||
import org.yuzu.yuzu_emu.utils.*
|
||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
|
||||
import org.yuzu.yuzu_emu.utils.FileUtil
|
||||
import org.yuzu.yuzu_emu.utils.GameHelper
|
||||
import org.yuzu.yuzu_emu.utils.GameIconUtils
|
||||
import org.yuzu.yuzu_emu.utils.Log
|
||||
import org.yuzu.yuzu_emu.utils.NativeConfig
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils
|
||||
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
|
||||
import java.lang.NullPointerException
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.BatteryManager
|
||||
import android.util.TypedValue
|
||||
import android.app.ActivityManager
|
||||
import android.graphics.Color
|
||||
import android.os.Debug
|
||||
import org.yuzu.yuzu_emu.utils.collect
|
||||
import java.io.File
|
||||
|
||||
class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||
private lateinit var emulationState: EmulationState
|
||||
private var emulationActivity: EmulationActivity? = null
|
||||
private var perfStatsUpdater: (() -> Unit)? = null
|
||||
private var thermalStatsUpdater: (() -> Unit)? = null
|
||||
private var batteryReceiverRegistered: Boolean = false
|
||||
private lateinit var cpuBackend: String
|
||||
private lateinit var gpuDriver: String
|
||||
|
||||
|
||||
private var _binding: FragmentEmulationBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
@ -198,8 +209,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
}
|
||||
})
|
||||
binding.drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
binding.inGameMenu.getHeaderView(0).findViewById<TextView>(R.id.text_game_title).text =
|
||||
game.title
|
||||
binding.inGameMenu.getHeaderView(0).apply {
|
||||
val titleView = findViewById<TextView>(R.id.text_game_title)
|
||||
titleView.text = game.title
|
||||
}
|
||||
|
||||
binding.inGameMenu.menu.findItem(R.id.menu_lock_drawer).apply {
|
||||
val lockMode = IntSetting.LOCK_DRAWER.getInt()
|
||||
|
@ -375,9 +388,23 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
emulationState.updateSurface()
|
||||
|
||||
// Setup overlays
|
||||
updateShowFpsOverlay()
|
||||
val temperature = getBatteryTemperature(requireContext())
|
||||
updateThermalOverlay(temperature)
|
||||
updateshowStatsOvelray()
|
||||
|
||||
// Re update binding when the specs values get initialized properly
|
||||
binding.inGameMenu.getHeaderView(0).apply {
|
||||
val titleView = findViewById<TextView>(R.id.text_game_title)
|
||||
val cpuBackendLabel = findViewById<TextView>(R.id.cpu_backend)
|
||||
val gpuvendorLabel = findViewById<TextView>(R.id.gpu_vendor)
|
||||
|
||||
titleView.text = game.title
|
||||
cpuBackendLabel.text = NativeLibrary.getCpuBackend()
|
||||
gpuvendorLabel.text = NativeLibrary.getGpuDriver()
|
||||
}
|
||||
|
||||
|
||||
val position = IntSetting.PERF_OVERLAY_POSITION.getInt()
|
||||
updateStatsPosition(position)
|
||||
|
||||
}
|
||||
}
|
||||
emulationViewModel.isEmulationStopping.collect(viewLifecycleOwner) {
|
||||
|
@ -385,7 +412,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
binding.loadingText.setText(R.string.shutting_down)
|
||||
ViewUtils.showView(binding.loadingIndicator)
|
||||
ViewUtils.hideView(binding.inputContainer)
|
||||
ViewUtils.hideView(binding.showFpsText)
|
||||
ViewUtils.hideView(binding.showStatsOverlayText)
|
||||
}
|
||||
}
|
||||
emulationViewModel.drawerOpen.collect(viewLifecycleOwner) {
|
||||
|
@ -466,23 +493,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
override fun onPause() {
|
||||
if (emulationState.isRunning && emulationActivity?.isInPictureInPictureMode != true) {
|
||||
emulationState.pause()
|
||||
}
|
||||
context?.let {
|
||||
if (batteryReceiverRegistered) {
|
||||
it.unregisterReceiver(batteryReceiver)
|
||||
batteryReceiverRegistered = false
|
||||
}
|
||||
}
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
context?.let {
|
||||
if (batteryReceiverRegistered) {
|
||||
it.unregisterReceiver(batteryReceiver)
|
||||
batteryReceiverRegistered = false
|
||||
}
|
||||
}
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
@ -493,11 +508,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
}
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (!batteryReceiverRegistered) {
|
||||
val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||||
context?.registerReceiver(batteryReceiver, filter)
|
||||
batteryReceiverRegistered = true
|
||||
}
|
||||
// If the overlay is enabled, we need to update the position if changed
|
||||
val position = IntSetting.PERF_OVERLAY_POSITION.getInt()
|
||||
updateStatsPosition(position)
|
||||
}
|
||||
|
||||
private fun resetInputOverlay() {
|
||||
|
@ -508,48 +521,103 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
}
|
||||
}
|
||||
@SuppressLint("DefaultLocale")
|
||||
private fun updateShowFpsOverlay() {
|
||||
private fun updateshowStatsOvelray() {
|
||||
val showOverlay = BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean()
|
||||
binding.showFpsText.setTextColor(Color.parseColor("#A146FF"))
|
||||
binding.showFpsText.setVisible(showOverlay)
|
||||
binding.showStatsOverlayText.apply {
|
||||
setTextColor(
|
||||
MaterialColors.getColor(
|
||||
this,
|
||||
com.google.android.material.R.attr.colorPrimary
|
||||
)
|
||||
)
|
||||
}
|
||||
binding.showStatsOverlayText.setVisible(showOverlay)
|
||||
if (showOverlay) {
|
||||
val SYSTEM_FPS = 0
|
||||
val FPS = 1
|
||||
val FRAMETIME = 2
|
||||
val SPEED = 3
|
||||
val sb = StringBuilder()
|
||||
perfStatsUpdater = {
|
||||
if (emulationViewModel.emulationStarted.value &&
|
||||
!emulationViewModel.isEmulationStopping.value
|
||||
) {
|
||||
sb.setLength(0)
|
||||
|
||||
val perfStats = NativeLibrary.getPerfStats()
|
||||
val cpuBackend = NativeLibrary.getCpuBackend()
|
||||
val gpuDriver = NativeLibrary.getGpuDriver()
|
||||
|
||||
// Get memory info
|
||||
val mi = ActivityManager.MemoryInfo()
|
||||
val activityManager =
|
||||
requireContext().getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||
activityManager.getMemoryInfo(mi)
|
||||
|
||||
// Calculate used memory
|
||||
val usedMegs = (mi.totalMem - mi.availMem) / 1048576L // Convert bytes to megabytes
|
||||
|
||||
val actualFps = perfStats[FPS]
|
||||
|
||||
if (BooleanSetting.SHOW_FPS.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||
val enableFrameInterpolation = BooleanSetting.FRAME_INTERPOLATION.getBoolean()
|
||||
val generatedFpsText = if (enableFrameInterpolation) {
|
||||
val generatedFps = actualFps * 2
|
||||
String.format("(Generated: %.1f)", generatedFps)
|
||||
} else {
|
||||
""
|
||||
val enableFrameSkipping = BooleanSetting.FRAME_SKIPPING.getBoolean()
|
||||
|
||||
var fpsText = String.format("FPS: %.1f", actualFps)
|
||||
|
||||
if (enableFrameInterpolation) {
|
||||
val interpolatedFps = actualFps * 2
|
||||
fpsText += String.format(" (Interp: %.1f)", interpolatedFps)
|
||||
}
|
||||
if (_binding != null) {
|
||||
binding.showFpsText.text = String.format(
|
||||
"%.1f %s FPS • %d MB • %s/%s",
|
||||
actualFps, generatedFpsText, usedMegs, cpuBackend, gpuDriver
|
||||
|
||||
if (enableFrameSkipping) {
|
||||
fpsText += " [Skipping]"
|
||||
}
|
||||
|
||||
sb.append(fpsText)
|
||||
}
|
||||
|
||||
if (BooleanSetting.SHOW_FRAMETIME.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||
if (sb.isNotEmpty()) sb.append(" | ")
|
||||
sb.append(
|
||||
String.format(
|
||||
"FT: %.1fms",
|
||||
(perfStats[FRAMETIME] * 1000.0f).toFloat()
|
||||
)
|
||||
)
|
||||
}
|
||||
perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 800)
|
||||
|
||||
if (BooleanSetting.SHOW_SPEED.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||
if (sb.isNotEmpty()) sb.append(" | ")
|
||||
sb.append(
|
||||
String.format(
|
||||
"Speed: %d%%",
|
||||
(perfStats[SPEED] * 100.0 + 0.5).toInt()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (BooleanSetting.SHOW_APP_RAM_USAGE.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||
if (sb.isNotEmpty()) sb.append(" | ")
|
||||
val appRamUsage = File("/proc/self/statm").readLines()[0].split(' ')[1].toLong() * 4096 / 1000000
|
||||
sb.append("Process RAM: $appRamUsage MB")
|
||||
}
|
||||
|
||||
if (BooleanSetting.SHOW_SYSTEM_RAM_USAGE.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||
if (sb.isNotEmpty()) sb.append(" | ")
|
||||
context?.let { ctx ->
|
||||
val activityManager = ctx.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
|
||||
val memInfo = ActivityManager.MemoryInfo()
|
||||
activityManager.getMemoryInfo(memInfo)
|
||||
val usedRamMB = (memInfo.totalMem - memInfo.availMem) / 1048576L
|
||||
sb.append("RAM: $usedRamMB MB")
|
||||
}
|
||||
}
|
||||
|
||||
if (BooleanSetting.SHOW_BAT_TEMPERATURE.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||
if (sb.isNotEmpty()) sb.append(" | ")
|
||||
val batteryTemp = getBatteryTemperature()
|
||||
val tempF = celsiusToFahrenheit(batteryTemp)
|
||||
sb.append(String.format("%.1f°C/%.1f°F", batteryTemp, tempF))
|
||||
}
|
||||
|
||||
if (BooleanSetting.OVERLAY_BACKGROUND.getBoolean(NativeConfig.isPerGameConfigLoaded())) {
|
||||
binding.showStatsOverlayText.setBackgroundResource(R.color.yuzu_transparent_black)
|
||||
} else {
|
||||
binding.showStatsOverlayText.setBackgroundResource(0)
|
||||
}
|
||||
|
||||
binding.showStatsOverlayText.text = sb.toString()
|
||||
}
|
||||
perfStatsUpdateHandler.postDelayed(perfStatsUpdater!!, 800)
|
||||
}
|
||||
perfStatsUpdateHandler.post(perfStatsUpdater!!)
|
||||
} else {
|
||||
|
@ -559,15 +627,52 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
private val batteryReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
intent?.let {
|
||||
if (it.action == Intent.ACTION_BATTERY_CHANGED) {
|
||||
val temperature = getBatteryTemperature(context!!)
|
||||
updateThermalOverlay(temperature)
|
||||
private fun updateStatsPosition(position: Int) {
|
||||
val params = binding.showStatsOverlayText.layoutParams as FrameLayout.LayoutParams
|
||||
when (position) {
|
||||
0 -> {
|
||||
params.gravity = (Gravity.TOP or Gravity.START)
|
||||
params.setMargins(resources.getDimensionPixelSize(R.dimen.spacing_large), 0, 0, 0)
|
||||
}
|
||||
|
||||
1 -> {
|
||||
params.gravity = (Gravity.TOP or Gravity.CENTER_HORIZONTAL)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
params.gravity = (Gravity.TOP or Gravity.END)
|
||||
params.setMargins(0, 0, resources.getDimensionPixelSize(R.dimen.spacing_large), 0)
|
||||
}
|
||||
|
||||
3 -> {
|
||||
params.gravity = (Gravity.BOTTOM or Gravity.START)
|
||||
params.setMargins(resources.getDimensionPixelSize(R.dimen.spacing_large), 0, 0, 0)
|
||||
}
|
||||
|
||||
4 -> {
|
||||
params.gravity = (Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL)
|
||||
}
|
||||
|
||||
5 -> {
|
||||
params.gravity = (Gravity.BOTTOM or Gravity.END)
|
||||
params.setMargins(0, 0, resources.getDimensionPixelSize(R.dimen.spacing_large), 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBatteryTemperature(): Float {
|
||||
try {
|
||||
val batteryIntent = requireContext().registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
// Temperature in tenths of a degree Celsius
|
||||
val temperature = batteryIntent?.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) ?: 0
|
||||
// Convert to degrees Celsius
|
||||
return temperature / 10.0f
|
||||
} catch (e: Exception) {
|
||||
return 0.0f
|
||||
}
|
||||
}
|
||||
private fun celsiusToFahrenheit(celsius: Float): Float {
|
||||
return (celsius * 9 / 5) + 32
|
||||
}
|
||||
|
||||
private fun updateThermalOverlay(temperature: Float) {
|
||||
|
@ -591,14 +696,6 @@ private fun updateThermalOverlay(temperature: Float) {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getBatteryTemperature(context: Context): Float {
|
||||
val intent: Intent? = context.registerReceiver(
|
||||
null,
|
||||
IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||||
)
|
||||
val temperature = intent?.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0) ?: 0
|
||||
return temperature / 10.0f
|
||||
}
|
||||
|
||||
@SuppressLint("SourceLockedOrientationActivity")
|
||||
private fun updateOrientation() {
|
||||
|
@ -725,10 +822,8 @@ private fun getBatteryTemperature(context: Context): Float {
|
|||
popup.menuInflater.inflate(R.menu.menu_overlay_options, popup.menu)
|
||||
|
||||
popup.menu.apply {
|
||||
findItem(R.id.menu_toggle_fps).isChecked =
|
||||
findItem(R.id.menu_show_stats_overlay).isChecked =
|
||||
BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean()
|
||||
findItem(R.id.thermal_indicator).isChecked =
|
||||
BooleanSetting.SHOW_THERMAL_OVERLAY.getBoolean()
|
||||
findItem(R.id.menu_rel_stick_center).isChecked =
|
||||
BooleanSetting.JOYSTICK_REL_CENTER.getBoolean()
|
||||
findItem(R.id.menu_dpad_slide).isChecked = BooleanSetting.DPAD_SLIDE.getBoolean()
|
||||
|
@ -741,34 +836,12 @@ private fun getBatteryTemperature(context: Context): Float {
|
|||
popup.setOnDismissListener { NativeConfig.saveGlobalConfig() }
|
||||
popup.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_toggle_fps -> {
|
||||
R.id.menu_show_stats_overlay -> {
|
||||
it.isChecked = !it.isChecked
|
||||
BooleanSetting.SHOW_PERFORMANCE_OVERLAY.setBoolean(it.isChecked)
|
||||
updateShowFpsOverlay()
|
||||
updateshowStatsOvelray()
|
||||
true
|
||||
}
|
||||
|
||||
R.id.thermal_indicator -> {
|
||||
it.isChecked = !it.isChecked
|
||||
BooleanSetting.SHOW_THERMAL_OVERLAY.setBoolean(it.isChecked)
|
||||
if (it.isChecked) {
|
||||
val temperature = getBatteryTemperature(requireContext())
|
||||
updateThermalOverlay(temperature)
|
||||
if (!batteryReceiverRegistered) {
|
||||
val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
|
||||
context?.registerReceiver(batteryReceiver, filter)
|
||||
batteryReceiverRegistered = true
|
||||
}
|
||||
} else {
|
||||
if (batteryReceiverRegistered) {
|
||||
context?.unregisterReceiver(batteryReceiver)
|
||||
batteryReceiverRegistered = false
|
||||
}
|
||||
binding.showThermalsText.text = ""
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_edit_overlay -> {
|
||||
binding.drawerLayout.close()
|
||||
binding.surfaceInputOverlay.requestFocus()
|
||||
|
@ -959,7 +1032,8 @@ private fun getBatteryTemperature(context: Context): Float {
|
|||
right = cutInsets.right
|
||||
}
|
||||
|
||||
v.updatePadding(left = left, top = cutInsets.top, right = right)
|
||||
v.setPadding(left, cutInsets.top, right, 0)
|
||||
|
||||
windowInsets
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,9 +66,23 @@ struct Values {
|
|||
Settings::Setting<bool> haptic_feedback{linkage, true, "haptic_feedback",
|
||||
Settings::Category::Overlay};
|
||||
Settings::Setting<bool> show_performance_overlay{linkage, true, "show_performance_overlay",
|
||||
Settings::Category::Overlay};
|
||||
Settings::Setting<bool> show_thermal_overlay{linkage, false, "show_thermal_overlay",
|
||||
Settings::Category::Overlay};
|
||||
Settings::Category::Overlay, Settings::Specialization::Paired, true , true};
|
||||
Settings::Setting<bool> overlay_background{linkage, false, "overlay_background",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<s32> perf_overlay_position{linkage, 0, "perf_overlay_position",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<bool> show_fps{linkage, true, "show_fps",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<bool> show_frame_time{linkage, false, "show_frame_time",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<bool> show_speed{linkage, true, "show_speed",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<bool> show_app_ram_usage{linkage, false, "show_app_ram_usage",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<bool> show_system_ram_usage{linkage, false, "show_system_ram_usage",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<bool> show_bat_temperature{linkage, false, "show_bat_temperature",
|
||||
Settings::Category::Overlay, Settings::Specialization::Default, true , true, &show_performance_overlay};
|
||||
Settings::Setting<bool> show_input_overlay{linkage, true, "show_input_overlay",
|
||||
Settings::Category::Overlay};
|
||||
Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay};
|
||||
|
|
32
src/android/app/src/main/res/drawable/ic_frames.xml
Normal file
32
src/android/app/src/main/res/drawable/ic_frames.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#FF000000"
|
||||
android:strokeWidth="1"
|
||||
android:pathData="M4,4 L4,20 L20,20" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#FF000000"
|
||||
android:strokeWidth="2"
|
||||
android:pathData="M4,16 L8,12 L12,14 L16,8 L20,10" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M4,16 C3.45,16 3,15.55 3,15 C3,14.45 3.45,14 4,14 C4.55,14 5,14.45 5,15 C5,15.55 4.55,16 4,16" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M8,12 C7.45,12 7,11.55 7,11 C7,10.45 7.45,10 8,10 C8.55,10 9,10.45 9,11 C9,11.55 8.55,12 8,12" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,14 C11.45,14 11,13.55 11,13 C11,12.45 11.45,12 12,12 C12.55,12 13,12.45 13,13 C13,13.55 12.55,14 12,14" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16,8 C15.45,8 15,7.55 15,7 C15,6.45 15.45,6 16,6 C16.55,6 17,6.45 17,7 C17,7.55 16.55,8 16,8" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,10 C19.45,10 19,9.55 19,9 C19,8.45 19.45,8 20,8 C20.55,8 21,8.45 21,9 C21,9.55 20.55,10 20,10" />
|
||||
</vector>
|
|
@ -140,15 +140,13 @@
|
|||
android:id="@+id/overlay_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:fitsSystemWindows="true">
|
||||
android:fitsSystemWindows="false">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/show_fps_text"
|
||||
android:id="@+id/show_stats_overlay_text"
|
||||
style="@style/TextAppearance.Material3.BodySmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:textColor="@android:color/white"
|
||||
|
|
|
@ -1,14 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/text_game_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:textAppearance="?attr/textAppearanceHeadlineMedium"
|
||||
android:textColor="?attr/colorOnSurface"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="Super Mario Odyssey" />
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:text="text_game_title" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textAlignment="viewStart"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="System Info:" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/cpu_backend"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="cpu_backend" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:text="|" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/gpu_vendor"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textColor="?attr/colorOnSurfaceVariant"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="gpu_vendor" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -2,13 +2,8 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_toggle_fps"
|
||||
android:title="@string/emulation_fps_counter"
|
||||
android:checkable="true" />
|
||||
|
||||
<item
|
||||
android:id="@+id/thermal_indicator"
|
||||
android:title="@string/emulation_thermal_indicator"
|
||||
android:id="@+id/menu_show_stats_overlay"
|
||||
android:title="@string/show_stats_overlay"
|
||||
android:checkable="true" />
|
||||
|
||||
<item
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
<color name="yuzu_surfaceTint_gray">#B7B7B7</color>
|
||||
|
||||
<!-- Common Colors Across All Themes -->
|
||||
<color name="yuzu_transparent_black">#80000000</color>
|
||||
<color name="yuzu_outlineVariant">#C6C5D0</color>
|
||||
<color name="yuzu_error">#FFB4AB</color>
|
||||
<color name="yuzu_errorContainer">#93000A</color>
|
||||
|
|
|
@ -249,6 +249,23 @@
|
|||
<item>2</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="statsPosition">
|
||||
<item>@string/overlay_position_top_left</item>
|
||||
<item>@string/overlay_position_center_top</item>
|
||||
<item>@string/overlay_position_top_right</item>
|
||||
<item>@string/overlay_position_bottom_left</item>
|
||||
<item>@string/overlay_position_center_bottom</item>
|
||||
<item>@string/overlay_position_bottom_right</item>
|
||||
</string-array>
|
||||
<integer-array name="statsPositionValues">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
<item>3</item>
|
||||
<item>4</item>
|
||||
<item>5</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="cpuBackendArm64Names">
|
||||
<item>@string/cpu_backend_dynarmic</item>
|
||||
<item>@string/cpu_backend_nce</item>
|
||||
|
|
|
@ -9,6 +9,37 @@
|
|||
<string name="notice_notification_channel_description">Shows notifications when something goes wrong.</string>
|
||||
<string name="notification_permission_not_granted">Notification permission not granted!</string>
|
||||
|
||||
<!-- Stats Overlay settings -->
|
||||
<string name="show_stats_overlay">ShoW Performance Stats Overlay</string>
|
||||
<string name="stats_overlay_customization">Customization</string>
|
||||
<string name="stats_overlay_items">Visibility</string>
|
||||
<string name="stats_overlay_options">Overlay</string>
|
||||
<string name="enable_stats_overlay_">Enable Performance Stats Overlay</string>
|
||||
<string name="stats_overlay_options_description">Configure what information is shown in the performance stats overlay</string>
|
||||
<string name="show_fps">Show FPS</string>
|
||||
<string name="show_fps_description">Display current frames per second</string>
|
||||
<string name="show_frametime">Show Frametime</string>
|
||||
<string name="show_frametime_description">Display current frametime</string>
|
||||
<string name="show_speed">Show Speed</string>
|
||||
<string name="show_speed_description">Display current emulation speed percentage</string>
|
||||
<string name="show_app_ram_usage">Show App Memory Usage</string>
|
||||
<string name="show_app_ram_usage_description">Display the amount of RAM getting used by the emulator</string>
|
||||
<string name="show_system_ram_usage">Show System Memory Usage</string>
|
||||
<string name="show_system_ram_usage_description">Display the amount of RAM getting used by the system</string>
|
||||
<string name="show_bat_temperature">Show Battery Temperature</string>
|
||||
<string name="show_bat_temperature_description">Display current Battery temperature in Celsius and Fahrenheit</string>
|
||||
<string name="overlay_position">Overlay Position</string>
|
||||
<string name="overlay_position_description">Choose where the performance stats overlay is displayed on the screen</string>
|
||||
<string name="overlay_position_top_left">Top Left</string>
|
||||
<string name="overlay_position_top_right">Top Right</string>
|
||||
<string name="overlay_position_bottom_left">Bottom Left</string>
|
||||
<string name="overlay_position_bottom_right">Bottom Right</string>
|
||||
<string name="overlay_position_center_top">Center Top</string>
|
||||
<string name="overlay_position_center_bottom">Center Bottom</string>
|
||||
<string name="overlay_background">Overlay Background</string>
|
||||
<string name="overlay_background_description">Adds a background behind the overlay for easier reading</string>
|
||||
|
||||
|
||||
<!-- Setup strings -->
|
||||
<string name="welcome">Welcome!</string>
|
||||
<string name="welcome_description">Learn how to setup <b>eden</b> and jump into emulation.</string>
|
||||
|
|
|
@ -229,6 +229,7 @@
|
|||
<color name="yuzu_onErrorContainer">#410002</color>
|
||||
<color name="yuzu_shadow">#000000</color>
|
||||
<color name="yuzu_scrim">#000000</color>
|
||||
<color name="yuzu_transparent_black">#80000000</color>
|
||||
<!-- Values used in dark mode but here are jsut white / black values-->
|
||||
<color name="yuzu_onPrimary_blue">#FFFFFF</color>
|
||||
<color name="yuzu_onSecondary_blue">#FFFFFF</color>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue