source: trunk/src/timer.cpp @ 636

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

Fix the SDL timer behaviour. Fixes ticket #26.

  • Property svn:keywords set to Id
File size: 2.5 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstdlib>
16#include <cstdio>
17#include <stdint.h>
18
19#if defined __linux__
20#   include <sys/time.h>
21#   include <unistd.h>
22#elif defined _WIN32
23#   define WIN32_LEAN_AND_MEAN
24#   include <windows.h>
25#else
26#   include <SDL.h>
27#endif
28
29#include "core.h"
30
31/*
32 * Timer implementation class
33 */
34
35class TimerData
36{
37    friend class Timer;
38
39private:
40    TimerData()
41    {
42#if defined __linux__
43        gettimeofday(&tv0, NULL);
44#elif defined _WIN32
45        LARGE_INTEGER tmp;
46        QueryPerformanceFrequency(&tmp);
47        ms_per_cycle = 1e3f / tmp.QuadPart;
48        QueryPerformanceCounter(&cycles0);
49#else
50        SDL_Init(SDL_INIT_TIMER);
51        ticks0 = SDL_GetTicks();
52#endif
53    }
54
55    float GetOrWait(float deltams, bool update)
56    {
57        float ret, towait;
58#if defined __linux__
59        struct timeval tv;
60        gettimeofday(&tv, NULL);
61        ret = 1e-3f * (tv.tv_usec - tv0.tv_usec)
62            + 1e3f * (tv.tv_sec - tv0.tv_sec);
63        if (update)
64            tv0 = tv;
65        towait = deltams - ret;
66        if (towait > 0.0f)
67            usleep((int)(towait * 1e3f));
68#elif defined _WIN32
69        LARGE_INTEGER cycles;
70        QueryPerformanceCounter(&cycles);
71        ret = ms_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
72        if (update)
73            cycles0 = cycles;
74        towait = deltams - ret;
75        if (towait > 5e-4f)
76            Sleep((int)(towait + 0.5f));
77#else
78        /* The crappy SDL fallback */
79        Uint32 ticks = SDL_GetTicks();
80        ret = ticks - ticks0;
81        if (update)
82            ticks0 = ticks;
83        towait = deltams - ret;
84        if (towait > 0.5f)
85            SDL_Delay((int)(towait + 0.5f));
86#endif
87        return ret;
88    }
89
90#if defined __linux__
91    struct timeval tv0;
92#elif defined _WIN32
93    float ms_per_cycle;
94    LARGE_INTEGER cycles0;
95#else
96    Uint32 ticks0;
97#endif
98};
99
100/*
101 * Timer public class
102 */
103
104Timer::Timer()
105  : data(new TimerData())
106{
107}
108
109Timer::~Timer()
110{
111    delete data;
112}
113
114float Timer::GetMs()
115{
116    return data->GetOrWait(0.0f, true);
117}
118
119float Timer::PollMs()
120{
121    return data->GetOrWait(0.0f, false);
122}
123
124void Timer::WaitMs(float deltams)
125{
126    (void)data->GetOrWait(deltams, false);
127}
128
Note: See TracBrowser for help on using the repository browser.