mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-10 12:22:12 -04:00
feat: FPS Limiter (#1446)
* Add interpolation frame rate cap * wip: reworked framelimiter Based on my testing this is a bit more stable in frametimes. * wip: efficiency improvement + windows build fix Significantly improve efficiency by using a hybrid approach. * wip: UI changes * wip: end frame AFTER limiting * wip: remove unused include * wip: minor ui code change Makes it easier to remove/add presets * Simplify Limiter UI - Change enableFrameInterpolation to an enum with off/capped/unlimited values - Simplify the UI to use 2 settings (unlock framerate + a max value entry) * wip: slight limiter simplification * wip: implement review suggestions * wip: fix syntax error * wip: revert enum order + replace old checks * Fix compile error --------- Co-authored-by: SailorSnoW <sailorsnow@pm.me> Co-authored-by: Loïs <49660929+SailorSnoW@users.noreply.github.com> Co-authored-by: SuperDude88 <82904174+SuperDude88@users.noreply.github.com> Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
+23
-3
@@ -28,6 +28,7 @@
|
||||
#include "d/d_s_logo.h"
|
||||
#include "d/d_s_menu.h"
|
||||
#include "d/d_s_play.h"
|
||||
#include "dusk/time.h"
|
||||
#include "f_ap/f_ap_game.h"
|
||||
#include "f_op/f_op_msg.h"
|
||||
#include "m_Do/m_Do_MemCard.h"
|
||||
@@ -279,8 +280,9 @@ void main01(void) {
|
||||
const auto pacing = dusk::game_clock::advance_main_loop();
|
||||
if (pacing.is_interpolating) {
|
||||
if (pacing.sim_ticks_to_run > 0) {
|
||||
dusk::frame_interp::begin_frame(true, true, 0.0f);
|
||||
dusk::frame_interp::begin_frame(dusk::getSettings().game.enableFrameInterpolation, true, 0.0f);
|
||||
dusk::frame_interp::set_ui_tick_pending(true);
|
||||
|
||||
for (int sim_tick = 0; sim_tick < pacing.sim_ticks_to_run; ++sim_tick) {
|
||||
dusk::frame_interp::begin_sim_tick();
|
||||
mDoCPd_c::read();
|
||||
@@ -291,7 +293,7 @@ void main01(void) {
|
||||
}
|
||||
}
|
||||
|
||||
dusk::frame_interp::begin_frame(true, false,
|
||||
dusk::frame_interp::begin_frame(dusk::getSettings().game.enableFrameInterpolation, false,
|
||||
dusk::game_clock::sample_interpolation_step());
|
||||
dusk::frame_interp::interpolate();
|
||||
dusk::frame_interp::begin_presentation_camera();
|
||||
@@ -301,7 +303,7 @@ void main01(void) {
|
||||
dusk::frame_interp::end_presentation_camera();
|
||||
dusk::frame_interp::set_ui_tick_pending(false);
|
||||
} else {
|
||||
dusk::frame_interp::begin_frame(false, true, 0.0f);
|
||||
dusk::frame_interp::begin_frame(dusk::FrameInterpMode::Off, true, 0.0f);
|
||||
dusk::frame_interp::set_ui_tick_pending(true);
|
||||
|
||||
// Game Inputs
|
||||
@@ -315,8 +317,26 @@ void main01(void) {
|
||||
mDoAud_Execute();
|
||||
}
|
||||
|
||||
static Limiter main_loop_limiter;
|
||||
static double last_fps_setting = 0.0;
|
||||
static Limiter::duration_t target_ns = 0;
|
||||
|
||||
if (dusk::getSettings().game.enableFrameInterpolation.getValue() == dusk::FrameInterpMode::Capped && !dusk::getTransientSettings().skipFrameRateLimit) {
|
||||
double current_fps = dusk::getSettings().video.maxFrameRate.getValue();
|
||||
if (current_fps != last_fps_setting) {
|
||||
last_fps_setting = current_fps;
|
||||
target_ns = static_cast<Limiter::duration_t>(1'000'000'000.0 / current_fps);
|
||||
}
|
||||
|
||||
Limiter::duration_t sleepTime = main_loop_limiter.Sleep(target_ns);
|
||||
dusk::frameUsagePct = 100.0f * (1.0f - static_cast<float>(sleepTime) / static_cast<float>(target_ns));
|
||||
} else {
|
||||
main_loop_limiter.Reset();
|
||||
}
|
||||
|
||||
aurora_end_frame();
|
||||
|
||||
|
||||
FrameMark;
|
||||
|
||||
#ifdef DUSK_DISCORD
|
||||
|
||||
Reference in New Issue
Block a user