rearrange some things
[voxelands-alt.git] / src / lib / time.c
blob650c08f0df1baaa1ad553afd9ba95c90581ca61d
1 /************************************************************************
2 * time.c
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program 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 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
20 #include "common.h"
22 #include <time.h>
24 #ifndef WIN32
25 #include <unistd.h>
26 #include <errno.h>
27 #include <sys/time.h>
28 #else
29 #include <windows.h>
30 #endif
32 #ifndef WIN32
33 static struct timeval start;
34 #else
35 static DWORD start;
36 #define TIME_WRAP_VALUE (~(DWORD)0)
37 #endif
39 /* initialise time */
40 void time_init()
42 #ifndef WIN32
43 gettimeofday(&start, NULL);
44 #else
45 timeBeginPeriod(1);
46 start = timeGetTime();
47 #endif
50 /* get number of milliseconds since start */
51 uint32_t time_ticks(void)
53 #ifndef WIN32
54 uint32_t ticks;
55 struct timeval now;
56 gettimeofday(&now, NULL);
57 ticks = (now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000;
58 return ticks;
59 #else
60 DWORD now = timeGetTime();
61 DWORD ticks;
62 if (now < start) {
63 ticks = (TIME_WRAP_VALUE-start) + now;
64 }else{
65 ticks = (now - start);
68 return ticks;
69 #endif
72 /* high resolution sleep() */
73 void delay(uint32_t ms)
75 #ifndef WIN32
76 struct timespec elapsed;
77 struct timespec tv;
78 int was_error;
80 /* Set the timeout interval */
81 elapsed.tv_sec = ms/1000;
82 elapsed.tv_nsec = (ms%1000)*1000000;
83 do {
84 errno = 0;
86 tv.tv_sec = elapsed.tv_sec;
87 tv.tv_nsec = elapsed.tv_nsec;
88 was_error = nanosleep(&tv, &elapsed);
89 } while (was_error && (errno == EINTR));
90 #else
91 Sleep(ms);
92 #endif
96 * for animation timing
97 * returns the seconds since last
99 float time_dtime(uint32_t last)
101 uint32_t now = time_ticks();
102 uint32_t elapsed = now-last;
103 return (float)elapsed/1000.0;
106 /* essentially a frame capper */
107 uint32_t interval_delay(uint32_t last, uint32_t hz)
109 if (last) {
110 uint32_t now = time_ticks();
111 uint32_t elapsed = now-last;
112 uint32_t timer = 1000/hz;
113 uint32_t idelay;
115 * If elapsed is greater than timer, this could really mess up
116 * the frame rate due to a negative value rolling over to an
117 * insanely high positive value, so only delay if we have to.
119 if (timer > elapsed) {
120 idelay = timer-elapsed;
121 delay(idelay);
124 return time_ticks();
127 /* get the frames per second */
128 uint32_t calc_fps(uint32_t prev, uint32_t current)
130 uint32_t diff = (current-prev);
131 if (diff) {
132 return 1000/diff;
133 }else{
134 return 1000;