diff --git a/src/citron/configuration/shared_translation.cpp b/src/citron/configuration/shared_translation.cpp index 393f49daf..641aa4f41 100644 --- a/src/citron/configuration/shared_translation.cpp +++ b/src/citron/configuration/shared_translation.cpp @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "citron/configuration/shared_translation.h" @@ -146,6 +147,11 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { INSERT( Settings, use_asynchronous_gpu_emulation, tr("Use asynchronous GPU emulation"), tr("Uses an extra CPU thread for rendering.\nThis option should always remain enabled.")); + INSERT( + Settings, respect_present_interval_zero, tr("Respect present interval 0 for unlocked FPS"), + tr("When enabled, present interval 0 will be used for games requesting unlocked FPS.\n" + "This matches console behavior more closely, but may cause higher battery usage and frame pacing issues.\n" + "When disabled (default), present interval 0 is capped at 120FPS to conserve battery.")); INSERT(Settings, nvdec_emulation, tr("NVDEC emulation:"), tr("Specifies how videos should be decoded.\nIt can either use the CPU or the GPU for " "decoding, or perform no decoding at all (black screen on videos).\n" diff --git a/src/common/settings.h b/src/common/settings.h index 47ab9d131..fcc62691d 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -284,6 +284,8 @@ struct Values { Category::Renderer}; SwitchableSetting use_asynchronous_gpu_emulation{ linkage, true, "use_asynchronous_gpu_emulation", Category::Renderer}; + SwitchableSetting respect_present_interval_zero{ + linkage, false, "respect_present_interval_zero", Category::Renderer}; SwitchableSetting accelerate_astc{linkage, #ifdef ANDROID AstcDecodeMode::Cpu, diff --git a/src/core/hle/service/nvnflinger/hardware_composer.cpp b/src/core/hle/service/nvnflinger/hardware_composer.cpp index f2dfe85a9..9ed4291b5 100644 --- a/src/core/hle/service/nvnflinger/hardware_composer.cpp +++ b/src/core/hle/service/nvnflinger/hardware_composer.cpp @@ -1,9 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2025 citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #include #include "common/microprofile.h" +#include "common/settings.h" #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" #include "core/hle/service/nvnflinger/buffer_item.h" #include "core/hle/service/nvnflinger/buffer_item_consumer.h" @@ -17,6 +19,14 @@ namespace { s32 NormalizeSwapInterval(f32* out_speed_scale, s32 swap_interval) { if (swap_interval <= 0) { + // If swap_interval is 0 and setting enabled, respect it as unlocked FPS + if (swap_interval == 0 && Settings::values.respect_present_interval_zero.GetValue()) { + if (out_speed_scale) { + *out_speed_scale = 1.0f; + } + return 0; + } + // As an extension, treat nonpositive swap interval as speed multiplier. if (out_speed_scale) { *out_speed_scale = 2.f * static_cast(1 - swap_interval);