You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

163 lines
3.5 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 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://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstdlib>
  14. #include <stdint.h>
  15. #if defined __linux__ || defined __APPLE__
  16. # include <sys/time.h>
  17. # include <unistd.h>
  18. #elif defined _WIN32
  19. # define WIN32_LEAN_AND_MEAN
  20. # include <windows.h>
  21. #elif defined __CELLOS_LV2__
  22. # include <sys/sys_time.h>
  23. # include <sys/timer.h>
  24. # include <sys/time_util.h>
  25. #else
  26. # include <SDL.h>
  27. #endif
  28. #include "core.h"
  29. namespace lol
  30. {
  31. /*
  32. * Timer implementation class
  33. */
  34. class TimerData
  35. {
  36. friend class Timer;
  37. private:
  38. TimerData()
  39. {
  40. #if defined __linux__ || defined __APPLE__
  41. gettimeofday(&tv0, NULL);
  42. #elif defined _WIN32
  43. QueryPerformanceCounter(&cycles0);
  44. #elif defined __CELLOS_LV2__
  45. SYS_TIMEBASE_GET(cycles0);
  46. #else
  47. SDL_Init(SDL_INIT_TIMER);
  48. ticks0 = SDL_GetTicks();
  49. #endif
  50. }
  51. float GetOrWait(float deltams, bool update)
  52. {
  53. float ret, towait;
  54. #if defined __linux__ || defined __APPLE__
  55. struct timeval tv;
  56. gettimeofday(&tv, NULL);
  57. ret = 1e-3f * (tv.tv_usec - tv0.tv_usec)
  58. + 1e3f * (tv.tv_sec - tv0.tv_sec);
  59. if (update)
  60. tv0 = tv;
  61. towait = deltams - ret;
  62. if (towait > 0.0f)
  63. usleep((int)(towait * 1e3f));
  64. #elif defined _WIN32
  65. LARGE_INTEGER cycles;
  66. QueryPerformanceCounter(&cycles);
  67. static float ms_per_cycle = GetMsPerCycle();
  68. ret = ms_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
  69. if (update)
  70. cycles0 = cycles;
  71. towait = deltams - ret;
  72. if (towait > 5e-4f)
  73. Sleep((int)(towait + 0.5f));
  74. #elif defined __CELLOS_LV2__
  75. uint64_t cycles;
  76. SYS_TIMEBASE_GET(cycles);
  77. static float ms_per_cycle = GetMsPerCycle();
  78. ret = ms_per_cycle * (cycles - cycles0);
  79. if (update)
  80. cycles0 = cycles;
  81. towait = deltams - ret;
  82. if (towait > 0.0f)
  83. sys_timer_usleep((int)(towait * 1e3f));
  84. #else
  85. /* The crappy SDL fallback */
  86. Uint32 ticks = SDL_GetTicks();
  87. ret = ticks - ticks0;
  88. if (update)
  89. ticks0 = ticks;
  90. towait = deltams - ret;
  91. if (towait > 0.5f)
  92. SDL_Delay((int)(towait + 0.5f));
  93. #endif
  94. return ret;
  95. }
  96. static float GetMsPerCycle()
  97. {
  98. #if defined __linux__ || defined __APPLE__
  99. return 1.0f;
  100. #elif defined _WIN32
  101. LARGE_INTEGER tmp;
  102. QueryPerformanceFrequency(&tmp);
  103. return 1e3f / tmp.QuadPart;
  104. #elif defined __CELLOS_LV2__
  105. return 1e3f / sys_time_get_timebase_frequency();
  106. #else
  107. return 1.0f;
  108. #endif
  109. }
  110. #if defined __linux__ || defined __APPLE__
  111. struct timeval tv0;
  112. #elif defined _WIN32
  113. LARGE_INTEGER cycles0;
  114. #elif defined __CELLOS_LV2__
  115. uint64_t cycles0;
  116. #else
  117. Uint32 ticks0;
  118. #endif
  119. };
  120. /*
  121. * Timer public class
  122. */
  123. Timer::Timer()
  124. : data(new TimerData())
  125. {
  126. }
  127. Timer::~Timer()
  128. {
  129. delete data;
  130. }
  131. float Timer::GetMs()
  132. {
  133. return data->GetOrWait(0.0f, true);
  134. }
  135. float Timer::PollMs()
  136. {
  137. return data->GetOrWait(0.0f, false);
  138. }
  139. void Timer::WaitMs(float deltams)
  140. {
  141. (void)data->GetOrWait(deltams, false);
  142. }
  143. } /* namespace lol */