2 Copyright 2004 John Tsiombikas <nuclear@siggraph.org>
4 This is a cross-platform millisecond resolution timer library.
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this library; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #if defined(__unix__) || defined(unix)
25 #else /* assume win32 */
32 /* BEWARE: this function will not work correctly if we go back in time
33 * and try to use it during the first second of 1-1-1970
35 static unsigned long sys_get_msec(void) {
36 #if defined(__unix__) || defined(unix)
37 static struct timeval timeval, first_timeval;
39 gettimeofday(&timeval, 0);
41 if(first_timeval.tv_sec == 0) {
42 first_timeval = timeval;
45 return (timeval.tv_sec - first_timeval.tv_sec) * 1000 + (timeval.tv_usec - first_timeval.tv_usec) / 1000;
47 return GetTickCount();
52 void timer_start(ntimer *timer) {
53 timer->state = TSTATE_RUNNING;
54 timer->stopped_interval += timer_getmsec(timer) - timer->stop;
58 void timer_stop(ntimer *timer) {
59 timer->stop = timer_getmsec(timer);
60 timer->state = TSTATE_PAUSED;
63 void timer_reset(ntimer *timer) {
64 timer->state = TSTATE_RESET;
65 timer->start = sys_get_msec();
67 timer->stopped_interval = 0;
71 void timer_fwd(ntimer *timer, unsigned long msec) {
72 timer->offset += msec;
73 if(timer->state != TSTATE_RUNNING) {
78 void timer_back(ntimer *timer, unsigned long msec) {
79 timer->offset -= msec;
80 if(timer->state != TSTATE_RUNNING) {
85 #define MAX(a, b) ((a) > (b) ? (a) : (b))
87 unsigned long timer_getmsec(ntimer *timer) {
88 if(timer->state == TSTATE_RUNNING) {
89 long time = (long)sys_get_msec() - timer->start - timer->stopped_interval + timer->offset;
97 return MAX(timer->stop, 0);
99 return 0; /* can't happen */
102 unsigned long timer_getsec(ntimer *timer) {
103 return timer_getmsec(timer) / 1000;