porting.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. /*
  17. Random portability stuff
  18. */
  19. #pragma once
  20. #ifdef _WIN32
  21. #ifdef _WIN32_WINNT
  22. #undef _WIN32_WINNT
  23. #endif
  24. #define _WIN32_WINNT 0x0501 // We need to do this before any other headers
  25. // because those might include sdkddkver.h which defines _WIN32_WINNT if not already set
  26. #endif
  27. #include <string>
  28. #include <vector>
  29. #include "irrlicht.h"
  30. #include "irrlichttypes.h" // u32
  31. #include "irrlichttypes_extrabloated.h"
  32. #include "debug.h"
  33. #include "constants.h"
  34. #include "gettime.h"
  35. #ifdef _MSC_VER
  36. #define SWPRINTF_CHARSTRING L"%S"
  37. #else
  38. #define SWPRINTF_CHARSTRING L"%s"
  39. #endif
  40. //currently not needed
  41. //template<typename T> struct alignment_trick { char c; T member; };
  42. //#define ALIGNOF(type) offsetof (alignment_trick<type>, member)
  43. #ifdef _WIN32
  44. #include <windows.h>
  45. #define sleep_ms(x) Sleep(x)
  46. #else
  47. #include <unistd.h>
  48. #include <cstdint> //for uintptr_t
  49. // Use standard Posix macro for Linux
  50. #if (defined(linux) || defined(__linux)) && !defined(__linux__)
  51. #define __linux__
  52. #endif
  53. #if (defined(__linux__) || defined(__GNU__)) && !defined(_GNU_SOURCE)
  54. #define _GNU_SOURCE
  55. #endif
  56. #define sleep_ms(x) usleep(x*1000)
  57. #endif
  58. #ifdef _MSC_VER
  59. #define ALIGNOF(x) __alignof(x)
  60. #define strtok_r(x, y, z) strtok_s(x, y, z)
  61. #define strtof(x, y) (float)strtod(x, y)
  62. #define strtoll(x, y, z) _strtoi64(x, y, z)
  63. #define strtoull(x, y, z) _strtoui64(x, y, z)
  64. #define strcasecmp(x, y) stricmp(x, y)
  65. #define strncasecmp(x, y, n) strnicmp(x, y, n)
  66. #else
  67. #define ALIGNOF(x) __alignof__(x)
  68. #endif
  69. #ifdef __MINGW32__
  70. #define strtok_r(x, y, z) mystrtok_r(x, y, z)
  71. #endif
  72. // strlcpy is missing from glibc. thanks a lot, drepper.
  73. // strlcpy is also missing from AIX and HP-UX because they aim to be weird.
  74. // We can't simply alias strlcpy to MSVC's strcpy_s, since strcpy_s by
  75. // default raises an assertion error and aborts the program if the buffer is
  76. // too small.
  77. #if defined(__FreeBSD__) || defined(__NetBSD__) || \
  78. defined(__OpenBSD__) || defined(__DragonFly__) || \
  79. defined(__APPLE__) || \
  80. defined(__sun) || defined(sun) || \
  81. defined(__QNX__) || defined(__QNXNTO__)
  82. #define HAVE_STRLCPY
  83. #endif
  84. // So we need to define our own.
  85. #ifndef HAVE_STRLCPY
  86. #define strlcpy(d, s, n) mystrlcpy(d, s, n)
  87. #endif
  88. #define PADDING(x, y) ((ALIGNOF(y) - ((uintptr_t)(x) & (ALIGNOF(y) - 1))) & (ALIGNOF(y) - 1))
  89. #if defined(__APPLE__)
  90. #include <mach-o/dyld.h>
  91. #include <CoreFoundation/CoreFoundation.h>
  92. #endif
  93. #ifndef _WIN32 // Posix
  94. #include <sys/time.h>
  95. #include <ctime>
  96. #if defined(__MACH__) && defined(__APPLE__)
  97. #include <mach/clock.h>
  98. #include <mach/mach.h>
  99. #endif
  100. #endif
  101. namespace porting
  102. {
  103. /*
  104. Signal handler (grabs Ctrl-C on POSIX systems)
  105. */
  106. void signal_handler_init();
  107. // Returns a pointer to a bool.
  108. // When the bool is true, program should quit.
  109. bool * signal_handler_killstatus();
  110. /*
  111. Path of static data directory.
  112. */
  113. extern std::string path_share;
  114. /*
  115. Directory for storing user data. Examples:
  116. Windows: "C:\Documents and Settings\user\Application Data\<PROJECT_NAME>"
  117. Linux: "~/.<PROJECT_NAME>"
  118. Mac: "~/Library/Application Support/<PROJECT_NAME>"
  119. */
  120. extern std::string path_user;
  121. /*
  122. Path to gettext locale files
  123. */
  124. extern std::string path_locale;
  125. /*
  126. Path to directory for storing caches.
  127. */
  128. extern std::string path_cache;
  129. /*
  130. Get full path of stuff in data directory.
  131. Example: "stone.png" -> "../data/stone.png"
  132. */
  133. std::string getDataPath(const char *subpath);
  134. /*
  135. Move cache folder from path_user to the
  136. system cache location if possible.
  137. */
  138. void migrateCachePath();
  139. /*
  140. Initialize path_*.
  141. */
  142. void initializePaths();
  143. /*
  144. Return system information
  145. e.g. "Linux/3.12.7 x86_64"
  146. */
  147. std::string get_sysinfo();
  148. // Monotonic counter getters.
  149. #ifdef _WIN32 // Windows
  150. extern double perf_freq;
  151. inline u64 os_get_time(double mult)
  152. {
  153. LARGE_INTEGER t;
  154. QueryPerformanceCounter(&t);
  155. return static_cast<double>(t.QuadPart) / (perf_freq / mult);
  156. }
  157. // Resolution is <1us.
  158. inline u64 getTimeS() { return os_get_time(1); }
  159. inline u64 getTimeMs() { return os_get_time(1000); }
  160. inline u64 getTimeUs() { return os_get_time(1000*1000); }
  161. inline u64 getTimeNs() { return os_get_time(1000*1000*1000); }
  162. #else // Posix
  163. inline void os_get_clock(struct timespec *ts)
  164. {
  165. #if defined(__MACH__) && defined(__APPLE__)
  166. // From http://stackoverflow.com/questions/5167269/clock-gettime-alternative-in-mac-os-x
  167. // OS X does not have clock_gettime, use clock_get_time
  168. clock_serv_t cclock;
  169. mach_timespec_t mts;
  170. host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
  171. clock_get_time(cclock, &mts);
  172. mach_port_deallocate(mach_task_self(), cclock);
  173. ts->tv_sec = mts.tv_sec;
  174. ts->tv_nsec = mts.tv_nsec;
  175. #elif defined(CLOCK_MONOTONIC_RAW)
  176. clock_gettime(CLOCK_MONOTONIC_RAW, ts);
  177. #elif defined(_POSIX_MONOTONIC_CLOCK)
  178. clock_gettime(CLOCK_MONOTONIC, ts);
  179. #else
  180. struct timeval tv;
  181. gettimeofday(&tv, NULL);
  182. TIMEVAL_TO_TIMESPEC(&tv, ts);
  183. #endif
  184. }
  185. inline u64 getTimeS()
  186. {
  187. struct timespec ts;
  188. os_get_clock(&ts);
  189. return ts.tv_sec;
  190. }
  191. inline u64 getTimeMs()
  192. {
  193. struct timespec ts;
  194. os_get_clock(&ts);
  195. return ((u64) ts.tv_sec) * 1000LL + ((u64) ts.tv_nsec) / 1000000LL;
  196. }
  197. inline u64 getTimeUs()
  198. {
  199. struct timespec ts;
  200. os_get_clock(&ts);
  201. return ((u64) ts.tv_sec) * 1000000LL + ((u64) ts.tv_nsec) / 1000LL;
  202. }
  203. inline u64 getTimeNs()
  204. {
  205. struct timespec ts;
  206. os_get_clock(&ts);
  207. return ((u64) ts.tv_sec) * 1000000000LL + ((u64) ts.tv_nsec);
  208. }
  209. #endif
  210. inline u64 getTime(TimePrecision prec)
  211. {
  212. switch (prec) {
  213. case PRECISION_SECONDS: return getTimeS();
  214. case PRECISION_MILLI: return getTimeMs();
  215. case PRECISION_MICRO: return getTimeUs();
  216. case PRECISION_NANO: return getTimeNs();
  217. }
  218. FATAL_ERROR("Called getTime with invalid time precision");
  219. }
  220. /**
  221. * Delta calculation function arguments.
  222. * @param old_time_ms old time for delta calculation
  223. * @param new_time_ms new time for delta calculation
  224. * @return positive delta value
  225. */
  226. inline u64 getDeltaMs(u64 old_time_ms, u64 new_time_ms)
  227. {
  228. if (new_time_ms >= old_time_ms) {
  229. return (new_time_ms - old_time_ms);
  230. }
  231. return (old_time_ms - new_time_ms);
  232. }
  233. inline const char *getPlatformName()
  234. {
  235. return
  236. #if defined(ANDROID)
  237. "Android"
  238. #elif defined(__linux__)
  239. "Linux"
  240. #elif defined(_WIN32) || defined(_WIN64)
  241. "Windows"
  242. #elif defined(__DragonFly__) || defined(__FreeBSD__) || \
  243. defined(__NetBSD__) || defined(__OpenBSD__)
  244. "BSD"
  245. #elif defined(__APPLE__) && defined(__MACH__)
  246. #if TARGET_OS_MAC
  247. "OSX"
  248. #elif TARGET_OS_IPHONE
  249. "iOS"
  250. #else
  251. "Apple"
  252. #endif
  253. #elif defined(_AIX)
  254. "AIX"
  255. #elif defined(__hpux)
  256. "HP-UX"
  257. #elif defined(__sun) || defined(sun)
  258. #if defined(__SVR4)
  259. "Solaris"
  260. #else
  261. "SunOS"
  262. #endif
  263. #elif defined(__HAIKU__)
  264. "Haiku"
  265. #elif defined(__CYGWIN__)
  266. "Cygwin"
  267. #elif defined(__unix__) || defined(__unix)
  268. #if defined(_POSIX_VERSION)
  269. "Posix"
  270. #else
  271. "Unix"
  272. #endif
  273. #else
  274. "?"
  275. #endif
  276. ;
  277. }
  278. bool secure_rand_fill_buf(void *buf, size_t len);
  279. // This attaches to the parents process console, or creates a new one if it doesnt exist.
  280. void attachOrCreateConsole();
  281. int mt_snprintf(char *buf, const size_t buf_size, const char *fmt, ...);
  282. /**
  283. * Opens URL in default web browser
  284. *
  285. * Must begin with http:// or https://, and not contain any new lines
  286. *
  287. * @param url The URL
  288. * @return true on success, false on failure
  289. */
  290. bool open_url(const std::string &url);
  291. /**
  292. * Opens a directory in the default file manager
  293. *
  294. * The directory must exist.
  295. *
  296. * @param path Path to directory
  297. * @return true on success, false on failure
  298. */
  299. bool open_directory(const std::string &path);
  300. } // namespace porting
  301. #ifdef __ANDROID__
  302. #include "porting_android.h"
  303. #endif