source: trunk/src/timer.cpp @ 116

Last change on this file since 116 was 116, checked in by sam, 11 years ago

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

  • Property svn:keywords set to Id
File size: 2.0 KB
Line 
1//
2// Deus Hax (working title)
3// Copyright (c) 2010 Sam Hocevar <sam@hocevar.net>
4//
5
6#if defined HAVE_CONFIG_H
7#   include "config.h"
8#endif
9
10#include <cstdlib>
11#include <cstdio>
12#include <stdint.h>
13
14#if defined __linux__
15#   include <sys/time.h>
16#elif defined _WIN32
17#   define WIN32_LEAN_AND_MEAN
18#   include <windows.h>
19#else
20#   include <SDL.h>
21#endif
22
23// XXX
24#include <SDL.h>
25
26#include "timer.h"
27
28/*
29 * Timer implementation class
30 */
31
32class TimerData
33{
34    friend class Timer;
35
36private:
37    TimerData()
38    {
39#if defined __linux__
40        gettimeofday(&tv0, NULL);
41#elif defined _WIN32
42        LARGE_INTEGER tmp;
43        QueryPerformanceFrequency(&tmp);
44        seconds_per_cycle = 1.0f / tmp.QuadPart;
45        QueryPerformanceCounter(&cycles0);
46#else
47        SDL_Init(SDL_INIT_TIMER);
48        ticks0 = SDL_GetTicks();
49#endif
50    }
51
52    float GetSeconds(bool update)
53    {
54        float ret;
55#if defined __linux__
56        struct timeval tv;
57        gettimeofday(&tv, NULL);
58        ret = 1e-6f * (tv.tv_usec - tv0.tv_usec) + (tv.tv_sec - tv0.tv_sec);
59        if (update)
60            tv0 = tv;
61#elif defined _WIN32
62        LARGE_INTEGER cycles;
63        QueryPerformanceCounter(&cycles);
64        ret = seconds_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
65        if (update)
66            cycles0 = cycles;
67#else
68        Uint32 ticks = SDL_GetTicks();
69        ret = 1e-3f * (ticks - ticks0);
70        if (update)
71            ticks0 = ticks;
72#endif
73        return ret;
74    }
75
76#if defined __linux__
77    struct timeval tv0;
78#elif defined _WIN32
79    float seconds_per_cycle;
80    LARGE_INTEGER cycles0;
81#else
82    Uint32 ticks0;
83#endif
84};
85
86/*
87 * Timer public class
88 */
89
90Timer::Timer()
91{
92    data = new TimerData();
93}
94
95Timer::~Timer()
96{
97    delete data;
98}
99
100float Timer::GetSeconds()
101{
102    return data->GetSeconds(true);
103}
104
105void Timer::WaitSeconds(float seconds)
106{
107    float sleep = seconds - data->GetSeconds(false);
108    if (sleep <= 1e-4f)
109        return;
110
111    SDL_Delay((int)(sleep * 1000.0f + 0.5f));
112}
113
Note: See TracBrowser for help on using the repository browser.