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

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