diff options
Diffstat (limited to 'src')
6 files changed, 95 insertions, 26 deletions
diff --git a/src/android/app/src/main/java/org/citron/citron_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/citron/citron_emu/features/settings/model/BooleanSetting.kt index 895194db5..f781d10c1 100644 --- a/src/android/app/src/main/java/org/citron/citron_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/citron/citron_emu/features/settings/model/BooleanSetting.kt @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later package org.citron.citron_emu.features.settings.model @@ -27,6 +28,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { SHOW_INPUT_OVERLAY("show_input_overlay"), TOUCHSCREEN("touchscreen"), SHOW_THERMAL_OVERLAY("show_thermal_overlay"), + SHOW_RAM_OVERLAY("show_ram_overlay"), USE_AUTO_STUB("use_auto_stub"); override fun getBoolean(needsGlobal: Boolean): Boolean = diff --git a/src/android/app/src/main/java/org/citron/citron_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/citron/citron_emu/fragments/EmulationFragment.kt index 93a15def9..f4678b603 100644 --- a/src/android/app/src/main/java/org/citron/citron_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/citron/citron_emu/fragments/EmulationFragment.kt @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later package org.citron.citron_emu.fragments @@ -11,9 +12,11 @@ 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.Debug import android.os.Handler import android.os.Looper import android.os.PowerManager @@ -68,6 +71,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { private var emulationActivity: EmulationActivity? = null private var perfStatsUpdater: (() -> Unit)? = null private var thermalStatsUpdater: (() -> Unit)? = null + private var ramStatsUpdater: (() -> Unit)? = null private var _binding: FragmentEmulationBinding? = null private val binding get() = _binding!! @@ -83,6 +87,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { private lateinit var powerManager: PowerManager + private val ramStatsUpdateHandler = Handler(Looper.myLooper()!!) + override fun onAttach(context: Context) { super.onAttach(context) if (context is EmulationActivity) { @@ -376,6 +382,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { // Setup overlays updateShowFpsOverlay() updateThermalOverlay() + updateRamOverlay() } } emulationViewModel.isEmulationStopping.collect(viewLifecycleOwner) { @@ -470,6 +477,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { override fun onDestroyView() { super.onDestroyView() + if (ramStatsUpdater != null) { + ramStatsUpdateHandler.removeCallbacks(ramStatsUpdater!!) + } _binding = null } @@ -552,8 +562,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { emulationViewModel.emulationStarted.value && !emulationViewModel.isEmulationStopping.value ) { - // Get thermal status + // Get thermal status for color val thermalStatus = when (powerManager.currentThermalStatus) { + PowerManager.THERMAL_STATUS_NONE -> 0f PowerManager.THERMAL_STATUS_LIGHT -> 0.25f PowerManager.THERMAL_STATUS_MODERATE -> 0.5f PowerManager.THERMAL_STATUS_SEVERE -> 0.75f @@ -563,34 +574,57 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { else -> 0f } - // Convert to Fahrenheit for additional info + // Convert to Fahrenheit val fahrenheit = (temperature * 9f / 5f) + 32f - // Create progress bar using block elements - val progressBarLength = 12 - val filledBars = (thermalStatus * progressBarLength).toInt() - val progressBar = buildString { - append("│") // Left border - repeat(filledBars) { append("█") } - repeat(progressBarLength - filledBars) { append("░") } - append("│") // Right border - append(" ") - append(String.format("%3d%%", (thermalStatus * 100).toInt())) - } - - // Color interpolation based on temperature (green at 30°C, red at 45°C) - val normalizedTemp = ((temperature - 30f) / 15f).coerceIn(0f, 1f) - val red = (normalizedTemp * 255).toInt() - val green = ((1f - normalizedTemp) * 255).toInt() + // Color based on thermal status (green to red) + val red = (thermalStatus * 255).toInt() + val green = ((1f - thermalStatus) * 255).toInt() val color = android.graphics.Color.rgb(red, green, 0) binding.showThermalsText.setTextColor(color) - binding.showThermalsText.text = String.format( - "%s\n%.1f°C • %.1f°F", - progressBar, - temperature, - fahrenheit - ) + binding.showThermalsText.text = String.format("%.1f°C • %.1f°F", temperature, fahrenheit) + } + } + + private fun updateRamOverlay() { + val showOverlay = BooleanSetting.SHOW_RAM_OVERLAY.getBoolean() + binding.showRamText.setVisible(showOverlay) + if (showOverlay) { + ramStatsUpdater = { + if (emulationViewModel.emulationStarted.value && + !emulationViewModel.isEmulationStopping.value + ) { + val runtime = Runtime.getRuntime() + val nativeHeapSize = Debug.getNativeHeapSize() + val nativeHeapFreeSize = Debug.getNativeHeapFreeSize() + val nativeHeapUsed = nativeHeapSize - nativeHeapFreeSize + + val usedMemInMB = nativeHeapUsed / 1048576L + val maxMemInMB = nativeHeapSize / 1048576L + val percentUsed = (nativeHeapUsed.toFloat() / nativeHeapSize.toFloat() * 100f) + + // Color interpolation from green to red based on usage percentage + val normalizedUsage = (percentUsed / 100f).coerceIn(0f, 1f) + val red = (normalizedUsage * 255).toInt() + val green = ((1f - normalizedUsage) * 255).toInt() + val color = Color.rgb(red, green, 0) + + binding.showRamText.setTextColor(color) + binding.showRamText.text = String.format( + "\nRAM: %d/%d MB (%.1f%%)", + usedMemInMB, + maxMemInMB, + percentUsed + ) + ramStatsUpdateHandler.postDelayed(ramStatsUpdater!!, 1000) + } + } + ramStatsUpdateHandler.post(ramStatsUpdater!!) + } else { + if (ramStatsUpdater != null) { + ramStatsUpdateHandler.removeCallbacks(ramStatsUpdater!!) + } } } @@ -723,6 +757,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { BooleanSetting.SHOW_PERFORMANCE_OVERLAY.getBoolean() findItem(R.id.thermal_indicator).isChecked = BooleanSetting.SHOW_THERMAL_OVERLAY.getBoolean() + findItem(R.id.ram_meter).apply { + isChecked = BooleanSetting.SHOW_RAM_OVERLAY.getBoolean() + isEnabled = false // This grays out the option + } findItem(R.id.menu_rel_stick_center).isChecked = BooleanSetting.JOYSTICK_REL_CENTER.getBoolean() findItem(R.id.menu_dpad_slide).isChecked = BooleanSetting.DPAD_SLIDE.getBoolean() @@ -749,6 +787,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { true } + R.id.ram_meter -> { + // Do nothing since it's disabled + true + } + R.id.menu_edit_overlay -> { binding.drawerLayout.close() binding.surfaceInputOverlay.requestFocus() diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index 00baf86a9..2dba36990 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: 2025 Citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once @@ -51,7 +52,7 @@ struct Values { Settings::Setting<s32> theme{linkage, 0, "theme", Settings::Category::Android}; Settings::Setting<s32> theme_mode{linkage, -1, "theme_mode", Settings::Category::Android}; - Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds", + Settings::Setting<bool> black_backgrounds{linkage, true, "black_backgrounds", Settings::Category::Android}; // Input/performance overlay settings @@ -67,8 +68,10 @@ 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::Setting<bool> show_thermal_overlay{linkage, true, "show_thermal_overlay", Settings::Category::Overlay}; + Settings::Setting<bool> show_ram_overlay{linkage, true, "show_ram_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}; 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 df91a08c5..fe028e028 100644 --- a/src/android/app/src/main/res/layout/fragment_emulation.xml +++ b/src/android/app/src/main/res/layout/fragment_emulation.xml @@ -171,6 +171,21 @@ </FrameLayout> + <com.google.android.material.textview.MaterialTextView + android:id="@+id/show_ram_text" + style="@style/TextAppearance.Material3.BodySmall" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="left" + android:layout_marginTop="24dp" + android:clickable="false" + android:focusable="false" + android:textColor="@android:color/white" + android:shadowColor="@android:color/black" + android:shadowRadius="3" + android:layout_below="@id/show_fps_text" + tools:ignore="RtlHardcoded" /> + </androidx.coordinatorlayout.widget.CoordinatorLayout> <com.google.android.material.navigation.NavigationView 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 a9e807427..d601421a7 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 @@ -12,6 +12,11 @@ android:checkable="true" /> <item + android:id="@+id/ram_meter" + android:title="@string/emulation_ram_meter" + android:checkable="true" /> + + <item android:id="@+id/menu_edit_overlay" android:title="@string/emulation_touch_overlay_edit" /> diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 5133fa98e..ce2b21bf1 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -480,6 +480,7 @@ <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_ram_meter">RAM meter</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> |