@@ -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; | ||||