added fps option in settings

This commit is contained in:
izzy2lost
2026-03-04 03:23:12 -05:00
parent 542bebce50
commit e4dba13851
6 changed files with 106 additions and 1 deletions
+14
View File
@@ -575,6 +575,7 @@ cleanup:
struct EmulatorSettings {
int surface_scale = 1; // 1, 2, or 3
int frame_rate_limit = 60; // 30 or 60
std::string tcg_thread = "multi"; // "single" or "multi"
bool use_dsp = false;
bool hrtf = true;
@@ -658,6 +659,13 @@ static bool WriteConfigToml(const std::string& config_path,
perf->insert_or_assign("hard_fpu", settings.hard_fpu);
android->insert_or_assign("tcg_thread",
(settings.tcg_thread == "single") ? "single" : "multi");
{
int frame_rate_limit = settings.frame_rate_limit;
if (frame_rate_limit != 30 && frame_rate_limit != 60) {
frame_rate_limit = 60;
}
android->insert_or_assign("frame_rate_limit", frame_rate_limit);
}
if (!audio_vp->contains("num_workers")) {
audio_vp->insert_or_assign("num_workers", 0);
}
@@ -790,6 +798,12 @@ static SetupFiles SyncSetupFiles() {
EmulatorSettings emuSettings;
emuSettings.surface_scale = GetPrefInt(env, activity, "setting_surface_scale", 1);
emuSettings.frame_rate_limit =
GetPrefInt(env, activity, "setting_frame_rate_limit", 60);
if (emuSettings.frame_rate_limit != 30 &&
emuSettings.frame_rate_limit != 60) {
emuSettings.frame_rate_limit = 60;
}
emuSettings.use_dsp = GetPrefBool(env, activity, "setting_use_dsp", false);
emuSettings.hrtf = GetPrefBool(env, activity, "setting_hrtf", true);
emuSettings.cache_shaders = GetPrefBool(env, activity, "setting_cache_shaders", true);
@@ -213,6 +213,7 @@ bool xemu_settings_load(void)
setenv("XEMU_ANDROID_TCG_TUNING", "1", 1);
setenv("XEMU_ANDROID_TCG_THREAD", "multi", 1);
setenv("XEMU_ANDROID_TCG_TB_SIZE", "128", 1);
setenv("XEMU_ANDROID_TARGET_FPS", "60", 1);
const char *path = xemu_settings_get_path();
if (!path || *path == '\0') {
@@ -327,6 +328,16 @@ bool xemu_settings_load(void)
tcg_thread->c_str());
}
}
if (auto frame_rate_limit =
android_cfg["frame_rate_limit"].value<int64_t>()) {
int fps = (int)*frame_rate_limit;
if (fps != 30 && fps != 60) {
fps = 60;
}
char fps_str[16];
snprintf(fps_str, sizeof(fps_str), "%d", fps);
setenv("XEMU_ANDROID_TARGET_FPS", fps_str, 1);
}
if (auto tcg_tb_size = android_cfg["tcg_tb_size"].value<int64_t>()) {
int tb_size = (int)*tcg_tb_size;
if (tb_size < 32) {
@@ -40,6 +40,7 @@ class SettingsActivity : AppCompatActivity() {
val btn2x = findViewById<MaterialButton>(R.id.btn_scale_2x)
val btn3x = findViewById<MaterialButton>(R.id.btn_scale_3x)
val toggleDisplayMode = findViewById<MaterialButtonToggleGroup>(R.id.toggle_display_mode)
val toggleFrameRate = findViewById<MaterialButtonToggleGroup>(R.id.toggle_frame_rate)
val toggleThread = findViewById<MaterialButtonToggleGroup>(R.id.toggle_tcg_thread)
val btnMulti = findViewById<MaterialButton>(R.id.btn_thread_multi)
val btnSingle = findViewById<MaterialButton>(R.id.btn_thread_single)
@@ -68,6 +69,12 @@ class SettingsActivity : AppCompatActivity() {
else -> toggleDisplayMode.check(R.id.btn_display_stretch)
}
val frameRateLimit = prefs.getInt("setting_frame_rate_limit", 60)
when (frameRateLimit) {
30 -> toggleFrameRate.check(R.id.btn_fps_30)
else -> toggleFrameRate.check(R.id.btn_fps_60)
}
tvVulkanDriverName.text =
prefs.getString("setting_vulkan_driver_name", null)
?: getString(R.string.settings_vulkan_driver_none)
@@ -113,6 +120,11 @@ class SettingsActivity : AppCompatActivity() {
R.id.btn_scale_3x -> 3
else -> 1
}
val selectedFrameRate = when (toggleFrameRate.checkedButtonId) {
R.id.btn_fps_30 -> 30
R.id.btn_fps_60 -> 60
else -> 60
}
val selectedThread = when (toggleThread.checkedButtonId) {
R.id.btn_thread_single -> "single"
else -> "multi"
@@ -126,6 +138,7 @@ class SettingsActivity : AppCompatActivity() {
val edit = prefs.edit()
.putInt("setting_display_mode", selectedDisplayMode)
.putInt("setting_surface_scale", selectedScale)
.putInt("setting_frame_rate_limit", selectedFrameRate)
.putString("setting_tcg_thread", selectedThread)
.putBoolean("setting_use_dsp", switchDsp.isChecked)
.putBoolean("setting_hrtf", switchHrtf.isChecked)
@@ -140,6 +140,40 @@
</com.google.android.material.button.MaterialButtonToggleGroup>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="6dp"
android:text="@string/settings_frame_rate_limit"
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
android:textColor="@color/xemu_text_muted" />
<com.google.android.material.button.MaterialButtonToggleGroup
android:id="@+id/toggle_frame_rate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:selectionRequired="true"
app:singleSelection="true">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_fps_30"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/settings_frame_rate_limit_30" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_fps_60"
style="?attr/materialButtonOutlinedStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/settings_frame_rate_limit_60" />
</com.google.android.material.button.MaterialButtonToggleGroup>
<!-- ── VULKAN DRIVER ── -->
<TextView
android:layout_width="match_parent"
@@ -89,6 +89,9 @@
<string name="settings_display_mode_stretch">Stretch</string>
<string name="settings_display_mode_4_3">4:3</string>
<string name="settings_display_mode_16_9">16:9</string>
<string name="settings_frame_rate_limit">Frame Rate Limit</string>
<string name="settings_frame_rate_limit_30">30 FPS</string>
<string name="settings_frame_rate_limit_60">60 FPS</string>
<string name="settings_resolution_scale">Internal Resolution Scale</string>
<string name="settings_resolution_scale_1x">1x (Native 480p)</string>
<string name="settings_resolution_scale_2x">2x (960p)</string>
+31 -1
View File
@@ -132,6 +132,8 @@ static bool g_android_use_hud = false;
static bool g_android_paused = false;
static bool g_android_should_quit = false;
static uint64_t g_android_frame_counter = 0;
static int g_android_target_fps = 60;
static int64_t g_android_frame_interval_ns = 16666666;
static GLuint g_android_blit_prog;
static GLuint g_android_blit_vao;
static GLuint g_android_blit_vbo;
@@ -208,6 +210,29 @@ void xemu_android_set_display_mode_setting(int mode)
g_android_display_mode = mode;
}
static void xemu_android_refresh_frame_limit_from_env(void)
{
int fps = 60;
const char *fps_env = SDL_getenv("XEMU_ANDROID_TARGET_FPS");
if (fps_env && fps_env[0] != '\0') {
char *endptr = NULL;
long parsed = strtol(fps_env, &endptr, 10);
if (endptr != fps_env && (!endptr || *endptr == '\0')) {
fps = (int)parsed;
}
}
if (fps != 30 && fps != 60) {
fps = 60;
}
g_android_target_fps = fps;
g_android_frame_interval_ns = 1000000000LL / g_android_target_fps;
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"android: target FPS set to %d",
g_android_target_fps);
}
static bool android_blit_init(void)
{
if (g_android_blit_prog) {
@@ -1377,6 +1402,7 @@ void xemu_android_display_loop(void)
}
}
#ifdef __ANDROID__
xemu_android_refresh_frame_limit_from_env();
SDL_GL_SetSwapInterval(g_config.display.window.vsync ? 1 : 0);
if (g_android_use_hud) {
xemu_hud_init(m_window, m_context);
@@ -1825,10 +1851,14 @@ void sdl2_gl_refresh(DisplayChangeListener *dcl)
qemu_mutex_unlock_main_loop();
/*
* Throttle to make sure swaps happen at 60Hz
* Throttle to keep swaps at the target frame rate.
*/
static int64_t last_update = 0;
#ifdef __ANDROID__
int64_t deadline = last_update + g_android_frame_interval_ns;
#else
int64_t deadline = last_update + 16666666;
#endif
#ifdef DEBUG_XEMU_C
int64_t sleep_acc = 0;