source: trunk/src/timer.cpp @ 173

Last change on this file since 173 was 173, checked in by sam, 10 years ago

Fix a Win32 timer regression bug.

  • Property svn:keywords set to Id
File size: 2.4 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#   include <unistd.h>
17#elif defined _WIN32
18#   define WIN32_LEAN_AND_MEAN
19#   include <windows.h>
20#   include <SDL.h> // FIXME: this should not be needed
21#else
22#   include <SDL.h>
23#endif
24
25#include "core.h"
26
27/*
28 * Timer implementation class
29 */
30
31class TimerData
32{
33    friend class Timer;
34
35private:
36    TimerData()
37    {
38#if defined __linux__
39        gettimeofday(&tv0, NULL);
40#elif defined _WIN32
41        LARGE_INTEGER tmp;
42        QueryPerformanceFrequency(&tmp);
43        ms_per_cycle = 1e3f / tmp.QuadPart;
44        QueryPerformanceCounter(&cycles0);
45#else
46        SDL_Init(SDL_INIT_TIMER);
47        ticks0 = SDL_GetTicks();
48#endif
49    }
50
51    float GetOrWait(float deltams, bool update)
52    {
53        float ret, towait;
54#if defined __linux__
55        struct timeval tv;
56        gettimeofday(&tv, NULL);
57        ret = 1e-3f * (tv.tv_usec - tv0.tv_usec)
58            + 1e3f * (tv.tv_sec - tv0.tv_sec);
59        if (update)
60            tv0 = tv;
61        towait = deltams - ret;
62        if (towait > 0.0f)
63            usleep((int)(towait * 1e3f));
64#elif defined _WIN32
65        LARGE_INTEGER cycles;
66        QueryPerformanceCounter(&cycles);
67        ret = ms_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
68        if (update)
69            cycles0 = cycles;
70        towait = deltams - ret;
71        if (towait > 5e-4f) // FIXME: use native Win32 stuff
72            SDL_Delay((int)(towait + 0.5f));
73#else
74        /* The crappy SDL fallback */
75        Uint32 ticks = SDL_GetTicks();
76        ret = 1e-6f * (ticks - ticks0);
77        if (update)
78            ticks0 = ticks;
79        towait = deltams - ret;
80        if (towait > 0.5f)
81            SDL_Delay((int)(towait + 0.5f));
82#endif
83        return ret;
84    }
85
86#if defined __linux__
87    struct timeval tv0;
88#elif defined _WIN32
89    float ms_per_cycle;
90    LARGE_INTEGER cycles0;
91#else
92    Uint32 ticks0;
93#endif
94};
95
96/*
97 * Timer public class
98 */
99
100Timer::Timer()
101{
102    data = new TimerData();
103}
104
105Timer::~Timer()
106{
107    delete data;
108}
109
110float Timer::GetMs()
111{
112    return data->GetOrWait(0.0f, true);
113}
114
115float Timer::PollMs()
116{
117    return data->GetOrWait(0.0f, false);
118}
119
120void Timer::WaitMs(float deltams)
121{
122    (void)data->GetOrWait(deltams, false);
123}
124
Note: See TracBrowser for help on using the repository browser.