Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

168 righe
3.7 KiB

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