diff options
Diffstat (limited to 'src/android')
6 files changed, 76 insertions, 5 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 86bd33672..664478472 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt | |||
| @@ -25,7 +25,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { | |||
| 25 | HAPTIC_FEEDBACK("haptic_feedback"), | 25 | HAPTIC_FEEDBACK("haptic_feedback"), |
| 26 | SHOW_PERFORMANCE_OVERLAY("show_performance_overlay"), | 26 | SHOW_PERFORMANCE_OVERLAY("show_performance_overlay"), |
| 27 | SHOW_INPUT_OVERLAY("show_input_overlay"), | 27 | SHOW_INPUT_OVERLAY("show_input_overlay"), |
| 28 | TOUCHSCREEN("touchscreen"); | 28 | TOUCHSCREEN("touchscreen"), |
| 29 | SHOW_THERMAL_OVERLAY("show_thermal_overlay"); | ||
| 29 | 30 | ||
| 30 | override fun getBoolean(needsGlobal: Boolean): Boolean = | 31 | override fun getBoolean(needsGlobal: Boolean): Boolean = |
| 31 | NativeConfig.getBoolean(key, needsGlobal) | 32 | NativeConfig.getBoolean(key, needsGlobal) |
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 937b8faf1..44af896da 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 | |||
| @@ -13,6 +13,7 @@ import android.net.Uri | |||
| 13 | import android.os.Bundle | 13 | import android.os.Bundle |
| 14 | import android.os.Handler | 14 | import android.os.Handler |
| 15 | import android.os.Looper | 15 | import android.os.Looper |
| 16 | import android.os.PowerManager | ||
| 16 | import android.os.SystemClock | 17 | import android.os.SystemClock |
| 17 | import android.view.* | 18 | import android.view.* |
| 18 | import android.widget.TextView | 19 | import android.widget.TextView |
| @@ -23,6 +24,7 @@ import androidx.core.content.res.ResourcesCompat | |||
| 23 | import androidx.core.graphics.Insets | 24 | import androidx.core.graphics.Insets |
| 24 | import androidx.core.view.ViewCompat | 25 | import androidx.core.view.ViewCompat |
| 25 | import androidx.core.view.WindowInsetsCompat | 26 | import androidx.core.view.WindowInsetsCompat |
| 27 | import androidx.core.view.updatePadding | ||
| 26 | import androidx.drawerlayout.widget.DrawerLayout | 28 | import androidx.drawerlayout.widget.DrawerLayout |
| 27 | import androidx.drawerlayout.widget.DrawerLayout.DrawerListener | 29 | import androidx.drawerlayout.widget.DrawerLayout.DrawerListener |
| 28 | import androidx.fragment.app.Fragment | 30 | import androidx.fragment.app.Fragment |
| @@ -38,7 +40,6 @@ import androidx.window.layout.WindowLayoutInfo | |||
| 38 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 40 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 39 | import com.google.android.material.slider.Slider | 41 | import com.google.android.material.slider.Slider |
| 40 | import kotlinx.coroutines.Dispatchers | 42 | import kotlinx.coroutines.Dispatchers |
| 41 | import kotlinx.coroutines.flow.collect | ||
| 42 | import kotlinx.coroutines.flow.collectLatest | 43 | import kotlinx.coroutines.flow.collectLatest |
| 43 | import kotlinx.coroutines.launch | 44 | import kotlinx.coroutines.launch |
| 44 | import org.yuzu.yuzu_emu.HomeNavigationDirections | 45 | import org.yuzu.yuzu_emu.HomeNavigationDirections |
| @@ -64,6 +65,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 64 | private lateinit var emulationState: EmulationState | 65 | private lateinit var emulationState: EmulationState |
| 65 | private var emulationActivity: EmulationActivity? = null | 66 | private var emulationActivity: EmulationActivity? = null |
| 66 | private var perfStatsUpdater: (() -> Unit)? = null | 67 | private var perfStatsUpdater: (() -> Unit)? = null |
| 68 | private var thermalStatsUpdater: (() -> Unit)? = null | ||
| 67 | 69 | ||
| 68 | private var _binding: FragmentEmulationBinding? = null | 70 | private var _binding: FragmentEmulationBinding? = null |
| 69 | private val binding get() = _binding!! | 71 | private val binding get() = _binding!! |
| @@ -77,6 +79,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 77 | 79 | ||
| 78 | private var isInFoldableLayout = false | 80 | private var isInFoldableLayout = false |
| 79 | 81 | ||
| 82 | private lateinit var powerManager: PowerManager | ||
| 83 | |||
| 80 | override fun onAttach(context: Context) { | 84 | override fun onAttach(context: Context) { |
| 81 | super.onAttach(context) | 85 | super.onAttach(context) |
| 82 | if (context is EmulationActivity) { | 86 | if (context is EmulationActivity) { |
| @@ -102,6 +106,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 102 | super.onCreate(savedInstanceState) | 106 | super.onCreate(savedInstanceState) |
| 103 | updateOrientation() | 107 | updateOrientation() |
| 104 | 108 | ||
| 109 | powerManager = requireContext().getSystemService(Context.POWER_SERVICE) as PowerManager | ||
| 110 | |||
| 105 | val intentUri: Uri? = requireActivity().intent.data | 111 | val intentUri: Uri? = requireActivity().intent.data |
| 106 | var intentGame: Game? = null | 112 | var intentGame: Game? = null |
| 107 | if (intentUri != null) { | 113 | if (intentUri != null) { |
| @@ -394,8 +400,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 394 | 400 | ||
| 395 | emulationState.updateSurface() | 401 | emulationState.updateSurface() |
| 396 | 402 | ||
| 397 | // Setup overlay | 403 | // Setup overlays |
| 398 | updateShowFpsOverlay() | 404 | updateShowFpsOverlay() |
| 405 | updateThermalOverlay() | ||
| 399 | } | 406 | } |
| 400 | } | 407 | } |
| 401 | } | 408 | } |
| @@ -553,6 +560,38 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 553 | } | 560 | } |
| 554 | } | 561 | } |
| 555 | 562 | ||
| 563 | private fun updateThermalOverlay() { | ||
| 564 | if (BooleanSetting.SHOW_THERMAL_OVERLAY.getBoolean()) { | ||
| 565 | thermalStatsUpdater = { | ||
| 566 | if (emulationViewModel.emulationStarted.value && | ||
| 567 | !emulationViewModel.isEmulationStopping.value | ||
| 568 | ) { | ||
| 569 | val thermalStatus = when (powerManager.currentThermalStatus) { | ||
| 570 | PowerManager.THERMAL_STATUS_LIGHT -> "😥" | ||
| 571 | PowerManager.THERMAL_STATUS_MODERATE -> "🥵" | ||
| 572 | PowerManager.THERMAL_STATUS_SEVERE -> "🔥" | ||
| 573 | PowerManager.THERMAL_STATUS_CRITICAL, | ||
| 574 | PowerManager.THERMAL_STATUS_EMERGENCY, | ||
| 575 | PowerManager.THERMAL_STATUS_SHUTDOWN -> "☢️" | ||
| 576 | |||
| 577 | else -> "🙂" | ||
| 578 | } | ||
| 579 | if (_binding != null) { | ||
| 580 | binding.showThermalsText.text = thermalStatus | ||
| 581 | } | ||
| 582 | thermalStatsUpdateHandler.postDelayed(thermalStatsUpdater!!, 1000) | ||
| 583 | } | ||
| 584 | } | ||
| 585 | thermalStatsUpdateHandler.post(thermalStatsUpdater!!) | ||
| 586 | binding.showThermalsText.visibility = View.VISIBLE | ||
| 587 | } else { | ||
| 588 | if (thermalStatsUpdater != null) { | ||
| 589 | thermalStatsUpdateHandler.removeCallbacks(thermalStatsUpdater!!) | ||
| 590 | } | ||
| 591 | binding.showThermalsText.visibility = View.GONE | ||
| 592 | } | ||
| 593 | } | ||
| 594 | |||
| 556 | @SuppressLint("SourceLockedOrientationActivity") | 595 | @SuppressLint("SourceLockedOrientationActivity") |
| 557 | private fun updateOrientation() { | 596 | private fun updateOrientation() { |
| 558 | emulationActivity?.let { | 597 | emulationActivity?.let { |
| @@ -641,6 +680,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 641 | popup.menu.apply { | 680 | popup.menu.apply { |
| 642 | findItem(R.id.menu_toggle_fps).isChecked = | 681 | findItem(R.id.menu_toggle_fps).isChecked = |
| 643 | BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean() | 682 | BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean() |
| 683 | findItem(R.id.thermal_indicator).isChecked = | ||
| 684 | BooleanSetting.SHOW_THERMAL_OVERLAY.getBoolean() | ||
| 644 | findItem(R.id.menu_rel_stick_center).isChecked = | 685 | findItem(R.id.menu_rel_stick_center).isChecked = |
| 645 | BooleanSetting.JOYSTICK_REL_CENTER.getBoolean() | 686 | BooleanSetting.JOYSTICK_REL_CENTER.getBoolean() |
| 646 | findItem(R.id.menu_dpad_slide).isChecked = BooleanSetting.DPAD_SLIDE.getBoolean() | 687 | findItem(R.id.menu_dpad_slide).isChecked = BooleanSetting.DPAD_SLIDE.getBoolean() |
| @@ -660,6 +701,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 660 | true | 701 | true |
| 661 | } | 702 | } |
| 662 | 703 | ||
| 704 | R.id.thermal_indicator -> { | ||
| 705 | it.isChecked = !it.isChecked | ||
| 706 | BooleanSetting.SHOW_THERMAL_OVERLAY.setBoolean(it.isChecked) | ||
| 707 | updateThermalOverlay() | ||
| 708 | true | ||
| 709 | } | ||
| 710 | |||
| 663 | R.id.menu_edit_overlay -> { | 711 | R.id.menu_edit_overlay -> { |
| 664 | binding.drawerLayout.close() | 712 | binding.drawerLayout.close() |
| 665 | binding.surfaceInputOverlay.requestFocus() | 713 | binding.surfaceInputOverlay.requestFocus() |
| @@ -850,7 +898,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 850 | right = cutInsets.right | 898 | right = cutInsets.right |
| 851 | } | 899 | } |
| 852 | 900 | ||
| 853 | v.setPadding(left, cutInsets.top, right, 0) | 901 | v.updatePadding(left = left, top = cutInsets.top, right = right) |
| 854 | windowInsets | 902 | windowInsets |
| 855 | } | 903 | } |
| 856 | } | 904 | } |
| @@ -1003,5 +1051,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | |||
| 1003 | 1051 | ||
| 1004 | companion object { | 1052 | companion object { |
| 1005 | private val perfStatsUpdateHandler = Handler(Looper.myLooper()!!) | 1053 | private val perfStatsUpdateHandler = Handler(Looper.myLooper()!!) |
| 1054 | private val thermalStatsUpdateHandler = Handler(Looper.myLooper()!!) | ||
| 1006 | } | 1055 | } |
| 1007 | } | 1056 | } |
diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index cf93304da..4a3bc8e53 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h | |||
| @@ -60,6 +60,8 @@ struct Values { | |||
| 60 | Settings::Category::Overlay}; | 60 | Settings::Category::Overlay}; |
| 61 | Settings::Setting<bool> show_performance_overlay{linkage, true, "show_performance_overlay", | 61 | Settings::Setting<bool> show_performance_overlay{linkage, true, "show_performance_overlay", |
| 62 | Settings::Category::Overlay}; | 62 | Settings::Category::Overlay}; |
| 63 | Settings::Setting<bool> show_thermal_overlay{linkage, false, "show_thermal_overlay", | ||
| 64 | Settings::Category::Overlay}; | ||
| 63 | Settings::Setting<bool> show_input_overlay{linkage, true, "show_input_overlay", | 65 | Settings::Setting<bool> show_input_overlay{linkage, true, "show_input_overlay", |
| 64 | Settings::Category::Overlay}; | 66 | Settings::Category::Overlay}; |
| 65 | Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay}; | 67 | Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay}; |
diff --git a/src/android/app/src/main/res/layout/fragment_emulation.xml b/src/android/app/src/main/res/layout/fragment_emulation.xml index 0d2bfe8d6..e99a15783 100644 --- a/src/android/app/src/main/res/layout/fragment_emulation.xml +++ b/src/android/app/src/main/res/layout/fragment_emulation.xml | |||
| @@ -140,6 +140,7 @@ | |||
| 140 | android:id="@+id/overlay_container" | 140 | android:id="@+id/overlay_container" |
| 141 | android:layout_width="match_parent" | 141 | android:layout_width="match_parent" |
| 142 | android:layout_height="match_parent" | 142 | android:layout_height="match_parent" |
| 143 | android:layout_marginHorizontal="20dp" | ||
| 143 | android:fitsSystemWindows="true"> | 144 | android:fitsSystemWindows="true"> |
| 144 | 145 | ||
| 145 | <com.google.android.material.textview.MaterialTextView | 146 | <com.google.android.material.textview.MaterialTextView |
| @@ -150,7 +151,19 @@ | |||
| 150 | android:layout_gravity="left" | 151 | android:layout_gravity="left" |
| 151 | android:clickable="false" | 152 | android:clickable="false" |
| 152 | android:focusable="false" | 153 | android:focusable="false" |
| 153 | android:paddingHorizontal="20dp" | 154 | android:textColor="@android:color/white" |
| 155 | android:shadowColor="@android:color/black" | ||
| 156 | android:shadowRadius="3" | ||
| 157 | tools:ignore="RtlHardcoded" /> | ||
| 158 | |||
| 159 | <com.google.android.material.textview.MaterialTextView | ||
| 160 | android:id="@+id/show_thermals_text" | ||
| 161 | style="@style/TextAppearance.Material3.BodySmall" | ||
| 162 | android:layout_width="wrap_content" | ||
| 163 | android:layout_height="wrap_content" | ||
| 164 | android:layout_gravity="right" | ||
| 165 | android:clickable="false" | ||
| 166 | android:focusable="false" | ||
| 154 | android:textColor="@android:color/white" | 167 | android:textColor="@android:color/white" |
| 155 | android:shadowColor="@android:color/black" | 168 | android:shadowColor="@android:color/black" |
| 156 | android:shadowRadius="3" | 169 | android:shadowRadius="3" |
diff --git a/src/android/app/src/main/res/menu/menu_overlay_options.xml b/src/android/app/src/main/res/menu/menu_overlay_options.xml index 363781652..a9e807427 100644 --- a/src/android/app/src/main/res/menu/menu_overlay_options.xml +++ b/src/android/app/src/main/res/menu/menu_overlay_options.xml | |||
| @@ -7,6 +7,11 @@ | |||
| 7 | android:checkable="true" /> | 7 | android:checkable="true" /> |
| 8 | 8 | ||
| 9 | <item | 9 | <item |
| 10 | android:id="@+id/thermal_indicator" | ||
| 11 | android:title="@string/emulation_thermal_indicator" | ||
| 12 | android:checkable="true" /> | ||
| 13 | |||
| 14 | <item | ||
| 10 | android:id="@+id/menu_edit_overlay" | 15 | android:id="@+id/menu_edit_overlay" |
| 11 | android:title="@string/emulation_touch_overlay_edit" /> | 16 | android:title="@string/emulation_touch_overlay_edit" /> |
| 12 | 17 | ||
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 3cd1586fd..f9e2122ee 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml | |||
| @@ -380,6 +380,7 @@ | |||
| 380 | <string name="emulation_exit">Exit emulation</string> | 380 | <string name="emulation_exit">Exit emulation</string> |
| 381 | <string name="emulation_done">Done</string> | 381 | <string name="emulation_done">Done</string> |
| 382 | <string name="emulation_fps_counter">FPS counter</string> | 382 | <string name="emulation_fps_counter">FPS counter</string> |
| 383 | <string name="emulation_thermal_indicator">Thermal indicator</string> | ||
| 383 | <string name="emulation_toggle_controls">Toggle controls</string> | 384 | <string name="emulation_toggle_controls">Toggle controls</string> |
| 384 | <string name="emulation_rel_stick_center">Relative stick center</string> | 385 | <string name="emulation_rel_stick_center">Relative stick center</string> |
| 385 | <string name="emulation_dpad_slide">D-pad slide</string> | 386 | <string name="emulation_dpad_slide">D-pad slide</string> |