SDL_systimer.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "SDL_config.h"
  19. #ifdef SDL_TIMER_WINDOWS
  20. #include "../../core/windows/SDL_windows.h"
  21. #include <mmsystem.h>
  22. #include "SDL_timer.h"
  23. #include "SDL_hints.h"
  24. /* The first (low-resolution) ticks value of the application */
  25. static DWORD start;
  26. static BOOL ticks_started = FALSE;
  27. #ifndef USE_GETTICKCOUNT
  28. /* Store if a high-resolution performance counter exists on the system */
  29. static BOOL hires_timer_available;
  30. /* The first high-resolution ticks value of the application */
  31. static LARGE_INTEGER hires_start_ticks;
  32. /* The number of ticks per second of the high-resolution performance counter */
  33. static LARGE_INTEGER hires_ticks_per_second;
  34. #endif
  35. static void
  36. timeSetPeriod(UINT uPeriod)
  37. {
  38. static UINT timer_period = 0;
  39. if (uPeriod != timer_period) {
  40. if (timer_period) {
  41. timeEndPeriod(timer_period);
  42. }
  43. timer_period = uPeriod;
  44. if (timer_period) {
  45. timeBeginPeriod(timer_period);
  46. }
  47. }
  48. }
  49. static void
  50. SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
  51. {
  52. UINT uPeriod;
  53. /* Unless the hint says otherwise, let's have good sleep precision */
  54. if (hint && *hint) {
  55. uPeriod = SDL_atoi(hint);
  56. } else {
  57. uPeriod = 1;
  58. }
  59. if (uPeriod || oldValue != hint) {
  60. timeSetPeriod(uPeriod);
  61. }
  62. }
  63. void
  64. SDL_InitTicks(void)
  65. {
  66. if (ticks_started) {
  67. return;
  68. }
  69. ticks_started = TRUE;
  70. /* Set first ticks value */
  71. #ifdef USE_GETTICKCOUNT
  72. start = GetTickCount();
  73. #else
  74. /* QueryPerformanceCounter has had problems in the past, but lots of games
  75. use it, so we'll rely on it here.
  76. */
  77. if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) {
  78. hires_timer_available = TRUE;
  79. QueryPerformanceCounter(&hires_start_ticks);
  80. } else {
  81. hires_timer_available = FALSE;
  82. timeSetPeriod(1); /* use 1 ms timer precision */
  83. start = timeGetTime();
  84. }
  85. #endif
  86. SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION,
  87. SDL_TimerResolutionChanged, NULL);
  88. }
  89. Uint32
  90. SDL_GetTicks(void)
  91. {
  92. DWORD now;
  93. #ifndef USE_GETTICKCOUNT
  94. LARGE_INTEGER hires_now;
  95. #endif
  96. if (!ticks_started) {
  97. SDL_InitTicks();
  98. }
  99. #ifdef USE_GETTICKCOUNT
  100. now = GetTickCount();
  101. #else
  102. if (hires_timer_available) {
  103. QueryPerformanceCounter(&hires_now);
  104. hires_now.QuadPart -= hires_start_ticks.QuadPart;
  105. hires_now.QuadPart *= 1000;
  106. hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
  107. return (DWORD) hires_now.QuadPart;
  108. } else {
  109. now = timeGetTime();
  110. }
  111. #endif
  112. return (now - start);
  113. }
  114. Uint64
  115. SDL_GetPerformanceCounter(void)
  116. {
  117. LARGE_INTEGER counter;
  118. if (!QueryPerformanceCounter(&counter)) {
  119. return SDL_GetTicks();
  120. }
  121. return counter.QuadPart;
  122. }
  123. Uint64
  124. SDL_GetPerformanceFrequency(void)
  125. {
  126. LARGE_INTEGER frequency;
  127. if (!QueryPerformanceFrequency(&frequency)) {
  128. return 1000;
  129. }
  130. return frequency.QuadPart;
  131. }
  132. void
  133. SDL_Delay(Uint32 ms)
  134. {
  135. Sleep(ms);
  136. }
  137. #endif /* SDL_TIMER_WINDOWS */
  138. /* vi: set ts=4 sw=4 expandtab: */