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
7 #include "IrrCompileConfig.h"
\r
10 #if defined(_IRR_COMPILE_WITH_SDL_DEVICE_)
\r
11 #include <SDL_endian.h>
\r
12 #define bswap_16(X) SDL_Swap16(X)
\r
13 #define bswap_32(X) SDL_Swap32(X)
\r
14 #define bswap_64(X) SDL_Swap64(X)
\r
15 #elif defined(_IRR_WINDOWS_API_) && defined(_MSC_VER)
\r
17 #define bswap_16(X) _byteswap_ushort(X)
\r
18 #define bswap_32(X) _byteswap_ulong(X)
\r
19 #define bswap_64(X) _byteswap_uint64(X)
\r
20 #define localtime _localtime_s
\r
21 #elif defined(_IRR_OSX_PLATFORM_) || defined(_IRR_IOS_PLATFORM_)
\r
22 #include <libkern/OSByteOrder.h>
\r
23 #define bswap_16(X) OSReadSwapInt16(&X,0)
\r
24 #define bswap_32(X) OSReadSwapInt32(&X,0)
\r
25 #define bswap_64(X) OSReadSwapInt64(&X,0)
\r
26 #elif defined(__FreeBSD__)
\r
27 #include <sys/endian.h>
\r
28 #define bswap_16(X) bswap16(X)
\r
29 #define bswap_32(X) bswap32(X)
\r
30 #define bswap_64(X) bswap64(X)
\r
31 #elif defined(__OpenBSD__)
\r
33 #define bswap_16(X) letoh16(X)
\r
34 #define bswap_32(X) letoh32(X)
\r
35 #define bswap_64(X) letoh64(X)
\r
36 #elif !defined(_IRR_SOLARIS_PLATFORM_) && !defined(__PPC__) && !defined(_IRR_WINDOWS_API_)
\r
37 #include <byteswap.h>
\r
39 #define bswap_16(X) ((((X)&0xFF) << 8) | (((X)&0xFF00) >> 8))
\r
40 #define bswap_32(X) ((((X)&0x000000FF) << 24) | (((X)&0xFF000000) >> 24) | (((X)&0x0000FF00) << 8) | (((X) &0x00FF0000) >> 8))
\r
41 #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
48 u16 Byteswap::byteswap(u16 num) {return bswap_16(num);}
\r
49 s16 Byteswap::byteswap(s16 num) {return bswap_16(num);}
\r
50 u32 Byteswap::byteswap(u32 num) {return bswap_32(num);}
\r
51 s32 Byteswap::byteswap(s32 num) {return bswap_32(num);}
\r
52 u64 Byteswap::byteswap(u64 num) {return bswap_64(num);}
\r
53 s64 Byteswap::byteswap(s64 num) {return bswap_64(num);}
\r
54 f32 Byteswap::byteswap(f32 num) {u32 tmp=IR(num); tmp=bswap_32(tmp); return (FR(tmp));}
\r
55 // prevent accidental byte swapping of chars
\r
56 u8 Byteswap::byteswap(u8 num) {return num;}
\r
57 c8 Byteswap::byteswap(c8 num) {return num;}
\r
61 #if defined(_IRR_WINDOWS_API_)
\r
62 // ----------------------------------------------------------------
\r
63 // Windows specific functions
\r
64 // ----------------------------------------------------------------
\r
66 #define WIN32_LEAN_AND_MEAN
\r
67 #include <windows.h>
\r
74 //! prints a debuginfo string
\r
75 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
77 core::stringc tmp(message);
\r
79 OutputDebugStringA(tmp.c_str());
\r
80 printf("%s", tmp.c_str());
\r
83 static LARGE_INTEGER HighPerformanceFreq;
\r
84 static BOOL HighPerformanceTimerSupport = FALSE;
\r
86 void Timer::initTimer(bool usePerformanceTimer)
\r
88 if (usePerformanceTimer)
\r
89 HighPerformanceTimerSupport = QueryPerformanceFrequency(&HighPerformanceFreq);
\r
91 HighPerformanceTimerSupport = FALSE;
\r
95 u32 Timer::getRealTime()
\r
97 if (HighPerformanceTimerSupport)
\r
99 LARGE_INTEGER nTime;
\r
100 BOOL queriedOK = QueryPerformanceCounter(&nTime);
\r
103 return u32((nTime.QuadPart) * 1000 / HighPerformanceFreq.QuadPart);
\r
106 return GetTickCount();
\r
109 } // end namespace os
\r
112 #elif defined( _IRR_ANDROID_PLATFORM_ )
\r
114 // ----------------------------------------------------------------
\r
116 // ----------------------------------------------------------------
\r
118 #include <android/log.h>
\r
125 //! prints a debuginfo string
\r
126 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
128 android_LogPriority LogLevel = ANDROID_LOG_UNKNOWN;
\r
133 LogLevel = ANDROID_LOG_DEBUG;
\r
135 case ELL_INFORMATION:
\r
136 LogLevel = ANDROID_LOG_INFO;
\r
139 LogLevel = ANDROID_LOG_WARN;
\r
142 LogLevel = ANDROID_LOG_ERROR;
\r
144 default: // ELL_NONE
\r
145 LogLevel = ANDROID_LOG_VERBOSE;
\r
149 // Android logcat restricts log-output and cuts the rest of the message away. But we want it all.
\r
150 // On my device max-len is 1023 (+ 0 byte). Some websites claim a limit of 4096 so maybe different numbers on different devices.
\r
151 const size_t maxLogLen = 1023;
\r
152 size_t msgLen = strlen(message);
\r
154 while ( msgLen-start > maxLogLen )
\r
156 __android_log_print(LogLevel, "Irrlicht", "%.*s\n", maxLogLen, &message[start]);
\r
157 start += maxLogLen;
\r
159 __android_log_print(LogLevel, "Irrlicht", "%s\n", &message[start]);
\r
162 void Timer::initTimer(bool usePerformanceTimer)
\r
164 initVirtualTimer();
\r
167 u32 Timer::getRealTime()
\r
170 gettimeofday(&tv, 0);
\r
171 return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
\r
173 } // end namespace os
\r
175 #elif defined(_IRR_EMSCRIPTEN_PLATFORM_)
\r
177 // ----------------------------------------------------------------
\r
178 // emscripten version
\r
179 // ----------------------------------------------------------------
\r
181 #include <emscripten.h>
\r
183 #include <sys/time.h>
\r
190 //! prints a debuginfo string
\r
191 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
199 case ELL_INFORMATION:
\r
203 log_level=EM_LOG_WARN;
\r
206 log_level=EM_LOG_ERROR;
\r
208 default: // ELL_NONE
\r
212 emscripten_log(log_level, "%s", message); // Note: not adding \n as emscripten_log seems to do that already.
\r
215 void Timer::initTimer(bool usePerformanceTimer)
\r
217 initVirtualTimer();
\r
220 u32 Timer::getRealTime()
\r
222 double time = emscripten_get_now();
\r
223 return (u32)(time);
\r
225 } // end namespace os
\r
229 // ----------------------------------------------------------------
\r
230 // linux/ansi version
\r
231 // ----------------------------------------------------------------
\r
235 #include <sys/time.h>
\r
242 //! prints a debuginfo string
\r
243 void Printer::print(const c8* message, ELOG_LEVEL ll)
\r
245 printf("%s\n", message);
\r
248 void Timer::initTimer(bool usePerformanceTimer)
\r
250 initVirtualTimer();
\r
253 u32 Timer::getRealTime()
\r
256 gettimeofday(&tv, 0);
\r
257 return (u32)(tv.tv_sec * 1000) + (tv.tv_usec / 1000);
\r
259 } // end namespace os
\r
261 #endif // end linux / emscripten / android / windows
\r
265 // The platform independent implementation of the printer
\r
266 ILogger* Printer::Logger = 0;
\r
268 void Printer::log(const c8* message, ELOG_LEVEL ll)
\r
271 Logger->log(message, ll);
\r
274 void Printer::log(const wchar_t* message, ELOG_LEVEL ll)
\r
277 Logger->log(message, ll);
\r
280 void Printer::log(const c8* message, const c8* hint, ELOG_LEVEL ll)
\r
283 Logger->log(message, hint, ll);
\r
286 void Printer::log(const c8* message, const io::path& hint, ELOG_LEVEL ll)
\r
289 Logger->log(message, hint.c_str(), ll);
\r
292 // ------------------------------------------------------
\r
293 // virtual timer implementation
\r
295 f32 Timer::VirtualTimerSpeed = 1.0f;
\r
296 s32 Timer::VirtualTimerStopCounter = 0;
\r
297 u32 Timer::LastVirtualTime = 0;
\r
298 u32 Timer::StartRealTime = 0;
\r
299 u32 Timer::StaticTime = 0;
\r
301 //! Get real time and date in calendar form
\r
302 ITimer::RealTimeDate Timer::getRealTimeAndDate()
\r
307 struct tm * timeinfo;
\r
308 timeinfo = localtime(&rawtime);
\r
310 // init with all 0 to indicate error
\r
311 ITimer::RealTimeDate date;
\r
312 memset(&date, 0, sizeof(date));
\r
313 // at least Windows returns NULL on some illegal dates
\r
316 // set useful values if succeeded
\r
317 date.Hour=(u32)timeinfo->tm_hour;
\r
318 date.Minute=(u32)timeinfo->tm_min;
\r
319 date.Second=(u32)timeinfo->tm_sec;
\r
320 date.Day=(u32)timeinfo->tm_mday;
\r
321 date.Month=(u32)timeinfo->tm_mon+1;
\r
322 date.Year=(u32)timeinfo->tm_year+1900;
\r
323 date.Weekday=(ITimer::EWeekday)timeinfo->tm_wday;
\r
324 date.Yearday=(u32)timeinfo->tm_yday+1;
\r
325 date.IsDST=timeinfo->tm_isdst != 0;
\r
330 //! returns current virtual time
\r
331 u32 Timer::getTime()
\r
334 return LastVirtualTime;
\r
336 return LastVirtualTime + (u32)((StaticTime - StartRealTime) * VirtualTimerSpeed);
\r
339 //! ticks, advances the virtual timer
\r
342 StaticTime = getRealTime();
\r
345 //! sets the current virtual time
\r
346 void Timer::setTime(u32 time)
\r
348 StaticTime = getRealTime();
\r
349 LastVirtualTime = time;
\r
350 StartRealTime = StaticTime;
\r
353 //! stops the virtual timer
\r
354 void Timer::stopTimer()
\r
358 // stop the virtual timer
\r
359 LastVirtualTime = getTime();
\r
362 --VirtualTimerStopCounter;
\r
365 //! starts the virtual timer
\r
366 void Timer::startTimer()
\r
368 ++VirtualTimerStopCounter;
\r
372 // restart virtual timer
\r
373 setTime(LastVirtualTime);
\r
377 //! sets the speed of the virtual timer
\r
378 void Timer::setSpeed(f32 speed)
\r
380 setTime(getTime());
\r
382 VirtualTimerSpeed = speed;
\r
383 if (VirtualTimerSpeed < 0.0f)
\r
384 VirtualTimerSpeed = 0.0f;
\r
387 //! gets the speed of the virtual timer
\r
388 f32 Timer::getSpeed()
\r
390 return VirtualTimerSpeed;
\r
393 //! returns if the timer currently is stopped
\r
394 bool Timer::isStopped()
\r
396 return VirtualTimerStopCounter < 0;
\r
399 void Timer::initVirtualTimer()
\r
401 StaticTime = getRealTime();
\r
402 StartRealTime = StaticTime;
\r
405 } // end namespace os
\r
406 } // end namespace irr
\r