| 298 | Framework *Framework::tryGetInstance() { return instance; } |
| 299 | |
| 300 | void Framework::run(sp<Stage> initialStage) |
| 301 | { |
| 302 | size_t frameCount = Options::frameLimit.get(); |
| 303 | if (!createWindow) |
| 304 | { |
| 305 | LogError("Trying to run framework without window"); |
| 306 | return; |
| 307 | } |
| 308 | size_t frame = 0; |
| 309 | LogInfo("Program loop started"); |
| 310 | |
| 311 | auto target_frame_duration = |
| 312 | std::chrono::duration<int64_t, std::micro>(1000000 / Options::targetFPS.get()); |
| 313 | |
| 314 | p->ProgramStages.push(initialStage); |
| 315 | |
| 316 | this->renderer->setPalette(this->data->loadPalette("xcom3/ufodata/pal_06.dat")); |
| 317 | auto expected_frame_time = std::chrono::steady_clock::now(); |
| 318 | |
| 319 | bool frame_time_limited_warning_shown = false; |
| 320 | |
| 321 | while (!p->quitProgram) |
| 322 | { |
| 323 | auto frame_time_now = std::chrono::steady_clock::now(); |
| 324 | if (expected_frame_time > frame_time_now) |
| 325 | { |
| 326 | auto time_to_sleep = expected_frame_time - frame_time_now; |
| 327 | auto time_to_sleep_us = |
| 328 | std::chrono::duration_cast<std::chrono::microseconds>(time_to_sleep); |
| 329 | LogDebug("sleeping for %d us", time_to_sleep_us.count()); |
| 330 | std::this_thread::sleep_for(time_to_sleep); |
| 331 | continue; |
| 332 | } |
| 333 | expected_frame_time += target_frame_duration; |
| 334 | frame++; |
| 335 | |
| 336 | if (!frame_time_limited_warning_shown && |
| 337 | frame_time_now > expected_frame_time + 5 * target_frame_duration) |
| 338 | { |
| 339 | frame_time_limited_warning_shown = true; |
| 340 | LogWarning("Over 5 frames behind - likely vsync limited?"); |
| 341 | } |
| 342 | |
| 343 | processEvents(); |
| 344 | |
| 345 | if (p->ProgramStages.isEmpty()) |
| 346 | { |
| 347 | break; |
| 348 | } |
| 349 | { |
| 350 | p->ProgramStages.current()->update(); |
| 351 | } |
| 352 | |
| 353 | for (StageCmd cmd : stageCommands) |
| 354 | { |
| 355 | switch (cmd.cmd) |
| 356 | { |
| 357 | case StageCmd::Command::CONTINUE: |