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
6 #include "irrString.h"
\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
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
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
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
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
60 #if defined(_IRR_WINDOWS_API_)
\r
61 // ----------------------------------------------------------------
\r
62 // Windows specific functions
\r
63 // ----------------------------------------------------------------
\r
65 #define WIN32_LEAN_AND_MEAN
\r
66 #include <windows.h>
\r
73 //! prints a debuginfo string
\r
74 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
76 core::stringc tmp(message);
\r
78 OutputDebugStringA(tmp.c_str());
\r
79 printf("%s", tmp.c_str());
\r
82 static LARGE_INTEGER HighPerformanceFreq;
\r
83 static BOOL HighPerformanceTimerSupport = FALSE;
\r
85 void Timer::initTimer(bool usePerformanceTimer)
\r
87 if (usePerformanceTimer)
\r
88 HighPerformanceTimerSupport = QueryPerformanceFrequency(&HighPerformanceFreq);
\r
90 HighPerformanceTimerSupport = FALSE;
\r
94 u32 Timer::getRealTime()
\r
96 if (HighPerformanceTimerSupport)
\r
98 LARGE_INTEGER nTime;
\r
99 BOOL queriedOK = QueryPerformanceCounter(&nTime);
\r
102 return u32((nTime.QuadPart) * 1000 / HighPerformanceFreq.QuadPart);
\r
105 return GetTickCount();
\r
108 } // end namespace os
\r
111 #elif defined( _IRR_ANDROID_PLATFORM_ )
\r
113 // ----------------------------------------------------------------
\r
115 // ----------------------------------------------------------------
\r
117 #include <android/log.h>
\r
124 //! prints a debuginfo string
\r
125 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
127 android_LogPriority LogLevel = ANDROID_LOG_UNKNOWN;
\r
132 LogLevel = ANDROID_LOG_DEBUG;
\r
134 case ELL_INFORMATION:
\r
135 LogLevel = ANDROID_LOG_INFO;
\r
138 LogLevel = ANDROID_LOG_WARN;
\r
141 LogLevel = ANDROID_LOG_ERROR;
\r
143 default: // ELL_NONE
\r
144 LogLevel = ANDROID_LOG_VERBOSE;
\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
153 while ( msgLen-start > maxLogLen )
\r
155 __android_log_print(LogLevel, "Irrlicht", "%.*s\n", maxLogLen, &message[start]);
\r
156 start += maxLogLen;
\r
158 __android_log_print(LogLevel, "Irrlicht", "%s\n", &message[start]);
\r
161 void Timer::initTimer(bool usePerformanceTimer)
\r
163 initVirtualTimer();
\r
166 u32 Timer::getRealTime()
\r
169 gettimeofday(&tv, 0);
\r
170 return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
\r
172 } // end namespace os
\r
174 #elif defined(_IRR_EMSCRIPTEN_PLATFORM_)
\r
176 // ----------------------------------------------------------------
\r
177 // emscripten version
\r
178 // ----------------------------------------------------------------
\r
180 #include <emscripten.h>
\r
182 #include <sys/time.h>
\r
189 //! prints a debuginfo string
\r
190 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
198 case ELL_INFORMATION:
\r
202 log_level=EM_LOG_WARN;
\r
205 log_level=EM_LOG_ERROR;
\r
207 default: // ELL_NONE
\r
211 emscripten_log(log_level, "%s", message); // Note: not adding \n as emscripten_log seems to do that already.
\r
214 void Timer::initTimer(bool usePerformanceTimer)
\r
216 initVirtualTimer();
\r
219 u32 Timer::getRealTime()
\r
221 double time = emscripten_get_now();
\r
222 return (u32)(time);
\r
224 } // end namespace os
\r
228 // ----------------------------------------------------------------
\r
229 // linux/ansi version
\r
230 // ----------------------------------------------------------------
\r
234 #include <sys/time.h>
\r
241 //! prints a debuginfo string
\r
242 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
244 printf("%s\n", message);
\r
247 void Timer::initTimer(bool usePerformanceTimer)
\r
249 initVirtualTimer();
\r
252 u32 Timer::getRealTime()
\r
255 gettimeofday(&tv, 0);
\r
256 return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
\r
258 } // end namespace os
\r
260 #endif // end linux / emscripten / android / windows
\r
264 // The platform independent implementation of the printer
\r
265 ILogger* Printer::Logger = 0;
\r
267 void Printer::log(const c8* message, ELOG_LEVEL ll)
\r
270 Logger->log(message, ll);
\r
273 void Printer::log(const wchar_t* message, ELOG_LEVEL ll)
\r
276 Logger->log(message, ll);
\r
279 void Printer::log(const c8* message, const c8* hint, ELOG_LEVEL ll)
\r
282 Logger->log(message, hint, ll);
\r
285 void Printer::log(const c8* message, const io::path& hint, ELOG_LEVEL ll)
\r
288 Logger->log(message, hint.c_str(), ll);
\r
291 // ------------------------------------------------------
\r
292 // virtual timer implementation
\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
300 //! Get real time and date in calendar form
\r
301 ITimer::RealTimeDate Timer::getRealTimeAndDate()
\r
306 struct tm * timeinfo;
\r
307 timeinfo = localtime(&rawtime);
\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
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
329 //! returns current virtual time
\r
330 u32 Timer::getTime()
\r
333 return LastVirtualTime;
\r
335 return LastVirtualTime + (u32)((StaticTime - StartRealTime) * VirtualTimerSpeed);
\r
338 //! ticks, advances the virtual timer
\r
341 StaticTime = getRealTime();
\r
344 //! sets the current virtual time
\r
345 void Timer::setTime(u32 time)
\r
347 StaticTime = getRealTime();
\r
348 LastVirtualTime = time;
\r
349 StartRealTime = StaticTime;
\r
352 //! stops the virtual timer
\r
353 void Timer::stopTimer()
\r
357 // stop the virtual timer
\r
358 LastVirtualTime = getTime();
\r
361 --VirtualTimerStopCounter;
\r
364 //! starts the virtual timer
\r
365 void Timer::startTimer()
\r
367 ++VirtualTimerStopCounter;
\r
371 // restart virtual timer
\r
372 setTime(LastVirtualTime);
\r
376 //! sets the speed of the virtual timer
\r
377 void Timer::setSpeed(f32 speed)
\r
379 setTime(getTime());
\r
381 VirtualTimerSpeed = speed;
\r
382 if (VirtualTimerSpeed < 0.0f)
\r
383 VirtualTimerSpeed = 0.0f;
\r
386 //! gets the speed of the virtual timer
\r
387 f32 Timer::getSpeed()
\r
389 return VirtualTimerSpeed;
\r
392 //! returns if the timer currently is stopped
\r
393 bool Timer::isStopped()
\r
395 return VirtualTimerStopCounter < 0;
\r
398 void Timer::initVirtualTimer()
\r
400 StaticTime = getRealTime();
\r
401 StartRealTime = StaticTime;
\r
404 } // end namespace os
\r
405 } // end namespace irr
\r