129 wiersze
2.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 <cstdio>
  15. #include <stdint.h>
  16. #if defined __linux__
  17. # include <sys/time.h>
  18. # include <unistd.h>
  19. #elif defined _WIN32
  20. # define WIN32_LEAN_AND_MEAN
  21. # include <windows.h>
  22. #else
  23. # include <SDL.h>
  24. #endif
  25. #include "core.h"
  26. /*
  27. * Timer implementation class
  28. */
  29. class TimerData
  30. {
  31. friend class Timer;
  32. private:
  33. TimerData()
  34. {
  35. #if defined __linux__
  36. gettimeofday(&tv0, NULL);
  37. #elif defined _WIN32
  38. LARGE_INTEGER tmp;
  39. QueryPerformanceFrequency(&tmp);
  40. ms_per_cycle = 1e3f / tmp.QuadPart;
  41. QueryPerformanceCounter(&cycles0);
  42. #else
  43. SDL_Init(SDL_INIT_TIMER);
  44. ticks0 = SDL_GetTicks();
  45. #endif
  46. }
  47. float GetOrWait(float deltams, bool update)
  48. {
  49. float ret, towait;
  50. #if defined __linux__
  51. struct timeval tv;
  52. gettimeofday(&tv, NULL);
  53. ret = 1e-3f * (tv.tv_usec - tv0.tv_usec)
  54. + 1e3f * (tv.tv_sec - tv0.tv_sec);
  55. if (update)
  56. tv0 = tv;
  57. towait = deltams - ret;
  58. if (towait > 0.0f)
  59. usleep((int)(towait * 1e3f));
  60. #elif defined _WIN32
  61. LARGE_INTEGER cycles;
  62. QueryPerformanceCounter(&cycles);
  63. ret = ms_per_cycle * (cycles.QuadPart - cycles0.QuadPart);
  64. if (update)
  65. cycles0 = cycles;
  66. towait = deltams - ret;
  67. if (towait > 5e-4f)
  68. Sleep((int)(towait + 0.5f));
  69. #else
  70. /* The crappy SDL fallback */
  71. Uint32 ticks = SDL_GetTicks();
  72. ret = 1e-6f * (ticks - ticks0);
  73. if (update)
  74. ticks0 = ticks;
  75. towait = deltams - ret;
  76. if (towait > 0.5f)
  77. SDL_Delay((int)(towait + 0.5f));
  78. #endif
  79. return ret;
  80. }
  81. #if defined __linux__
  82. struct timeval tv0;
  83. #elif defined _WIN32
  84. float ms_per_cycle;
  85. LARGE_INTEGER cycles0;
  86. #else
  87. Uint32 ticks0;
  88. #endif
  89. };
  90. /*
  91. * Timer public class
  92. */
  93. Timer::Timer()
  94. : data(new TimerData())
  95. {
  96. }
  97. Timer::~Timer()
  98. {
  99. delete data;
  100. }
  101. float Timer::GetMs()
  102. {
  103. return data->GetOrWait(0.0f, true);
  104. }
  105. float Timer::PollMs()
  106. {
  107. return data->GetOrWait(0.0f, false);
  108. }
  109. void Timer::WaitMs(float deltams)
  110. {
  111. (void)data->GetOrWait(deltams, false);
  112. }