Time revamp (#2304)

* Don't Use OSCalendarTime for Speedrun Timing

- Shouldn't rely on OSTicksToCalendarTime since it will be changed to handle time zone conversion, and that doesn't make sense on elapsed time

* Use OSGetSystemTime Extension

- Fixes desyncing issues with save file time and a couple other odd instances, particularly on mobile platforms that suspend apps

* Time revamp

* Update aurora

* Split IGT/RTA calculations

* Shift-Turbo to slow down

---------

Co-authored-by: SuperDude88 <82904174+SuperDude88@users.noreply.github.com>
This commit is contained in:
Luke Street
2026-08-14 00:07:54 -06:00
committed by GitHub
parent 045fbd9b46
commit 0f5a248401
24 changed files with 248 additions and 148 deletions
+34 -20
View File
@@ -233,7 +233,7 @@ void main01(void) {
OSReport("Entering Main Loop (main01)...\n");
dusk::game_clock::ensure_initialized();
dusk::game_clock::initialize();
do {
// 1. Update Window Events
@@ -248,7 +248,7 @@ void main01(void) {
break;
case AURORA_UNPAUSED:
dusk::audio::SetPaused(false);
dusk::game_clock::reset_frame_timer();
dusk::game_clock::reset();
dusk::mouse::on_focus_gained();
break;
case AURORA_SDL_EVENT:
@@ -290,46 +290,56 @@ void main01(void) {
dusk::ui::update();
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(dusk::getSettings().game.enableFrameInterpolation, true, 0.0f);
const auto timing = dusk::game_clock::advance();
const auto interpolationMode = dusk::getSettings().game.enableFrameInterpolation.getValue();
if (timing.separatePresentation) {
if (timing.numSimTicks > 0) {
dusk::frame_interp::begin_frame(interpolationMode, 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();
for (int i = 0; i < timing.numSimTicks; ++i) {
if (timing.interpolating) {
dusk::frame_interp::begin_sim_tick();
}
dusk::game_clock::begin_sim_tick();
mDoCPd_c::read();
dusk::mouse::read();
dusk::gyro::read(pacing.sim_pace);
dusk::gyro::read(dusk::game_clock::kSimPeriod);
fapGm_Execute();
mDoAud_Execute();
dusk::game_clock::commit_sim_tick();
}
}
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();
// run draw functions for anything specially marked to handle interp
const float interpolationStep =
timing.interpolating ? dusk::game_clock::sample_interpolation_step() : 1.0f;
dusk::frame_interp::begin_frame(interpolationMode, false, interpolationStep);
if (timing.interpolating) {
dusk::frame_interp::interpolate();
dusk::frame_interp::begin_presentation_camera();
}
fpcM_DrawIterater((fpcM_DrawIteraterFunc)fpcM_Draw);
cAPIGph_Painter();
dusk::frame_interp::end_presentation_camera();
if (timing.interpolating) {
dusk::frame_interp::end_presentation_camera();
}
dusk::frame_interp::set_ui_tick_pending(false);
} else {
dusk::frame_interp::begin_frame(dusk::FrameInterpMode::Off, true, 0.0f);
dusk::frame_interp::set_ui_tick_pending(true);
dusk::game_clock::begin_sim_tick();
// Game Inputs
mDoCPd_c::read();
dusk::mouse::read();
dusk::gyro::read(pacing.presentation_dt_seconds);
dusk::gyro::read(timing.dt);
// EXECUTE GAME LOGIC & RENDER
// This calls mDoGph_Painter -> JFWDisplay -> GX Functions
fapGm_Execute();
mDoAud_Execute();
dusk::game_clock::commit_sim_tick();
}
aurora_end_frame();
@@ -345,7 +355,10 @@ void main01(void) {
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) {
if (dusk::getSettings().game.enableFrameInterpolation.getValue() ==
dusk::FrameInterpMode::Capped &&
!dusk::getTransientSettings().turboMode)
{
ZoneScopedN("Frame limiter");
double current_fps = dusk::getSettings().video.maxFrameRate.getValue();
if (current_fps != last_fps_setting) {
@@ -354,7 +367,8 @@ void main01(void) {
}
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));
dusk::frameUsagePct =
100.0f * (1.0f - static_cast<float>(sleepTime) / static_cast<float>(target_ns));
} else {
main_loop_limiter.Reset();
}
@@ -845,7 +859,7 @@ int game_main(int argc, char* argv[]) {
OSInit();
mDoMain::sPowerOnTime = OSGetTime();
mDoMain::sPowerOnTime = DUSK_IF_ELSE(OSGetSystemTime(), OSGetTime());
// Reset Data
static mDoRstData sResetData = {0};