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 34f417434f..4d5208c4c7 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
@@ -10,6 +10,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
CPU_DEBUG_MODE("cpu_debug_mode"),
FASTMEM("cpuopt_fastmem"),
FASTMEM_EXCLUSIVES("cpuopt_fastmem_exclusives"),
+ CORE_SYNC_CORE_SPEED("sync_core_speed"),
RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
USE_DOCKED_MODE("use_docked_mode"),
RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache"),
@@ -27,9 +28,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
SHOW_INPUT_OVERLAY("show_input_overlay"),
TOUCHSCREEN("touchscreen"),
SHOW_THERMAL_OVERLAY("show_thermal_overlay"),
- ENABLE_FRAME_INTERPOLATION("enable_frame_interpolation"),
- ENABLE_FRAME_SKIPPING("enable_frame_skipping"),
- CORE_USE_MULTI_CORE("use_multi_core");
+ ENABLE_FRAME_INTERPOLATION("enable_frame_interpolation"),
+ ENABLE_FRAME_SKIPPING("enable_frame_skipping");
external fun isFrameSkippingEnabled(): Boolean
external fun isFrameInterpolationEnabled(): Boolean
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
index 2780b550e7..0868da00a5 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
@@ -206,6 +206,25 @@ abstract class SettingsItem(
override fun reset() = BooleanSetting.ENABLE_FRAME_SKIPPING.reset()
}
+ val syncCoreSpeedSetting = object : AbstractBooleanSetting {
+ override val key = BooleanSetting.CORE_SYNC_CORE_SPEED.key
+
+ override fun getBoolean(needsGlobal: Boolean): Boolean {
+ return BooleanSetting.CORE_SYNC_CORE_SPEED.getBoolean(needsGlobal)
+ }
+
+ override fun setBoolean(value: Boolean) {
+ BooleanSetting.CORE_SYNC_CORE_SPEED.setBoolean(value)
+ }
+
+ override val defaultValue = BooleanSetting.CORE_SYNC_CORE_SPEED.defaultValue
+
+ override fun getValueAsString(needsGlobal: Boolean): String =
+ BooleanSetting.CORE_SYNC_CORE_SPEED.getValueAsString(needsGlobal)
+
+ override fun reset() = BooleanSetting.CORE_SYNC_CORE_SPEED.reset()
+ }
+
put(
SwitchSetting(
BooleanSetting.ENABLE_FRAME_INTERPOLATION,
@@ -230,6 +249,14 @@ abstract class SettingsItem(
)
)
+ put(
+ SwitchSetting(
+ syncCoreSpeedSetting,
+ titleId = R.string.use_sync_core,
+ descriptionId = R.string.use_sync_core_description
+ )
+ )
+
put(
SingleChoiceSetting(
IntSetting.REGION_INDEX,
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index 1af631ce1a..fe31b4054e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -159,6 +159,7 @@ class SettingsFragmentPresenter(
add(StringSetting.DEVICE_NAME.key)
add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
add(ShortSetting.RENDERER_SPEED_LIMIT.key)
+ add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
add(BooleanSetting.USE_DOCKED_MODE.key)
add(IntSetting.REGION_INDEX.key)
add(IntSetting.LANGUAGE_INDEX.key)
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 51495df2fc..263acda9fa 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -217,6 +217,10 @@
CPU accuracy
%1$s%2$s
+
+ Synchronize Core Speed
+ Synchronize the core tick speed to the maximum speed percentage to improve performance without altering the games actual speed.
+
Device name
Docked Mode
diff --git a/src/common/settings.h b/src/common/settings.h
index e0788abda6..9eb04897da 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -210,6 +210,7 @@ struct Values {
true,
true,
&use_speed_limit};
+ SwitchableSetting sync_core_speed{linkage, false, "sync_core_speed", Category::Core, Specialization::Default};
// Cpu
SwitchableSetting cpu_backend{linkage,
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 1abfa920c4..3d67ab9f5c 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -14,6 +14,7 @@
#include "common/x64/cpu_wait.h"
#endif
+#include "common/settings.h"
#include "common/microprofile.h"
#include "core/core_timing.h"
#include "core/hardware_properties.h"
@@ -184,10 +185,20 @@ void CoreTiming::ResetTicks() {
}
u64 CoreTiming::GetClockTicks() const {
+ u64 fres;
if (is_multicore) [[likely]] {
- return clock->GetCNTPCT();
+ fres = clock->GetCNTPCT();
+ } else {
+ fres = Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
+ }
+
+ if (Settings::values.sync_core_speed.GetValue()) {
+ const double ticks = static_cast(fres);
+ const double speed_limit = static_cast(Settings::values.speed_limit.GetValue())*0.01;
+ return static_cast(ticks/speed_limit);
+ } else {
+ return fres;
}
- return Common::WallClock::CPUTickToCNTPCT(cpu_ticks);
}
u64 CoreTiming::GetGPUTicks() const {
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index 0549e8ae44..e80319cddf 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -71,6 +71,10 @@ std::unique_ptr InitializeTranslations(QWidget* parent) {
"faster or not.\n200% for a 30 FPS game is 60 FPS, and for a "
"60 FPS game it will be 120 FPS.\nDisabling it means unlocking the framerate to the "
"maximum your PC can reach."));
+ INSERT(Settings, sync_core_speed, tr("Synchronize Core Speed"),
+ tr("Synchronizes CPU core speed with the game's maximum rendering speed to boost FPS without affecting game speed (animations, physics, etc.).\n"
+ "Compatibility varies by game; many (especially older ones) may not respond well.\n"
+ "Can help reduce stuttering at lower framerates."));
// Cpu
INSERT(Settings, cpu_accuracy, tr("Accuracy:"),