Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix negative delta arguments #35617

Merged
merged 1 commit into from
Sep 6, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion main/main_timer_sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ int MainTimerSync::get_average_physics_steps(double &p_min, double &p_max) {
const double typical_lower = typical_physics_steps[i];
const double current_min = typical_lower / (i + 1);
if (current_min > p_max) {
return i; // bail out of further restrictions would void the interval
return i; // bail out if further restrictions would void the interval
} else if (current_min > p_min) {
p_min = current_min;
}
Expand Down Expand Up @@ -105,6 +105,12 @@ MainFrameTime MainTimerSync::advance_core(double p_physics_step, int p_physics_t
}
}

#ifdef DEBUG_ENABLED
if (max_typical_steps < 0) {
WARN_PRINT_ONCE("`max_typical_steps` is negative. This could hint at an engine bug or system timer misconfiguration.");
}
#endif

// try to keep it consistent with previous iterations
if (ret.physics_steps < min_typical_steps) {
const int max_possible_steps = floor((time_accum)*p_physics_ticks_per_second + get_physics_jitter_fix());
Expand All @@ -124,6 +130,10 @@ MainFrameTime MainTimerSync::advance_core(double p_physics_step, int p_physics_t
}
}

if (ret.physics_steps < 0) {
ret.physics_steps = 0;
}

time_accum -= ret.physics_steps * p_physics_step;

// keep track of accumulated step counts
Expand Down Expand Up @@ -151,6 +161,9 @@ MainFrameTime MainTimerSync::advance_checked(double p_physics_step, int p_physic
p_process_step = 1.0 / fixed_fps;
}

float min_output_step = p_process_step / 8;
min_output_step = MAX(min_output_step, 1E-6);

lawnjelly marked this conversation as resolved.
Show resolved Hide resolved
// compensate for last deficit
p_process_step += time_deficit;

Expand All @@ -177,9 +190,37 @@ MainFrameTime MainTimerSync::advance_checked(double p_physics_step, int p_physic
// last clamping: make sure time_accum is between 0 and p_physics_step for consistency between physics and process
ret.clamp_process_step(process_minus_accum, process_minus_accum + p_physics_step);

// all the operations above may have turned ret.p_process_step negative or zero, keep a minimal value
if (ret.process_step < min_output_step) {
ret.process_step = min_output_step;
}

// restore time_accum
time_accum = ret.process_step - process_minus_accum;

// forcing ret.process_step to be positive may trigger a violation of the
// promise that time_accum is between 0 and p_physics_step
#ifdef DEBUG_ENABLED
if (time_accum < -1E-7) {
WARN_PRINT_ONCE("Intermediate value of `time_accum` is negative. This could hint at an engine bug or system timer misconfiguration.");
}
#endif

if (time_accum > p_physics_step) {
const int extra_physics_steps = floor(time_accum * p_physics_ticks_per_second);
time_accum -= extra_physics_steps * p_physics_step;
ret.physics_steps += extra_physics_steps;
}

#ifdef DEBUG_ENABLED
if (time_accum < -1E-7) {
WARN_PRINT_ONCE("Final value of `time_accum` is negative. It should always be between 0 and `p_physics_step`. This hints at an engine bug.");
}
if (time_accum > p_physics_step + 1E-7) {
WARN_PRINT_ONCE("Final value of `time_accum` is larger than `p_physics_step`. It should always be between 0 and `p_physics_step`. This hints at an engine bug.");
}
#endif

// track deficit
time_deficit = p_process_step - ret.process_step;

Expand Down