mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 10:44:49 +01:00 
			
		
		
		
	android: Add thermal throttling overlay
This commit is contained in:
		
							parent
							
								
									71e59bdcd8
								
							
						
					
					
						commit
						5fa9bc192c
					
				| @ -25,7 +25,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { | ||||
|     HAPTIC_FEEDBACK("haptic_feedback"), | ||||
|     SHOW_PERFORMANCE_OVERLAY("show_performance_overlay"), | ||||
|     SHOW_INPUT_OVERLAY("show_input_overlay"), | ||||
|     TOUCHSCREEN("touchscreen"); | ||||
|     TOUCHSCREEN("touchscreen"), | ||||
|     SHOW_THERMAL_OVERLAY("show_thermal_overlay"); | ||||
| 
 | ||||
|     override fun getBoolean(needsGlobal: Boolean): Boolean = | ||||
|         NativeConfig.getBoolean(key, needsGlobal) | ||||
|  | ||||
| @ -13,6 +13,7 @@ import android.net.Uri | ||||
| import android.os.Bundle | ||||
| import android.os.Handler | ||||
| import android.os.Looper | ||||
| import android.os.PowerManager | ||||
| import android.os.SystemClock | ||||
| import android.view.* | ||||
| import android.widget.TextView | ||||
| @ -23,6 +24,7 @@ import androidx.core.content.res.ResourcesCompat | ||||
| import androidx.core.graphics.Insets | ||||
| import androidx.core.view.ViewCompat | ||||
| import androidx.core.view.WindowInsetsCompat | ||||
| import androidx.core.view.updatePadding | ||||
| import androidx.drawerlayout.widget.DrawerLayout | ||||
| import androidx.drawerlayout.widget.DrawerLayout.DrawerListener | ||||
| import androidx.fragment.app.Fragment | ||||
| @ -38,7 +40,6 @@ import androidx.window.layout.WindowLayoutInfo | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||
| import com.google.android.material.slider.Slider | ||||
| import kotlinx.coroutines.Dispatchers | ||||
| import kotlinx.coroutines.flow.collect | ||||
| import kotlinx.coroutines.flow.collectLatest | ||||
| import kotlinx.coroutines.launch | ||||
| import org.yuzu.yuzu_emu.HomeNavigationDirections | ||||
| @ -64,6 +65,7 @@ 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 _binding: FragmentEmulationBinding? = null | ||||
|     private val binding get() = _binding!! | ||||
| @ -77,6 +79,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
| 
 | ||||
|     private var isInFoldableLayout = false | ||||
| 
 | ||||
|     private lateinit var powerManager: PowerManager | ||||
| 
 | ||||
|     override fun onAttach(context: Context) { | ||||
|         super.onAttach(context) | ||||
|         if (context is EmulationActivity) { | ||||
| @ -102,6 +106,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|         super.onCreate(savedInstanceState) | ||||
|         updateOrientation() | ||||
| 
 | ||||
|         powerManager = requireContext().getSystemService(Context.POWER_SERVICE) as PowerManager | ||||
| 
 | ||||
|         val intentUri: Uri? = requireActivity().intent.data | ||||
|         var intentGame: Game? = null | ||||
|         if (intentUri != null) { | ||||
| @ -394,8 +400,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
| 
 | ||||
|                             emulationState.updateSurface() | ||||
| 
 | ||||
|                             // Setup overlay | ||||
|                             // Setup overlays | ||||
|                             updateShowFpsOverlay() | ||||
|                             updateThermalOverlay() | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @ -553,6 +560,38 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun updateThermalOverlay() { | ||||
|         if (BooleanSetting.SHOW_THERMAL_OVERLAY.getBoolean()) { | ||||
|             thermalStatsUpdater = { | ||||
|                 if (emulationViewModel.emulationStarted.value && | ||||
|                     !emulationViewModel.isEmulationStopping.value | ||||
|                 ) { | ||||
|                     val thermalStatus = when (powerManager.currentThermalStatus) { | ||||
|                         PowerManager.THERMAL_STATUS_LIGHT -> "😥" | ||||
|                         PowerManager.THERMAL_STATUS_MODERATE -> "🥵" | ||||
|                         PowerManager.THERMAL_STATUS_SEVERE -> "🔥" | ||||
|                         PowerManager.THERMAL_STATUS_CRITICAL, | ||||
|                         PowerManager.THERMAL_STATUS_EMERGENCY, | ||||
|                         PowerManager.THERMAL_STATUS_SHUTDOWN -> "☢️" | ||||
| 
 | ||||
|                         else -> "🙂" | ||||
|                     } | ||||
|                     if (_binding != null) { | ||||
|                         binding.showThermalsText.text = thermalStatus | ||||
|                     } | ||||
|                     thermalStatsUpdateHandler.postDelayed(thermalStatsUpdater!!, 1000) | ||||
|                 } | ||||
|             } | ||||
|             thermalStatsUpdateHandler.post(thermalStatsUpdater!!) | ||||
|             binding.showThermalsText.visibility = View.VISIBLE | ||||
|         } else { | ||||
|             if (thermalStatsUpdater != null) { | ||||
|                 thermalStatsUpdateHandler.removeCallbacks(thermalStatsUpdater!!) | ||||
|             } | ||||
|             binding.showThermalsText.visibility = View.GONE | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @SuppressLint("SourceLockedOrientationActivity") | ||||
|     private fun updateOrientation() { | ||||
|         emulationActivity?.let { | ||||
| @ -641,6 +680,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|         popup.menu.apply { | ||||
|             findItem(R.id.menu_toggle_fps).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() | ||||
| @ -660,6 +701,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|                     true | ||||
|                 } | ||||
| 
 | ||||
|                 R.id.thermal_indicator -> { | ||||
|                     it.isChecked = !it.isChecked | ||||
|                     BooleanSetting.SHOW_THERMAL_OVERLAY.setBoolean(it.isChecked) | ||||
|                     updateThermalOverlay() | ||||
|                     true | ||||
|                 } | ||||
| 
 | ||||
|                 R.id.menu_edit_overlay -> { | ||||
|                     binding.drawerLayout.close() | ||||
|                     binding.surfaceInputOverlay.requestFocus() | ||||
| @ -850,7 +898,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|                 right = cutInsets.right | ||||
|             } | ||||
| 
 | ||||
|             v.setPadding(left, cutInsets.top, right, 0) | ||||
|             v.updatePadding(left = left, top = cutInsets.top, right = right) | ||||
|             windowInsets | ||||
|         } | ||||
|     } | ||||
| @ -1003,5 +1051,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
| 
 | ||||
|     companion object { | ||||
|         private val perfStatsUpdateHandler = Handler(Looper.myLooper()!!) | ||||
|         private val thermalStatsUpdateHandler = Handler(Looper.myLooper()!!) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -60,6 +60,8 @@ struct Values { | ||||
|                                             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::Setting<bool> show_input_overlay{linkage, true, "show_input_overlay", | ||||
|                                                Settings::Category::Overlay}; | ||||
|     Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay}; | ||||
|  | ||||
| @ -140,6 +140,7 @@ | ||||
|             android:id="@+id/overlay_container" | ||||
|             android:layout_width="match_parent" | ||||
|             android:layout_height="match_parent" | ||||
|             android:layout_marginHorizontal="20dp" | ||||
|             android:fitsSystemWindows="true"> | ||||
| 
 | ||||
|             <com.google.android.material.textview.MaterialTextView | ||||
| @ -150,7 +151,19 @@ | ||||
|                 android:layout_gravity="left" | ||||
|                 android:clickable="false" | ||||
|                 android:focusable="false" | ||||
|                 android:paddingHorizontal="20dp" | ||||
|                 android:textColor="@android:color/white" | ||||
|                 android:shadowColor="@android:color/black" | ||||
|                 android:shadowRadius="3" | ||||
|                 tools:ignore="RtlHardcoded" /> | ||||
| 
 | ||||
|             <com.google.android.material.textview.MaterialTextView | ||||
|                 android:id="@+id/show_thermals_text" | ||||
|                 style="@style/TextAppearance.Material3.BodySmall" | ||||
|                 android:layout_width="wrap_content" | ||||
|                 android:layout_height="wrap_content" | ||||
|                 android:layout_gravity="right" | ||||
|                 android:clickable="false" | ||||
|                 android:focusable="false" | ||||
|                 android:textColor="@android:color/white" | ||||
|                 android:shadowColor="@android:color/black" | ||||
|                 android:shadowRadius="3" | ||||
|  | ||||
| @ -6,6 +6,11 @@ | ||||
|         android:title="@string/emulation_fps_counter" | ||||
|         android:checkable="true" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/thermal_indicator" | ||||
|         android:title="@string/emulation_thermal_indicator" | ||||
|         android:checkable="true" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/menu_edit_overlay" | ||||
|         android:title="@string/emulation_touch_overlay_edit" /> | ||||
|  | ||||
| @ -380,6 +380,7 @@ | ||||
|     <string name="emulation_exit">Exit emulation</string> | ||||
|     <string name="emulation_done">Done</string> | ||||
|     <string name="emulation_fps_counter">FPS counter</string> | ||||
|     <string name="emulation_thermal_indicator">Thermal indicator</string> | ||||
|     <string name="emulation_toggle_controls">Toggle controls</string> | ||||
|     <string name="emulation_rel_stick_center">Relative stick center</string> | ||||
|     <string name="emulation_dpad_slide">D-pad slide</string> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user