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 c16de8f7a9..f43e5f9dd6 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
@@ -16,6 +16,7 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
CORE_SYNC_CORE_SPEED("sync_core_speed"),
RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
USE_FAST_CPU_TIME("use_fast_cpu_time"),
+ USE_CUSTOM_CPU_TICKS("use_custom_cpu_ticks"),
USE_DOCKED_MODE("use_docked_mode"),
USE_AUTO_STUB("use_auto_stub"),
RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache"),
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt
index aa1e1b578e..c2bc0d2b0e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt
@@ -37,6 +37,7 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
MEMORY_LAYOUT("memory_layout_mode"),
FSR_SHARPENING_SLIDER("fsr_sharpening_slider"),
FAST_CPU_TIME("fast_cpu_time"),
+ CPU_TICKS("cpu_ticks"),
FAST_GPU_TIME("fast_gpu_time"),
CABINET_APPLET("cabinet_applet_mode"),
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 bdfafb82d8..84c9f419a4 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
@@ -580,6 +580,22 @@ abstract class SettingsItem(
valuesId = R.array.clockValues
)
)
+ put(
+ SwitchSetting(
+ BooleanSetting.USE_CUSTOM_CPU_TICKS,
+ titleId = R.string.custom_cpu_ticks,
+ descriptionId = R.string.custom_cpu_ticks_description
+ )
+ )
+ put(
+ SliderSetting(
+ IntSetting.CPU_TICKS,
+ titleId = R.string.cpu_ticks,
+ descriptionId = 0,
+ min = 77,
+ max = 65535
+ )
+ )
put(
SwitchSetting(
BooleanSetting.RENDERER_REACTIVE_FLUSHING,
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 7ca75ed9e2..24214c3895 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
@@ -448,6 +448,8 @@ class SettingsFragmentPresenter(
add(HeaderSetting(R.string.veil_misc))
add(BooleanSetting.USE_FAST_CPU_TIME.key)
add(IntSetting.FAST_CPU_TIME.key)
+ add(BooleanSetting.USE_CUSTOM_CPU_TICKS.key)
+ add(IntSetting.CPU_TICKS.key)
add(BooleanSetting.USE_LRU_CACHE.key)
add(BooleanSetting.CORE_SYNC_CORE_SPEED.key)
add(IntSetting.MEMORY_LAYOUT.key)
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 5c41f6650a..10d02b4b82 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -90,6 +90,9 @@
Enable or disable the Least Recently Used (LRU) cache, increasing performance by saving CPU process usage. Some games have issue with it, notably TotK 1.2.1, so disable if the game doesn\'t boot or crashes randomly.
Fast CPU Time
Forces the emulated CPU to run at a higher clock, reducing certain FPS limiters. This option is hacky and may cause issues, and weaker CPUs may see reduced performance.
+ Custom CPU Ticks
+ Set a custom value of CPU ticks. Higher values can increase performance, but may also cause the game to freeze. A range of 77–21000 is recommended.
+ Ticks
CPU Clock
Use Boost (1700MHz) to run at the Switch\'s highest native clock, or Fast (2000MHz) to run at 2x clock.
Memory Layout
diff --git a/src/common/settings.h b/src/common/settings.h
index 3a27546537..b6e091ab50 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -259,6 +259,25 @@ struct Values {
true,
&use_fast_cpu_time};
+ SwitchableSetting use_custom_cpu_ticks{linkage,
+ false,
+ "use_custom_cpu_ticks",
+ Category::Cpu,
+ Specialization::Paired,
+ true,
+ true};
+
+ SwitchableSetting cpu_ticks{linkage,
+ 16000,
+ 77,
+ 65535,
+ "cpu_ticks",
+ Category::Cpu,
+ Specialization::Countable,
+ true,
+ true,
+ &use_custom_cpu_ticks};
+
SwitchableSetting cpu_debug_mode{linkage, false, "cpu_debug_mode", Category::CpuDebug};
Setting cpuopt_page_tables{linkage, true, "cpuopt_page_tables", Category::CpuDebug};
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index a8ffdb3cb7..3bd0d57e4d 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -172,7 +172,9 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr& event_type,
}
void CoreTiming::AddTicks(u64 ticks_to_add) {
- cpu_ticks += ticks_to_add;
+ cpu_ticks = Settings::values.use_custom_cpu_ticks.GetValue()
+ ? Settings::values.cpu_ticks.GetValue()
+ : cpu_ticks + ticks_to_add;
downcount -= static_cast(cpu_ticks);
}
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 31112e3aa7..42bf5d21d5 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -73,8 +73,9 @@ void ConfigureCpu::Setup(const ConfigurationShared::Builder& builder) {
} else if (setting->Id() == Settings::values.cpu_backend.Id()) {
backend_layout->addWidget(widget);
backend_combobox = widget->combobox;
- } else if (setting->Id() == Settings::values.fast_cpu_time.Id()
- || setting->Id() == Settings::values.use_fast_cpu_time.Id()) {
+ } else if (setting->Id() == Settings::values.fast_cpu_time.Id()) {
+ ui->general_layout->addWidget(widget);
+ } else if (setting->Id() == Settings::values.cpu_ticks.Id()) {
ui->general_layout->addWidget(widget);
} else {
// Presently, all other settings here are unsafe checkboxes
diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp
index fe3ec401aa..28eb2108f8 100644
--- a/src/yuzu/configuration/shared_translation.cpp
+++ b/src/yuzu/configuration/shared_translation.cpp
@@ -106,6 +106,13 @@ std::unique_ptr InitializeTranslations(QWidget* parent)
tr("Overclocks the emulated CPU to remove some FPS limiters. Weaker CPUs may see reduced performance, "
"and certain games may behave improperly.\nUse Boost (1700MHz) to run at the Switch's highest native "
"clock, or Fast (2000MHz) to run at 2x clock."));
+
+ INSERT(Settings, use_custom_cpu_ticks, QString(), QString());
+ INSERT(Settings,
+ cpu_ticks,
+ tr("Custom CPU Ticks"),
+ tr("Set a custom value of CPU ticks. Higher values can increase performance, but may "
+ "also cause the game to freeze. A range of 77–21000 is recommended."));
INSERT(Settings, cpu_backend, tr("Backend:"), QString());
// Cpu Debug