source: trunk/src/timer.cpp @ 763

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

ps3: fix a bug in the timer code.

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