您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

206 行
4.0 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://www.wtfpl.net/ for more details.
  9. //
  10. #include <lol/engine-internal.h>
  11. #include <cstdlib>
  12. #include <stdint.h>
  13. #if __linux__ || __native_client__ || __APPLE__ \
  14. || (HAVE_GETTIMEOFDAY && HAVE_USLEEP && HAVE_SYS_TIME_H && HAVE_UNISTD_H)
  15. # include <sys/time.h>
  16. # include <unistd.h>
  17. #elif _XBOX
  18. # include <xtl.h>
  19. # undef near /* Fuck Microsoft */
  20. # undef far /* Fuck Microsoft again */
  21. # include <xbox.h>
  22. #elif _WIN32
  23. # define WIN32_LEAN_AND_MEAN
  24. # include <windows.h>
  25. #elif __CELLOS_LV2__
  26. # include <sys/sys_time.h>
  27. # include <sys/timer.h>
  28. # include <sys/time_util.h>
  29. #elif HAVE_SDL_SDL_H
  30. # include <SDL/SDL.h>
  31. #else
  32. # include <SDL.h>
  33. #endif
  34. namespace lol
  35. {
  36. /*
  37. * Timer implementation class
  38. */
  39. class TimerData
  40. {
  41. friend class Timer;
  42. private:
  43. TimerData()
  44. {
  45. Init();
  46. (void)GetSeconds(true);
  47. }
  48. #if __linux__ || __native_client__ || __APPLE__ \
  49. || (HAVE_GETTIMEOFDAY && HAVE_USLEEP)
  50. inline void Init()
  51. {
  52. m_tv.tv_usec = 0;
  53. m_tv.tv_sec = 0;
  54. }
  55. float GetSeconds(bool reset)
  56. {
  57. struct timeval tv, tv0 = m_tv;
  58. gettimeofday(&tv, nullptr);
  59. if (reset)
  60. m_tv = tv;
  61. return 1e-6f * (tv.tv_usec - tv0.tv_usec) + (tv.tv_sec - tv0.tv_sec);
  62. }
  63. static void WaitSeconds(float seconds)
  64. {
  65. if (seconds > 0.0f)
  66. usleep((int)(seconds * 1e6f));
  67. }
  68. struct timeval m_tv;
  69. #elif _WIN32
  70. inline void Init()
  71. {
  72. m_cycles.QuadPart = 0;
  73. }
  74. float GetSeconds(bool reset)
  75. {
  76. static float secs_per_cycle = GetSecondsPerCycle();
  77. LARGE_INTEGER cycles, cycles0 = m_cycles;
  78. QueryPerformanceCounter(&cycles);
  79. if (reset)
  80. m_cycles = cycles;
  81. return secs_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
  82. }
  83. static void WaitSeconds(float seconds)
  84. {
  85. if (seconds > 5e-4f)
  86. Sleep((int)(seconds * 1e3f + 0.5f));
  87. }
  88. static float GetSecondsPerCycle()
  89. {
  90. LARGE_INTEGER tmp;
  91. QueryPerformanceFrequency(&tmp);
  92. return 1.f / tmp.QuadPart;
  93. }
  94. LARGE_INTEGER m_cycles;
  95. #elif __CELLOS_LV2__
  96. inline void Init()
  97. {
  98. m_cycles = 0;
  99. }
  100. float GetSeconds(bool reset)
  101. {
  102. static float secs_per_cycle = GetSecondsPerCycle();
  103. uint64_t cycles, cycles0 = m_cycles;
  104. SYS_TIMEBASE_GET(cycles);
  105. if (reset)
  106. m_cycles = cycles;
  107. return secs_per_cycle * (cycles - cycles0);
  108. }
  109. static void WaitSeconds(float seconds)
  110. {
  111. if (seconds > 0.0f)
  112. sys_timer_usleep((int)(seconds * 1e6f));
  113. }
  114. static float GetSecondsPerCycle()
  115. {
  116. return 1.f / sys_time_get_timebase_frequency();
  117. }
  118. uint64_t m_cycles;
  119. #else
  120. inline void Init()
  121. {
  122. m_ticks = 0;
  123. }
  124. float GetSeconds(bool reset)
  125. {
  126. static bool initialised = Init();
  127. /* The crappy SDL fallback */
  128. Uint32 ticks = SDL_GetTicks(), ticks0 = m_ticks;
  129. if (reset)
  130. m_ticks = ticks;
  131. return 1e-3f * (ticks - ticks0);
  132. }
  133. static void WaitSeconds(float seconds)
  134. {
  135. if (seconds > 5e-4f)
  136. SDL_Delay((int)(seconds * 1e3f + 0.5f));
  137. }
  138. static bool Init()
  139. {
  140. SDL_Init(SDL_INIT_TIMER);
  141. return true;
  142. }
  143. Uint32 m_ticks;
  144. #endif
  145. };
  146. /*
  147. * Timer public class
  148. */
  149. Timer::Timer()
  150. : data(new TimerData())
  151. {
  152. }
  153. Timer::~Timer()
  154. {
  155. delete data;
  156. }
  157. float Timer::Get()
  158. {
  159. return data->GetSeconds(true);
  160. }
  161. float Timer::Poll()
  162. {
  163. return data->GetSeconds(false);
  164. }
  165. void Timer::Wait(float seconds)
  166. {
  167. float secs_elapsed = data->GetSeconds(false);
  168. data->WaitSeconds(seconds - secs_elapsed);
  169. }
  170. } /* namespace lol */