diff --git a/common/framelimit.cpp b/common/framelimit.cpp index 8a202af5..64105dcd 100644 --- a/common/framelimit.cpp +++ b/common/framelimit.cpp @@ -48,12 +48,13 @@ void Frame_Limiter(FrameLimitFlags flags) #else auto frame_end = std::chrono::steady_clock::now(); #endif - int64_t _ms_per_tick = 1000 / Settings.Video.FrameLimit; - auto remaining = - _ms_per_tick - std::chrono::duration_cast(frame_end - frame_start).count(); - if (remaining > 0) { - ms_sleep(unsigned(remaining)); + unsigned int min_frame_time = 1000000 / Settings.Video.FrameLimit; + auto cur_frame_time = std::chrono::duration_cast(frame_end - frame_start).count(); + if (cur_frame_time < min_frame_time) { + frame_start += std::chrono::microseconds{min_frame_time}; + us_sleep(min_frame_time - cur_frame_time); + } else { + frame_start = frame_end; } - frame_start = std::chrono::steady_clock::now(); } } diff --git a/common/mssleep.h b/common/mssleep.h index ef0dc26d..9f7c8a66 100644 --- a/common/mssleep.h +++ b/common/mssleep.h @@ -16,6 +16,21 @@ #include #endif +/** + * Yield the current thread for at least us microseconds. + */ +static inline void us_sleep(unsigned us) +{ +#ifdef _WIN32 + Sleep((us + 999) / 1000); +#else + struct timespec ts; + ts.tv_sec = us / 1000000; + ts.tv_nsec = (us % 1000000) * 1000; + nanosleep(&ts, NULL); +#endif +} + /** * Yield the current thread for at least ms milliseconds. */