SDL_systimer.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:5k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. #ifdef SAVE_RCSID
  19. static char rcsid =
  20.  "@(#) $Id: SDL_systimer.c,v 1.4 2002/04/22 21:38:03 wmay Exp $";
  21. #endif
  22. #include <windows.h>
  23. #include <mmsystem.h>
  24. #include "SDL_timer.h"
  25. #include "SDL_timer_c.h"
  26. #include "SDL_error.h"
  27. #ifdef _WIN32_WCE
  28. #define USE_GETTICKCOUNT
  29. #define USE_SETTIMER
  30. #endif
  31. #define TIME_WRAP_VALUE (~(DWORD)0)
  32. /* The first (low-resolution) ticks value of the application */
  33. static DWORD start;
  34. #ifndef USE_GETTICKCOUNT
  35. /* Store if a high-resolution performance counter exists on the system */
  36. static BOOL hires_timer_available;
  37. /* The first high-resolution ticks value of the application */
  38. static LARGE_INTEGER hires_start_ticks;
  39. /* The number of ticks per second of the high-resolution performance counter */
  40. static LARGE_INTEGER hires_ticks_per_second;
  41. #endif
  42. void SDL_StartTicks(void)
  43. {
  44. /* Set first ticks value */
  45. #ifdef USE_GETTICKCOUNT
  46. start = GetTickCount();
  47. #else
  48. #if 0 /* Apparently there are problems with QPC on Win2K */
  49. if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE)
  50. {
  51. hires_timer_available = TRUE;
  52. QueryPerformanceCounter(&hires_start_ticks);
  53. }
  54. else
  55. #endif
  56. {
  57. hires_timer_available = FALSE;
  58. timeBeginPeriod(1); /* use 1 ms timer precision */
  59. start = timeGetTime();
  60. }
  61. #endif
  62. }
  63. Uint32 SDL_GetTicks(void)
  64. {
  65. DWORD now, ticks;
  66. #ifndef USE_GETTICKCOUNT
  67. LARGE_INTEGER hires_now;
  68. #endif
  69. #ifdef USE_GETTICKCOUNT
  70. now = GetTickCount();
  71. #else
  72. if (hires_timer_available)
  73. {
  74. QueryPerformanceCounter(&hires_now);
  75. hires_now.QuadPart -= hires_start_ticks.QuadPart;
  76. hires_now.QuadPart *= 1000;
  77. hires_now.QuadPart /= hires_ticks_per_second.QuadPart;
  78. return (DWORD)hires_now.QuadPart;
  79. }
  80. else
  81. {
  82. now = timeGetTime();
  83. }
  84. #endif
  85. if ( now < start ) {
  86. ticks = (TIME_WRAP_VALUE-start) + now;
  87. } else {
  88. ticks = (now - start);
  89. }
  90. return(ticks);
  91. }
  92. void SDL_Delay(Uint32 ms)
  93. {
  94. Sleep(ms);
  95. }
  96. #ifdef USE_SETTIMER
  97. static UINT WIN_timer;
  98. int SDL_SYS_TimerInit(void)
  99. {
  100. return(0);
  101. }
  102. void SDL_SYS_TimerQuit(void)
  103. {
  104. return;
  105. }
  106. /* Forward declaration because this is called by the timer callback */
  107. int SDL_SYS_StartTimer(void);
  108. static VOID CALLBACK TimerCallbackProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
  109. {
  110. Uint32 ms;
  111. ms = SDL_alarm_callback(SDL_alarm_interval);
  112. if ( ms != SDL_alarm_interval ) {
  113. KillTimer(NULL, idEvent);
  114. if ( ms ) {
  115. SDL_alarm_interval = ROUND_RESOLUTION(ms);
  116. SDL_SYS_StartTimer();
  117. } else {
  118. SDL_alarm_interval = 0;
  119. }
  120. }
  121. }
  122. int SDL_SYS_StartTimer(void)
  123. {
  124. int retval;
  125. WIN_timer = SetTimer(NULL, 0, SDL_alarm_interval, TimerCallbackProc);
  126. if ( WIN_timer ) {
  127. retval = 0;
  128. } else {
  129. retval = -1;
  130. }
  131. return retval;
  132. }
  133. void SDL_SYS_StopTimer(void)
  134. {
  135. if ( WIN_timer ) {
  136. KillTimer(NULL, WIN_timer);
  137. WIN_timer = 0;
  138. }
  139. }
  140. #else /* !USE_SETTIMER */
  141. /* Data to handle a single periodic alarm */
  142. static UINT timerID = 0;
  143. static void CALLBACK HandleAlarm(UINT uID,  UINT uMsg, DWORD dwUser,
  144. DWORD dw1, DWORD dw2)
  145. {
  146. SDL_ThreadedTimerCheck();
  147. }
  148. int SDL_SYS_TimerInit(void)
  149. {
  150. MMRESULT result;
  151. /* Set timer resolution */
  152. result = timeBeginPeriod(TIMER_RESOLUTION);
  153. if ( result != TIMERR_NOERROR ) {
  154. SDL_SetError("Warning: Can't set %d ms timer resolution",
  155. TIMER_RESOLUTION);
  156. }
  157. /* Allow 10 ms of drift so we don't chew on CPU */
  158. timerID = timeSetEvent(TIMER_RESOLUTION,1,HandleAlarm,0,TIME_PERIODIC);
  159. if ( ! timerID ) {
  160. SDL_SetError("timeSetEvent() failed");
  161. return(-1);
  162. }
  163. return(SDL_SetTimerThreaded(1));
  164. }
  165. void SDL_SYS_TimerQuit(void)
  166. {
  167. if ( timerID ) {
  168. timeKillEvent(timerID);
  169. }
  170. timeEndPeriod(TIMER_RESOLUTION);
  171. }
  172. int SDL_SYS_StartTimer(void)
  173. {
  174. SDL_SetError("Internal logic error: Win32 uses threaded timer");
  175. return(-1);
  176. }
  177. void SDL_SYS_StopTimer(void)
  178. {
  179. return;
  180. }
  181. #endif /* USE_SETTIMER */