]> git.lizzy.rs Git - irrlicht.git/blob - source/Irrlicht/os.cpp
Reduce IrrCompileConfig usage to files that actually need it
[irrlicht.git] / source / Irrlicht / os.cpp
1 // Copyright (C) 2002-2012 Nikolaus Gebhardt\r
2 // This file is part of the "Irrlicht Engine".\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h\r
4 \r
5 #include "os.h"\r
6 #include "irrString.h"\r
7 #include "irrMath.h"\r
8 \r
9 #if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)\r
10         #include <SDL_endian.h>\r
11         #define bswap_16(X) SDL_Swap16(X)\r
12         #define bswap_32(X) SDL_Swap32(X)\r
13         #define bswap_64(X) SDL_Swap64(X)\r
14 #elif defined(_IRR_WINDOWS_API_) && defined(_MSC_VER)\r
15         #include <stdlib.h>\r
16         #define bswap_16(X) _byteswap_ushort(X)\r
17         #define bswap_32(X) _byteswap_ulong(X)\r
18         #define bswap_64(X) _byteswap_uint64(X)\r
19         #define localtime _localtime_s\r
20 #elif defined(_IRR_OSX_PLATFORM_) || defined(_IRR_IOS_PLATFORM_)\r
21         #include <libkern/OSByteOrder.h>\r
22         #define bswap_16(X) OSReadSwapInt16(&X,0)\r
23         #define bswap_32(X) OSReadSwapInt32(&X,0)\r
24         #define bswap_64(X) OSReadSwapInt64(&X,0)\r
25 #elif defined(__FreeBSD__)\r
26         #include <sys/endian.h>\r
27         #define bswap_16(X) bswap16(X)\r
28         #define bswap_32(X) bswap32(X)\r
29         #define bswap_64(X) bswap64(X)\r
30 #elif defined(__OpenBSD__)\r
31         #include <endian.h>\r
32         #define bswap_16(X) letoh16(X)\r
33         #define bswap_32(X) letoh32(X)\r
34         #define bswap_64(X) letoh64(X)\r
35 #elif !defined(_IRR_SOLARIS_PLATFORM_) && !defined(__PPC__) && !defined(_IRR_WINDOWS_API_)\r
36         #include <byteswap.h>\r
37 #else\r
38         #define bswap_16(X) ((((X)&0xFF) << 8) | (((X)&0xFF00) >> 8))\r
39         #define bswap_32(X) ((((X)&0x000000FF) << 24) | (((X)&0xFF000000) >> 24) | (((X)&0x0000FF00) << 8) | (((X) &0x00FF0000) >> 8))\r
40         #define bswap_64(X) ((((X)&0x00000000000000FF) << 56) | (((X)&0xFF00000000000000) >> 56) | (((X)&0x000000000000FF00) << 40) | (((X)&0x00FF000000000000) >> 40) | (((X)&0x0000000000FF0000) << 24) | (((X)&0x0000FF0000000000) >> 24) | (((X)&0x00000000FF000000) << 8) | (((X) &0x000000FF00000000) >> 8))\r
41 #endif\r
42 \r
43 namespace irr\r
44 {\r
45 namespace os\r
46 {\r
47         u16 Byteswap::byteswap(u16 num) {return bswap_16(num);}\r
48         s16 Byteswap::byteswap(s16 num) {return bswap_16(num);}\r
49         u32 Byteswap::byteswap(u32 num) {return bswap_32(num);}\r
50         s32 Byteswap::byteswap(s32 num) {return bswap_32(num);}\r
51         u64 Byteswap::byteswap(u64 num) {return bswap_64(num);}\r
52         s64 Byteswap::byteswap(s64 num) {return bswap_64(num);}\r
53         f32 Byteswap::byteswap(f32 num) {u32 tmp=IR(num); tmp=bswap_32(tmp); return (FR(tmp));}\r
54         // prevent accidental byte swapping of chars\r
55         u8  Byteswap::byteswap(u8 num)  {return num;}\r
56         c8  Byteswap::byteswap(c8 num)  {return num;}\r
57 }\r
58 }\r
59 \r
60 #if defined(_IRR_WINDOWS_API_)\r
61 // ----------------------------------------------------------------\r
62 // Windows specific functions\r
63 // ----------------------------------------------------------------\r
64 \r
65 #define WIN32_LEAN_AND_MEAN\r
66 #include <windows.h>\r
67 #include <time.h>\r
68 \r
69 namespace irr\r
70 {\r
71 namespace os\r
72 {\r
73         //! prints a debuginfo string\r
74         void Printer::print(const c8* message, ELOG_LEVEL ll)\r
75         {\r
76                 core::stringc tmp(message);\r
77                 tmp += "\n";\r
78                 OutputDebugStringA(tmp.c_str());\r
79                 printf("%s", tmp.c_str());\r
80         }\r
81 \r
82         static LARGE_INTEGER HighPerformanceFreq;\r
83         static BOOL HighPerformanceTimerSupport = FALSE;\r
84 \r
85         void Timer::initTimer(bool usePerformanceTimer)\r
86         {\r
87                 if (usePerformanceTimer)\r
88                         HighPerformanceTimerSupport = QueryPerformanceFrequency(&HighPerformanceFreq);\r
89                 else\r
90                         HighPerformanceTimerSupport = FALSE;\r
91                 initVirtualTimer();\r
92         }\r
93 \r
94         u32 Timer::getRealTime()\r
95         {\r
96                 if (HighPerformanceTimerSupport)\r
97                 {\r
98                         LARGE_INTEGER nTime;\r
99                         BOOL queriedOK = QueryPerformanceCounter(&nTime);\r
100 \r
101                         if(queriedOK)\r
102                                 return u32((nTime.QuadPart) * 1000 / HighPerformanceFreq.QuadPart);\r
103                 }\r
104 \r
105                 return GetTickCount();\r
106         }\r
107 \r
108 } // end namespace os\r
109 \r
110 \r
111 #elif defined( _IRR_ANDROID_PLATFORM_ )\r
112 \r
113 // ----------------------------------------------------------------\r
114 // Android version\r
115 // ----------------------------------------------------------------\r
116 \r
117 #include <android/log.h>\r
118 \r
119 namespace irr\r
120 {\r
121 namespace os\r
122 {\r
123 \r
124         //! prints a debuginfo string\r
125         void Printer::print(const c8* message, ELOG_LEVEL ll)\r
126         {\r
127                 android_LogPriority LogLevel = ANDROID_LOG_UNKNOWN;\r
128 \r
129                 switch (ll)\r
130                 {\r
131                 case ELL_DEBUG:\r
132                         LogLevel = ANDROID_LOG_DEBUG;\r
133                         break;\r
134                 case ELL_INFORMATION:\r
135                         LogLevel = ANDROID_LOG_INFO;\r
136                         break;\r
137                 case ELL_WARNING:\r
138                         LogLevel = ANDROID_LOG_WARN;\r
139                         break;\r
140                 case ELL_ERROR:\r
141                         LogLevel = ANDROID_LOG_ERROR;\r
142                         break;\r
143                 default: // ELL_NONE\r
144                         LogLevel = ANDROID_LOG_VERBOSE;\r
145                         break;\r
146                 }\r
147 \r
148                 // Android logcat restricts log-output and cuts the rest of the message away. But we want it all.\r
149                 // On my device max-len is 1023 (+ 0 byte). Some websites claim a limit of 4096 so maybe different numbers on different devices.\r
150                 const size_t maxLogLen = 1023;\r
151                 size_t msgLen = strlen(message);\r
152                 size_t start = 0;\r
153                 while ( msgLen-start > maxLogLen )\r
154                 {\r
155                         __android_log_print(LogLevel, "Irrlicht", "%.*s\n", maxLogLen, &message[start]);\r
156                         start += maxLogLen;\r
157                 }\r
158                 __android_log_print(LogLevel, "Irrlicht", "%s\n", &message[start]);\r
159         }\r
160 \r
161         void Timer::initTimer(bool usePerformanceTimer)\r
162         {\r
163                 initVirtualTimer();\r
164         }\r
165 \r
166         u32 Timer::getRealTime()\r
167         {\r
168                 timeval tv;\r
169                 gettimeofday(&tv, 0);\r
170                 return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000);\r
171         }\r
172 } // end namespace os\r
173 \r
174 #elif defined(_IRR_EMSCRIPTEN_PLATFORM_)\r
175 \r
176 // ----------------------------------------------------------------\r
177 // emscripten version\r
178 // ----------------------------------------------------------------\r
179 \r
180 #include <emscripten.h>\r
181 #include <time.h>\r
182 #include <sys/time.h>\r
183 \r
184 namespace irr\r
185 {\r
186 namespace os\r
187 {\r
188 \r
189         //! prints a debuginfo string\r
190         void Printer::print(const c8* message, ELOG_LEVEL ll)\r
191         {\r
192         int log_level;\r
193                 switch (ll)\r
194                 {\r
195                 case ELL_DEBUG:\r
196             log_level=0;\r
197                 break;\r
198                 case ELL_INFORMATION:\r
199            log_level=0;\r
200                 break;\r
201                 case ELL_WARNING:\r
202             log_level=EM_LOG_WARN;\r
203                         break;\r
204                 case ELL_ERROR:\r
205             log_level=EM_LOG_ERROR;\r
206                 break;\r
207                 default: // ELL_NONE\r
208             log_level=0;\r
209                         break;\r
210                 }\r
211         emscripten_log(log_level, "%s", message);       // Note: not adding \n as emscripten_log seems to do that already.\r
212         }\r
213 \r
214         void Timer::initTimer(bool usePerformanceTimer)\r
215         {\r
216                 initVirtualTimer();\r
217         }\r
218 \r
219         u32 Timer::getRealTime()\r
220         {\r
221         double time = emscripten_get_now();\r
222         return (u32)(time);\r
223         }\r
224 } // end namespace os\r
225 \r
226 #else\r
227 \r
228 // ----------------------------------------------------------------\r
229 // linux/ansi version\r
230 // ----------------------------------------------------------------\r
231 \r
232 #include <stdio.h>\r
233 #include <time.h>\r
234 #include <sys/time.h>\r
235 \r
236 namespace irr\r
237 {\r
238 namespace os\r
239 {\r
240 \r
241         //! prints a debuginfo string\r
242         void Printer::print(const c8* message, ELOG_LEVEL ll)\r
243         {\r
244                 printf("%s\n", message);\r
245         }\r
246 \r
247         void Timer::initTimer(bool usePerformanceTimer)\r
248         {\r
249                 initVirtualTimer();\r
250         }\r
251 \r
252         u32 Timer::getRealTime()\r
253         {\r
254                 timeval tv;\r
255                 gettimeofday(&tv, 0);\r
256                 return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000);\r
257         }\r
258 } // end namespace os\r
259 \r
260 #endif // end linux / emscripten / android / windows\r
261 \r
262 namespace os\r
263 {\r
264         // The platform independent implementation of the printer\r
265         ILogger* Printer::Logger = 0;\r
266 \r
267         void Printer::log(const c8* message, ELOG_LEVEL ll)\r
268         {\r
269                 if (Logger)\r
270                         Logger->log(message, ll);\r
271         }\r
272 \r
273         void Printer::log(const wchar_t* message, ELOG_LEVEL ll)\r
274         {\r
275                 if (Logger)\r
276                         Logger->log(message, ll);\r
277         }\r
278 \r
279         void Printer::log(const c8* message, const c8* hint, ELOG_LEVEL ll)\r
280         {\r
281                 if (Logger)\r
282                         Logger->log(message, hint, ll);\r
283         }\r
284 \r
285         void Printer::log(const c8* message, const io::path& hint, ELOG_LEVEL ll)\r
286         {\r
287                 if (Logger)\r
288                         Logger->log(message, hint.c_str(), ll);\r
289         }\r
290 \r
291         // ------------------------------------------------------\r
292         // virtual timer implementation\r
293 \r
294         f32 Timer::VirtualTimerSpeed = 1.0f;\r
295         s32 Timer::VirtualTimerStopCounter = 0;\r
296         u32 Timer::LastVirtualTime = 0;\r
297         u32 Timer::StartRealTime = 0;\r
298         u32 Timer::StaticTime = 0;\r
299 \r
300         //! Get real time and date in calendar form\r
301         ITimer::RealTimeDate Timer::getRealTimeAndDate()\r
302         {\r
303                 time_t rawtime;\r
304                 time(&rawtime);\r
305 \r
306                 struct tm * timeinfo;\r
307                 timeinfo = localtime(&rawtime);\r
308 \r
309                 // init with all 0 to indicate error\r
310                 ITimer::RealTimeDate date;\r
311                 memset(&date, 0, sizeof(date));\r
312                 // at least Windows returns NULL on some illegal dates\r
313                 if (timeinfo)\r
314                 {\r
315                         // set useful values if succeeded\r
316                         date.Hour=(u32)timeinfo->tm_hour;\r
317                         date.Minute=(u32)timeinfo->tm_min;\r
318                         date.Second=(u32)timeinfo->tm_sec;\r
319                         date.Day=(u32)timeinfo->tm_mday;\r
320                         date.Month=(u32)timeinfo->tm_mon+1;\r
321                         date.Year=(u32)timeinfo->tm_year+1900;\r
322                         date.Weekday=(ITimer::EWeekday)timeinfo->tm_wday;\r
323                         date.Yearday=(u32)timeinfo->tm_yday+1;\r
324                         date.IsDST=timeinfo->tm_isdst != 0;\r
325                 }\r
326                 return date;\r
327         }\r
328 \r
329         //! returns current virtual time\r
330         u32 Timer::getTime()\r
331         {\r
332                 if (isStopped())\r
333                         return LastVirtualTime;\r
334 \r
335                 return LastVirtualTime + (u32)((StaticTime - StartRealTime) * VirtualTimerSpeed);\r
336         }\r
337 \r
338         //! ticks, advances the virtual timer\r
339         void Timer::tick()\r
340         {\r
341                 StaticTime = getRealTime();\r
342         }\r
343 \r
344         //! sets the current virtual time\r
345         void Timer::setTime(u32 time)\r
346         {\r
347                 StaticTime = getRealTime();\r
348                 LastVirtualTime = time;\r
349                 StartRealTime = StaticTime;\r
350         }\r
351 \r
352         //! stops the virtual timer\r
353         void Timer::stopTimer()\r
354         {\r
355                 if (!isStopped())\r
356                 {\r
357                         // stop the virtual timer\r
358                         LastVirtualTime = getTime();\r
359                 }\r
360 \r
361                 --VirtualTimerStopCounter;\r
362         }\r
363 \r
364         //! starts the virtual timer\r
365         void Timer::startTimer()\r
366         {\r
367                 ++VirtualTimerStopCounter;\r
368 \r
369                 if (!isStopped())\r
370                 {\r
371                         // restart virtual timer\r
372                         setTime(LastVirtualTime);\r
373                 }\r
374         }\r
375 \r
376         //! sets the speed of the virtual timer\r
377         void Timer::setSpeed(f32 speed)\r
378         {\r
379                 setTime(getTime());\r
380 \r
381                 VirtualTimerSpeed = speed;\r
382                 if (VirtualTimerSpeed < 0.0f)\r
383                         VirtualTimerSpeed = 0.0f;\r
384         }\r
385 \r
386         //! gets the speed of the virtual timer\r
387         f32 Timer::getSpeed()\r
388         {\r
389                 return VirtualTimerSpeed;\r
390         }\r
391 \r
392         //! returns if the timer currently is stopped\r
393         bool Timer::isStopped()\r
394         {\r
395                 return VirtualTimerStopCounter < 0;\r
396         }\r
397 \r
398         void Timer::initVirtualTimer()\r
399         {\r
400                 StaticTime = getRealTime();\r
401                 StartRealTime = StaticTime;\r
402         }\r
403 \r
404 } // end namespace os\r
405 } // end namespace irr\r
406 \r
407 \r