Changeset 116


Ignore:
Timestamp:
Aug 15, 2010, 4:29:11 PM (10 years ago)
Author:
sam
Message:

Implement a better timing mechanism for fixed framerate. Accuracy is
sub-millisecond but can be improved if we get rid of SDL timers.

Location:
trunk/src
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/Makefile.am

    r114 r116  
    88    scene.cpp scene.h font.cpp font.h layer.cpp layer.h map.cpp map.h \
    99    joystick.cpp joystick.h asset.cpp asset.h ticker.cpp ticker.h \
    10     forge.cpp forge.h video.cpp video.h \
     10    forge.cpp forge.h video.cpp video.h timer.cpp timer.h \
    1111    debugfps.cpp debugfps.h
    1212libcommon_a_CXXFLAGS = `pkg-config --cflags sdl gl SDL_image`
  • trunk/src/debugfps.cpp

    r112 r116  
    6666    char buf[1024];
    6767    sprintf(buf, "%3.2f ms (%3.2f fps) -- max %3.2f ms -- #%i",
    68             mean, 1000.0f / mean, max, data->frame);
     68            1000.0f * mean, 1.0f / mean, 1000.0f * max, data->frame);
    6969    data->font->Print(10, 10, buf);
    7070    data->font->Print(11, 10, buf);
  • trunk/src/gtk/editor.cpp

    r114 r116  
    2222static volatile int quit = 0;
    2323
    24 static GTimer *timer;
    25 static float delta_time;
    2624static int ticking = 0;
     25static float const FPS = 30.0f;
    2726
    2827static gint main_quit(GtkWidget *widget, GdkEventExpose *event)
     
    3938{
    4039    // FIXME: do not do anything if the previous tick was too recent?
    41     delta_time = 1000.0f * g_timer_elapsed(timer, NULL);
    42     g_timer_start(timer);
    4340
    4441    // FIXME: only quit if all assets have been cleaned
     
    4946
    5047    /* Tick the game */
    51     Ticker::TickGame(delta_time);
     48    Ticker::TickGame();
    5249
    5350    gtk_widget_draw(GTK_WIDGET(widget), NULL);
     
    8380        /* Clear the screen, tick the renderer, and show the frame */
    8481        Video::Clear();
    85         Ticker::TickRender(delta_time);
     82        Ticker::TickRender();
    8683        gtk_gl_area_swapbuffers(GTK_GL_AREA(widget));
     84        Ticker::ClampFps(FPS);
    8785    }
    8886
     
    159157
    160158    //gtk_idle_add(tick, glarea);
    161     gtk_timeout_add(33, tick, glarea);
     159    gtk_timeout_add(1000 / FPS, tick, glarea);
    162160
    163     timer = g_timer_new();
    164161    gtk_main();
    165162
  • trunk/src/test-map.cpp

    r112 r116  
    1818#include "ticker.h"
    1919#include "video.h"
     20
     21static int const FPS = 30.0f;
    2022
    2123int main(int argc, char **argv)
     
    4042    SDL_WM_GrabInput(SDL_GRAB_ON);
    4143
    42     /* Initialise timer */
    43     Uint32 ticks = SDL_GetTicks();
    44 
    4544    /* Initialise OpenGL */
    4645    Video::Setup(video->w, video->h);
     
    5554    while (!game->Finished())
    5655    {
    57         /* Compute delta time */
    58         Uint32 newticks = SDL_GetTicks();
    59         float delta_time = (float)(newticks - ticks);
    60         ticks = newticks;
    61 
    6256        /* Tick the game */
    63         Ticker::TickGame(delta_time);
     57        Ticker::TickGame();
    6458
    6559        /* Clear the screen, tick the renderer, and show the frame */
    6660        Video::Clear();
    67         Ticker::TickRender(delta_time);
     61        Ticker::TickRender();
    6862        SDL_GL_SwapBuffers();
    6963
    7064        /* Clamp to desired framerate */
    71         while (SDL_GetTicks() < ticks + (33.33333f - 0.5f))
    72             SDL_Delay(1);
     65        Ticker::ClampFps(FPS);
    7366    }
    7467
  • trunk/src/ticker.cpp

    r111 r116  
    1414#include "ticker.h"
    1515#include "asset.h"
     16#include "timer.h"
    1617
    1718/*
     
    3031        for (int i = 0; i < Asset::GROUP_COUNT; i++)
    3132            list[i] = NULL;
     33        timer = new Timer();
     34        bias = 0.0f;
    3235    }
    3336
     
    3841            fprintf(stderr, "ERROR: still %i assets in ticker\n", nassets);
    3942#endif
     43        delete timer;
    4044    }
    4145
    4246private:
     47    /* Asset management */
    4348    Asset *todo;
    4449    Asset *list[Asset::GROUP_COUNT];
    4550    int nassets;
     51
     52    /* FPS management */
     53    float delta_time;
     54    Timer *timer;
     55    float bias;
    4656}
    4757tickerdata;
     
    6272}
    6373
    64 void Ticker::TickGame(float delta_time)
     74void Ticker::TickGame()
    6575{
     76    data->delta_time = data->timer->GetSeconds();
     77    data->bias += data->delta_time;
     78
    6679    /* Insert waiting objects in the appropriate lists */
    6780    while (data->todo)
     
    94107        for (Asset *a = data->list[i]; a; a = a->next)
    95108            if (!a->destroy)
    96                 a->TickGame(delta_time);
     109                a->TickGame(data->delta_time);
    97110}
    98111
    99 void Ticker::TickRender(float delta_time)
     112void Ticker::TickRender()
    100113{
    101114    /* Tick objects for the render loop */
     
    103116        for (Asset *a = data->list[i]; a; a = a->next)
    104117            if (!a->destroy)
    105                 a->TickRender(delta_time);
     118                a->TickRender(data->delta_time);
    106119}
    107120
     121void Ticker::ClampFps(float fps)
     122{
     123    float ideal_time = 1.0f / fps;
     124
     125    data->timer->WaitSeconds(ideal_time - data->bias);
     126    data->bias -= ideal_time;
     127}
     128
  • trunk/src/ticker.h

    r100 r116  
    2222    static void Register(Asset *asset);
    2323
    24     static void TickGame(float delta_time);
    25     static void TickRender(float delta_time);
     24    static void TickGame();
     25    static void TickRender();
     26    static void ClampFps(float fps);
    2627};
    2728
Note: See TracChangeset for help on using the changeset viewer.