diff --git a/engine/engine.c b/engine/engine.c index 6cf3cfa..848df2b 100644 --- a/engine/engine.c +++ b/engine/engine.c @@ -37,54 +37,52 @@ int main(int argc, char *argv[]) void *gamemem = calloc(1, game_conf.memsize); game_init(argc, argv, gamemem, renderer); - perf_t perf = { .freq = SDL_GetPerformanceFrequency() / 1000000.0 }; - uint64_t frame = 0, prevt = SDL_GetTicks64(); + const uint64_t perfhz = SDL_GetPerformanceFrequency(); + const uint64_t intervalperf = (INTERVAL * perfhz) / 1000; + perf_t perf = { .freq = perfhz / 1000000.0 }; + uint64_t frame = 0; while (1) { - const uint64_t t = SDL_GetTicks64(); - const uint64_t dt = t - prevt; - if (dt >= INTERVAL) { - perf.start = SDL_GetPerformanceCounter(); + perf.start = SDL_GetPerformanceCounter(); - // Handle all events currently in queue - SDL_Event evt; - while (SDL_PollEvent(&evt)) { - if (game_evthandle(gamemem, &evt) != GAMESTATUS_OK) - goto quit; - } - perf.evt = SDL_GetPerformanceCounter(); - - // Update game state - if (game_update(gamemem, INTERVAL) != GAMESTATUS_OK) + // Handle all events currently in queue + SDL_Event evt; + while (SDL_PollEvent(&evt)) { + if (game_evthandle(gamemem, &evt) != GAMESTATUS_OK) goto quit; - perf.update = SDL_GetPerformanceCounter(); + } + perf.evt = SDL_GetPerformanceCounter(); - // Render frame - SDL_RenderClear(renderer); - game_render(gamemem, renderer, t); - SDL_RenderPresent(renderer); - perf.render = SDL_GetPerformanceCounter(); + // Update game state + if (game_update(gamemem, INTERVAL) != GAMESTATUS_OK) + goto quit; + perf.update = SDL_GetPerformanceCounter(); - // Print performance analysis every 16 frames - if ((frame & 15) == 0) { - const double evt = (perf.evt - perf.start) / perf.freq; - const double update = (perf.update - perf.evt) / perf.freq; - const double render - = (perf.render - perf.update) / perf.freq; - const double total = (perf.render - perf.start) / perf.freq; - const double total_pc = (100 * total / (1000 * INTERVAL)); - printf( - VT100_CLEAR VT100_CURSORTOPLEFT - "evt\t%10.3f μs\nupdate\t%10.3f μs\nrender\t" - "%10.3f μs\ntotal\t%10.3f μs (%05.2f%%)\n", - evt, update, render, total, total_pc); - } + // Render frame + SDL_RenderClear(renderer); + game_render(gamemem, renderer, SDL_GetTicks64()); + SDL_RenderPresent(renderer); + perf.render = SDL_GetPerformanceCounter(); - // Increment frame counter and update time - ++frame; - prevt = t; + // Print performance analysis every 16 frames + if ((frame & 15) == 0) { + const double evt = (perf.evt - perf.start) / perf.freq; + const double update = (perf.update - perf.evt) / perf.freq; + const double render + = (perf.render - perf.update) / perf.freq; + const double total = (perf.render - perf.start) / perf.freq; + const double total_pc = (100 * total / (1000 * INTERVAL)); + printf( + VT100_CLEAR VT100_CURSORTOPLEFT + "evt\t%10.3f μs\nupdate\t%10.3f μs\nrender\t" + "%10.3f μs\ntotal\t%10.3f μs (%05.2f%%)\n", + evt, update, render, total, total_pc); } - SDL_Delay(INTERVAL / 8); + // Increment frame counter and wait until next interval + ++frame; + const uint64_t elapsed = SDL_GetPerformanceCounter() - perf.start; + assert(elapsed < intervalperf); + SDL_Delay((1000 * (intervalperf - elapsed)) / perfhz); } quit: