SDL_systimer.c (4975B)
1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org> 4 5 This software is provided 'as-is', without any express or implied 6 warranty. In no event will the authors be held liable for any damages 7 arising from the use of this software. 8 9 Permission is granted to anyone to use this software for any purpose, 10 including commercial applications, and to alter it and redistribute it 11 freely, subject to the following restrictions: 12 13 1. The origin of this software must not be misrepresented; you must not 14 claim that you wrote the original software. If you use this software 15 in a product, an acknowledgment in the product documentation would be 16 appreciated but is not required. 17 2. Altered source versions must be plainly marked as such, and must not be 18 misrepresented as being the original software. 19 3. This notice may not be removed or altered from any source distribution. 20*/ 21#include "../../SDL_internal.h" 22 23#ifdef SDL_TIMER_WINDOWS 24 25#include "../../core/windows/SDL_windows.h" 26#include <mmsystem.h> 27 28#include "SDL_timer.h" 29#include "SDL_hints.h" 30 31 32/* The first (low-resolution) ticks value of the application */ 33static DWORD start; 34static BOOL ticks_started = FALSE; 35 36#ifndef USE_GETTICKCOUNT 37/* Store if a high-resolution performance counter exists on the system */ 38static BOOL hires_timer_available; 39/* The first high-resolution ticks value of the application */ 40static LARGE_INTEGER hires_start_ticks; 41/* The number of ticks per second of the high-resolution performance counter */ 42static LARGE_INTEGER hires_ticks_per_second; 43 44#ifndef __WINRT__ 45static void 46timeSetPeriod(UINT uPeriod) 47{ 48 static UINT timer_period = 0; 49 50 if (uPeriod != timer_period) { 51 if (timer_period) { 52 timeEndPeriod(timer_period); 53 } 54 55 timer_period = uPeriod; 56 57 if (timer_period) { 58 timeBeginPeriod(timer_period); 59 } 60 } 61} 62 63static void 64SDL_TimerResolutionChanged(void *userdata, const char *name, const char *oldValue, const char *hint) 65{ 66 UINT uPeriod; 67 68 /* Unless the hint says otherwise, let's have good sleep precision */ 69 if (hint && *hint) { 70 uPeriod = SDL_atoi(hint); 71 } else { 72 uPeriod = 1; 73 } 74 if (uPeriod || oldValue != hint) { 75 timeSetPeriod(uPeriod); 76 } 77} 78#endif /* ifndef __WINRT__ */ 79 80#endif /* !USE_GETTICKCOUNT */ 81 82void 83SDL_TicksInit(void) 84{ 85 if (ticks_started) { 86 return; 87 } 88 ticks_started = SDL_TRUE; 89 90 /* Set first ticks value */ 91#ifdef USE_GETTICKCOUNT 92 start = GetTickCount(); 93#else 94 /* QueryPerformanceCounter has had problems in the past, but lots of games 95 use it, so we'll rely on it here. 96 */ 97 if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) { 98 hires_timer_available = TRUE; 99 QueryPerformanceCounter(&hires_start_ticks); 100 } else { 101 hires_timer_available = FALSE; 102#ifdef __WINRT__ 103 start = 0; /* the timer failed to start! */ 104#else 105 timeSetPeriod(1); /* use 1 ms timer precision */ 106 start = timeGetTime(); 107 108 SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION, 109 SDL_TimerResolutionChanged, NULL); 110#endif /* __WINRT__ */ 111 } 112#endif /* USE_GETTICKCOUNT */ 113} 114 115void 116SDL_TicksQuit(void) 117{ 118#ifndef USE_GETTICKCOUNT 119 if (!hires_timer_available) { 120#ifndef __WINRT__ 121 SDL_DelHintCallback(SDL_HINT_TIMER_RESOLUTION, 122 SDL_TimerResolutionChanged, NULL); 123 124 timeSetPeriod(0); 125#endif /* __WINRT__ */ 126 } 127#endif /* USE_GETTICKCOUNT */ 128 129 ticks_started = SDL_FALSE; 130} 131 132Uint32 133SDL_GetTicks(void) 134{ 135 DWORD now; 136#ifndef USE_GETTICKCOUNT 137 LARGE_INTEGER hires_now; 138#endif 139 140 if (!ticks_started) { 141 SDL_TicksInit(); 142 } 143 144#ifdef USE_GETTICKCOUNT 145 now = GetTickCount(); 146#else 147 if (hires_timer_available) { 148 QueryPerformanceCounter(&hires_now); 149 150 hires_now.QuadPart -= hires_start_ticks.QuadPart; 151 hires_now.QuadPart *= 1000; 152 hires_now.QuadPart /= hires_ticks_per_second.QuadPart; 153 154 return (DWORD) hires_now.QuadPart; 155 } else { 156#ifdef __WINRT__ 157 now = 0; 158#else 159 now = timeGetTime(); 160#endif /* __WINRT__ */ 161 } 162#endif 163 164 return (now - start); 165} 166 167Uint64 168SDL_GetPerformanceCounter(void) 169{ 170 LARGE_INTEGER counter; 171 172 if (!QueryPerformanceCounter(&counter)) { 173 return SDL_GetTicks(); 174 } 175 return counter.QuadPart; 176} 177 178Uint64 179SDL_GetPerformanceFrequency(void) 180{ 181 LARGE_INTEGER frequency; 182 183 if (!QueryPerformanceFrequency(&frequency)) { 184 return 1000; 185 } 186 return frequency.QuadPart; 187} 188 189#ifdef __WINRT__ 190static void 191Sleep(DWORD timeout) 192{ 193 static HANDLE mutex = 0; 194 if ( ! mutex ) 195 { 196 mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS); 197 } 198 WaitForSingleObjectEx(mutex, timeout, FALSE); 199} 200#endif 201 202void 203SDL_Delay(Uint32 ms) 204{ 205 Sleep(ms); 206} 207 208#endif /* SDL_TIMER_WINDOWS */ 209 210/* vi: set ts=4 sw=4 expandtab: */