| @@ -20,7 +20,10 @@ class DebugFpsData | |||||
| { | { | ||||
| friend class DebugFps; | friend class DebugFps; | ||||
| static int const HISTORY = 30; | |||||
| private: | private: | ||||
| float history[HISTORY]; | |||||
| Font *font; | Font *font; | ||||
| int frame; | int frame; | ||||
| }; | }; | ||||
| @@ -33,6 +36,8 @@ DebugFps::DebugFps() | |||||
| { | { | ||||
| data = new DebugFpsData(); | data = new DebugFpsData(); | ||||
| for (int i = 0; i < DebugFpsData::HISTORY; i++) | |||||
| data->history[i] = 0.0f; | |||||
| data->font = Forge::GetFont("gfx/font/ascii.png"); | data->font = Forge::GetFont("gfx/font/ascii.png"); | ||||
| data->frame = 0; | data->frame = 0; | ||||
| } | } | ||||
| @@ -46,8 +51,21 @@ void DebugFps::TickRender(float delta_time) | |||||
| { | { | ||||
| Asset::TickGame(delta_time); | Asset::TickGame(delta_time); | ||||
| data->history[data->frame % DebugFpsData::HISTORY] = delta_time; | |||||
| data->frame++; | |||||
| float mean = 0.0f, max = 0.0f; | |||||
| for (int i = 0; i < DebugFpsData::HISTORY; i++) | |||||
| { | |||||
| mean += data->history[i]; | |||||
| if (data->history[i] > max) | |||||
| max = data->history[i]; | |||||
| } | |||||
| mean /= DebugFpsData::HISTORY; | |||||
| char buf[1024]; | char buf[1024]; | ||||
| sprintf(buf, "%3.2f fps (%i)", 1000.0f / delta_time, data->frame++); | |||||
| sprintf(buf, "%3.2f ms (%3.2f fps) -- max %3.2f ms -- #%i", | |||||
| mean, 1000.0f / mean, max, data->frame); | |||||
| data->font->Print(10, 10, buf); | data->font->Print(10, 10, buf); | ||||
| data->font->Print(11, 10, buf); | data->font->Print(11, 10, buf); | ||||
| data->font->Print(10, 11, buf); | data->font->Print(10, 11, buf); | ||||
| @@ -19,7 +19,11 @@ | |||||
| #include "video.h" | #include "video.h" | ||||
| #include "game.h" | #include "game.h" | ||||
| volatile int quit = 0; | |||||
| static volatile int quit = 0; | |||||
| static GTimer *timer; | |||||
| static float delta_time; | |||||
| static int ticking = 0; | |||||
| static gint main_quit(GtkWidget *widget, GdkEventExpose *event) | static gint main_quit(GtkWidget *widget, GdkEventExpose *event) | ||||
| { | { | ||||
| @@ -33,14 +37,16 @@ static gint main_quit(GtkWidget *widget, GdkEventExpose *event) | |||||
| static gboolean tick(void *widget) | static gboolean tick(void *widget) | ||||
| { | { | ||||
| float const delta_time = 33.33333f; | |||||
| // FIXME: do not do anything if the previous tick was too recent? | // FIXME: do not do anything if the previous tick was too recent? | ||||
| delta_time = 1000.0f * g_timer_elapsed(timer, NULL); | |||||
| g_timer_start(timer); | |||||
| // FIXME: only quit if all assets have been cleaned | // FIXME: only quit if all assets have been cleaned | ||||
| if (quit) | if (quit) | ||||
| return FALSE; | return FALSE; | ||||
| ticking = 1; | |||||
| /* Tick the game */ | /* Tick the game */ | ||||
| Ticker::TickGame(delta_time); | Ticker::TickGame(delta_time); | ||||
| @@ -70,10 +76,9 @@ static gint draw(GtkWidget *widget, GdkEventExpose *event) | |||||
| return TRUE; | return TRUE; | ||||
| /* OpenGL functions can be called only if make_current returns true */ | /* OpenGL functions can be called only if make_current returns true */ | ||||
| if (gtk_gl_area_make_current(GTK_GL_AREA(widget))) | |||||
| if (ticking && gtk_gl_area_make_current(GTK_GL_AREA(widget))) | |||||
| { | { | ||||
| // FIXME: do not do anything if the game tick wasn't called? | |||||
| float const delta_time = 33.33333f; | |||||
| ticking = 0; | |||||
| /* Clear the screen, tick the renderer, and show the frame */ | /* Clear the screen, tick the renderer, and show the frame */ | ||||
| Video::Clear(); | Video::Clear(); | ||||
| @@ -87,6 +92,7 @@ static gint draw(GtkWidget *widget, GdkEventExpose *event) | |||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||
| { | { | ||||
| /* Initialize GTK */ | /* Initialize GTK */ | ||||
| g_thread_init(NULL); | |||||
| gtk_init(&argc, &argv); | gtk_init(&argc, &argv); | ||||
| if (gdk_gl_query() == FALSE) | if (gdk_gl_query() == FALSE) | ||||
| @@ -151,6 +157,8 @@ int main(int argc, char **argv) | |||||
| //gtk_idle_add(tick, glarea); | //gtk_idle_add(tick, glarea); | ||||
| gtk_timeout_add(33, tick, glarea); | gtk_timeout_add(33, tick, glarea); | ||||
| timer = g_timer_new(); | |||||
| gtk_main(); | gtk_main(); | ||||
| return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||||
| @@ -40,9 +40,7 @@ int main(int argc, char **argv) | |||||
| SDL_WM_GrabInput(SDL_GRAB_ON); | SDL_WM_GrabInput(SDL_GRAB_ON); | ||||
| /* Initialise timer */ | /* Initialise timer */ | ||||
| Uint32 start, ticks; | |||||
| start = ticks = SDL_GetTicks(); | |||||
| int frames = 0; | |||||
| Uint32 ticks = SDL_GetTicks(); | |||||
| /* Initialise OpenGL */ | /* Initialise OpenGL */ | ||||
| Video::Setup(video->w, video->h); | Video::Setup(video->w, video->h); | ||||
| @@ -56,7 +54,10 @@ int main(int argc, char **argv) | |||||
| while (!game->Finished()) | while (!game->Finished()) | ||||
| { | { | ||||
| float const delta_time = 33.33333f; | |||||
| /* Compute delta time */ | |||||
| Uint32 newticks = SDL_GetTicks(); | |||||
| float delta_time = (float)(newticks - ticks); | |||||
| ticks = newticks; | |||||
| /* Tick the game */ | /* Tick the game */ | ||||
| Ticker::TickGame(delta_time); | Ticker::TickGame(delta_time); | ||||
| @@ -67,14 +68,10 @@ int main(int argc, char **argv) | |||||
| SDL_GL_SwapBuffers(); | SDL_GL_SwapBuffers(); | ||||
| /* Clamp to desired framerate */ | /* Clamp to desired framerate */ | ||||
| while (SDL_GetTicks() < ticks + (delta_time - 0.5f)) | |||||
| while (SDL_GetTicks() < ticks + (33.33333f - 0.5f)) | |||||
| SDL_Delay(1); | SDL_Delay(1); | ||||
| ticks = SDL_GetTicks(); | |||||
| frames++; | |||||
| } | } | ||||
| Uint32 total = SDL_GetTicks() - start; | |||||
| printf("%f fps\n", 1000.0f * frames / total); | |||||
| SDL_Quit(); | SDL_Quit(); | ||||
| return EXIT_SUCCESS; | return EXIT_SUCCESS; | ||||