-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathbflib_datetm.c
194 lines (177 loc) · 4.61 KB
/
bflib_datetm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/******************************************************************************/
// Bullfrog Engine Emulation Library - for use to remake classic games like
// Syndicate Wars, Magic Carpet or Dungeon Keeper.
/******************************************************************************/
/** @file bflib_datetm.c
* Date and time related routines.
* @par Purpose:
* Gets system date and time, makes delay, converts date/time formats.
* @par Comment:
* None.
* @author Tomasz Lis
* @date 12 Feb 2008 - 30 Dec 2008
* @par Copying and copyrights:
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
/******************************************************************************/
#include "bflib_datetm.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "bflib_basics.h"
#include "globals.h"
#if defined(WIN32)
//instead of #include <windows.h>
#include <windef.h>
#include <winbase.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define LARGE_DELAY_TIME 20
/******************************************************************************/
struct TbTime global_time;
struct TbDate global_date;
TbClockMSec (* LbTimerClock)(void);
/******************************************************************************/
/**
* Returns the number of milliseconds elapsed since the program was launched.
* A version for (CLOCKS_PER_SEC == 1000).
*/
TbClockMSec LbTimerClock_1000(void)
{
// original DK uses win32 function timeGetTime();
return clock();
}
/**
* Returns the number of milliseconds elapsed since the program was launched.
* A version for (CLOCKS_PER_SEC == 1024).
*/
TbClockMSec LbTimerClock_1024(void)
{
clock_t cclk;
cclk = clock();
return cclk - (cclk>>6) - (cclk>>7);
}
/**
* Returns the number of milliseconds elapsed since the program was launched.
* Version for any CLOCKS_PER_SEC, but unsafe.
*/
TbClockMSec LbTimerClock_any(void)
{
long long clk = 500 * clock();
return (clk / CLOCKS_PER_SEC) << 1;
}
/** Fills structure with current time.
*
* @param curr_time The structure to be filled.
* @return
*/
TbResult LbTime(struct TbTime *curr_time)
{
time_t dtime;
time(&dtime);
return LbDateTimeDecode(&dtime,NULL,curr_time);
}
/** Returns current calendar time in seconds.
*
* @return System time in seconds.
*/
TbTimeSec LbTimeSec(void)
{
time_t dtime;
time(&dtime);
return dtime;
}
//Fills structure with current date
TbResult LbDate(struct TbDate *curr_date)
{
time_t dtime;
time(&dtime);
return LbDateTimeDecode(&dtime,curr_date,NULL);
}
//Fills structures with current date and time
TbResult LbDateTime(struct TbDate *curr_date, struct TbTime *curr_time)
{
time_t dtime;
time(&dtime);
return LbDateTimeDecode(&dtime,curr_date,curr_time);
}
TbResult LbDateTimeDecode(const time_t *datetime,struct TbDate *curr_date,struct TbTime *curr_time)
{
struct tm *ltime=localtime(datetime);
if (curr_date!=NULL)
{
curr_date->Day=ltime->tm_mday;
curr_date->Month=ltime->tm_mon+1;
curr_date->Year=1900+ltime->tm_year;
curr_date->DayOfWeek=ltime->tm_wday;
}
if (curr_time!=NULL)
{
curr_time->Hour=ltime->tm_hour;
curr_time->Minute=ltime->tm_min;
curr_time->Second=ltime->tm_sec;
curr_time->HSecond=0;
}
return Lb_SUCCESS;
}
inline void LbDoMultitasking(void)
{
#if defined(WIN32)
Sleep(LARGE_DELAY_TIME>>1); // This switches to other tasks
#endif
}
TbBool __fastcall LbSleepFor(TbClockMSec delay)
{
register TbClockMSec currclk;
register TbClockMSec endclk;
currclk=LbTimerClock();
endclk=currclk+delay;
while ((currclk+LARGE_DELAY_TIME) < endclk)
{
LbDoMultitasking();
currclk=LbTimerClock();
}
while (currclk < endclk)
currclk=LbTimerClock();
return true;
}
TbBool __fastcall LbSleepUntil(TbClockMSec endtime)
{
register TbClockMSec currclk;
currclk=LbTimerClock();
while ((currclk+LARGE_DELAY_TIME) < endtime)
{
LbDoMultitasking();
currclk=LbTimerClock();
}
while (currclk < endtime)
currclk=LbTimerClock();
return true;
}
TbResult LbTimerInit(void)
{
switch (CLOCKS_PER_SEC)
{
case 1000:
LbTimerClock = LbTimerClock_1000;
break;
case 1024:
LbTimerClock = LbTimerClock_1024;
break;
default:
LbTimerClock = LbTimerClock_any;
WARNMSG("Timer uses unsafe clock multiplication!");
break;
}
return Lb_SUCCESS;
}
/******************************************************************************/
#ifdef __cplusplus
}
#endif