diff options
| -rw-r--r-- | kon/kondebug.c | 14 | ||||
| -rw-r--r-- | kon/kondebug.h | 4 | ||||
| -rw-r--r-- | kon/konprogram.c | 16 | ||||
| -rw-r--r-- | kon/konprogram.h | 1 |
4 files changed, 33 insertions, 2 deletions
diff --git a/kon/kondebug.c b/kon/kondebug.c index a68ebcf..54e8d13 100644 --- a/kon/kondebug.c +++ b/kon/kondebug.c @@ -91,6 +91,7 @@ struct kon_debug { double accumTime; int accumFrames; float fps; + double times[4]; /* update, draw, present, blit */ float graph[KON_DEBUG_GRAPH]; int graphHead; }; @@ -607,6 +608,16 @@ void kon_debugFrame(kon_debug_t *d) d->graphHead = (d->graphHead + 1) % KON_DEBUG_GRAPH; } +void kon_debugTimes(kon_debug_t *d, double update, double draw, double present, double blit) +{ + double in[4]; + int i; + + if (!d) return; + in[0] = update; in[1] = draw; in[2] = present; in[3] = blit; + for (i = 0; i < 4; i++) d->times[i] += (in[i] - d->times[i]) * 0.1; +} + static void kon_debugBox_(const kon_debug_t *d, kon_framebuffer_t *fb, int x, int y, const char *s, uint32_t color) { int w = 0; @@ -628,6 +639,9 @@ static void kon_debugDrawOverlay_(kon_debug_t *d, kon_framebuffer_t *fb) y += d->lineH + 3; if (d->overlay >= 1) { + snprintf(line, sizeof(line), "upd %.1f draw %.1f scale %.1f blit %.1f", d->times[0] * 1000.0, d->times[1] * 1000.0, d->times[2] * 1000.0, d->times[3] * 1000.0); + kon_debugBox_(d, fb, x, y, line, dim); + y += d->lineH + 3; kon_fillRectangle(fb, x - 2, y - 2, KON_DEBUG_GRAPH + 4, 34, 0xB0000000); for (i = 0; i < KON_DEBUG_GRAPH; i++) { float ms = d->graph[(d->graphHead + i) % KON_DEBUG_GRAPH]; diff --git a/kon/kondebug.h b/kon/kondebug.h index f17f0c2..0f32a0f 100644 --- a/kon/kondebug.h +++ b/kon/kondebug.h @@ -69,6 +69,9 @@ int kon_debugConsoleOpen(const kon_debug_t *debug); void kon_debugFrame(kon_debug_t *debug); void kon_debugDraw(kon_debug_t *debug, kon_framebuffer_t *fb); +/* where the frame went, in seconds. shown under the fps when the overlay is on */ +void kon_debugTimes(kon_debug_t *debug, double update, double draw, double present, double blit); + float kon_debugFps(const kon_debug_t *debug); /* set by the quit and exit commands, the game decides what to do with it */ @@ -87,6 +90,7 @@ static inline int kon_debugFeedEvent(kon_debug_t *debug, const kon_event_t *even static inline int kon_debugConsoleOpen(const kon_debug_t *debug) { (void)debug; return 0; } static inline void kon_debugFrame(kon_debug_t *debug) { (void)debug; } static inline void kon_debugDraw(kon_debug_t *debug, kon_framebuffer_t *fb) { (void)debug; (void)fb; } +static inline void kon_debugTimes(kon_debug_t *debug, double update, double draw, double present, double blit) { (void)debug; (void)update; (void)draw; (void)present; (void)blit; } static inline float kon_debugFps(const kon_debug_t *debug) { (void)debug; return 0.0f; } static inline int kon_debugQuitRequested(const kon_debug_t *debug) { (void)debug; return 0; } diff --git a/kon/konprogram.c b/kon/konprogram.c index 31fe7b6..a87aee8 100644 --- a/kon/konprogram.c +++ b/kon/konprogram.c @@ -110,7 +110,7 @@ static void kon_frame_(void *data) { const kon_programConfig_t *config = &state->config; kon_display_t *display = program->display; kon_event_t ev; - kon_time now, dt; + kon_time now, dt, t0, t1, t2, t3, t4, cap; while (kon_pollEvent(program->window, &ev)) { if (kon_debugFeedEvent(program->debug, &ev)) continue; @@ -131,17 +131,29 @@ static void kon_frame_(void *data) { else kon_setWindowPos(program->window, state->shakeX, state->shakeY); } + t0 = kon_getTime(); if (config->update) config->update(program, dt, config->user); + t1 = kon_getTime(); kon_clearFramebuffer(display->game, KON_BACKGROUND_COLOR); if (config->draw) config->draw(program, display->game, config->user); + t2 = kon_getTime(); kon_presentDisplay(display); + t3 = kon_getTime(); if (config->drawScreen) config->drawScreen(program, display->screen, config->user); kon_debugFrame(program->debug); if (kon_debugQuitRequested(program->debug)) kon_setShouldClose(program->window, true); kon_debugDraw(program->debug, display->screen); + t4 = kon_getTime(); kon_blitPixels(program->window, display->screen->data, display->screen->width, display->screen->height); - kon_sleep(0.008); + kon_debugTimes(program->debug, t1 - t0, t2 - t1, t3 - t2, kon_getTime() - t4); + + /* only wait out what is left of the frame, a fixed sleep eats time the frame could use */ + if (config->maxFps >= 0) { + cap = 1.0 / (config->maxFps > 0 ? config->maxFps : 120); + dt = kon_getTime() - now; + if (dt < cap) kon_sleep(cap - dt); + } } void kon_programQuit(kon_program_t *program) { diff --git a/kon/konprogram.h b/kon/konprogram.h index f0a29b3..04aef18 100644 --- a/kon/konprogram.h +++ b/kon/konprogram.h @@ -46,6 +46,7 @@ typedef struct kon_programConfig { int windowWidth, windowHeight; /* 3 times the game size */ const char *assetDir; /* folder with loose files, "assets". only used with KON_DEVELOPER */ const char *packPath; /* pack file to read assets from, none if NULL */ + int maxFps; /* frame cap, 120. -1 for none */ void *user; /* given back to every callback */ /* return 0 to quit before the loop starts */ |
