MCPcopy Create free account
hub / github.com/clementgallet/libTAS / exitFrameBoundary

Method exitFrameBoundary

src/library/DeterministicTimer.cpp:276–334  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

274}
275
276void DeterministicTimer::exitFrameBoundary()
277{
278 if (Global::shared_config.debug_state & SharedConfig::DEBUG_UNCONTROLLED_TIME)
279 return NonDeterministicTimer::get().exitFrameBoundary();
280
281 LOGTRACE(LCF_TIMEGET);
282
283 /* Reset the counts of each time get function */
284 for (int i = 0; i < SharedConfig::TIMETYPE_NUMTRACKEDTYPES; i++) {
285 main_gettimes[i] = 0;
286 sec_gettimes[i] = 0;
287 }
288
289 /* We sleep the right amount of time so that the game runs at normal speed */
290
291 /* Get the current actual time */
292 TimeHolder currentTime = TimeHolder::now();
293
294 /* If we are not fast forwarding, and not the first frame,
295 * then we wait the delta amount of time.
296 */
297 if (Global::shared_config.running && !(Global::shared_config.fastforward && (Global::shared_config.fastforward_mode & SharedConfig::FF_SLEEP))) {
298 PROFILE_SCOPE("Sleep", PROFILER_INFO_FRAME);
299 PROFILE_PAUSE(PAUSE_ON_SLEEP);
300
301 TimeHolder desiredTime = lastEnterTime + baseTimeIncrement * Global::shared_config.speed_divisor;
302
303 TimeHolder sleepTimee = desiredTime - currentTime;
304 LOG(LL_DEBUG, LCF_TIMESET, "sleep for %u.%09u", sleepTimee.tv_sec, sleepTimee.tv_nsec);
305
306 /* Call the real nanosleep function */
307 perfTimer.switchTimer(PerfTimer::IdleTimer);
308#ifdef __unix__
309 NATIVECALL(clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &desiredTime, NULL));
310#else
311 /* nanosleep() uses relative time */
312 TimeHolder sleepTime = desiredTime - currentTime;
313 NATIVECALL(nanosleep(&sleepTime, NULL));
314#endif
315 perfTimer.switchTimer(PerfTimer::FrameTimer);
316
317 /* We try to keep a contant fps, so we set the last enter time to the
318 * desired time, so that if the sleep time was not perfect, or the frame
319 * took too long to process, we may compensate on future frames. This
320 * needs a threshold, otherwise we will constantly try to catch up, and
321 * no sleep will happen */
322 TimeHolder thresholdTime = lastEnterTime + baseTimeIncrement * (Global::shared_config.speed_divisor * 10); // Arbitrary value
323
324 if (currentTime > thresholdTime) {
325 lastEnterTime = currentTime;
326 }
327 else {
328 lastEnterTime = desiredTime;
329 }
330 }
331
332 insideFrameBoundary = false;
333 frame_mutex.unlock();

Callers 1

frameBoundaryFunction · 0.45

Calls 4

clock_nanosleepFunction · 0.85
nanosleepFunction · 0.85
switchTimerMethod · 0.80
unlockMethod · 0.45

Tested by

no test coverage detected