Atlas - SDL_systimer.c
Home / ext / SDL2 / src / timer / windows Lines: 1 | Size: 5275 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2018 Sam Lantinga <[email protected]> 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 = 0; 34static BOOL ticks_started = FALSE; 35 36/* Store if a high-resolution performance counter exists on the system */ 37static BOOL hires_timer_available; 38/* The first high-resolution ticks value of the application */ 39static LARGE_INTEGER hires_start_ticks; 40/* The number of ticks per second of the high-resolution performance counter */ 41static LARGE_INTEGER hires_ticks_per_second; 42 43static void 44SDL_SetSystemTimerResolution(const UINT uPeriod) 45{ 46#ifndef __WINRT__ 47 static UINT timer_period = 0; 48 49 if (uPeriod != timer_period) { 50 if (timer_period) { 51 timeEndPeriod(timer_period); 52 } 53 54 timer_period = uPeriod; 55 56 if (timer_period) { 57 timeBeginPeriod(timer_period); 58 } 59 } 60#endif 61} 62 63static void SDLCALL 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 SDL_SetSystemTimerResolution(uPeriod); 76 } 77} 78 79void 80SDL_TicksInit(void) 81{ 82 if (ticks_started) { 83 return; 84 } 85 ticks_started = SDL_TRUE; 86 87 /* if we didn't set a precision, set it high. This affects lots of things 88 on Windows besides the SDL timers, like audio callbacks, etc. */ 89 SDL_AddHintCallback(SDL_HINT_TIMER_RESOLUTION, 90 SDL_TimerResolutionChanged, NULL); 91 92 /* Set first ticks value */ 93 /* QueryPerformanceCounter has had problems in the past, but lots of games 94 use it, so we'll rely on it here. 95 */ 96 if (QueryPerformanceFrequency(&hires_ticks_per_second) == TRUE) { 97 hires_timer_available = TRUE; 98 QueryPerformanceCounter(&hires_start_ticks); 99 } else { 100 hires_timer_available = FALSE; 101#ifndef __WINRT__ 102 start = timeGetTime(); 103#endif /* __WINRT__ */ 104 } 105} 106 107void 108SDL_TicksQuit(void) 109{ 110 SDL_DelHintCallback(SDL_HINT_TIMER_RESOLUTION, 111 SDL_TimerResolutionChanged, NULL); 112 113 SDL_SetSystemTimerResolution(0); /* always release our timer resolution request. */ 114 115 start = 0; 116 ticks_started = SDL_FALSE; 117} 118 119Uint32 120SDL_GetTicks(void) 121{ 122 DWORD now = 0; 123 LARGE_INTEGER hires_now; 124 125 if (!ticks_started) { 126 SDL_TicksInit(); 127 } 128 129 if (hires_timer_available) { 130 QueryPerformanceCounter(&hires_now); 131 132 hires_now.QuadPart -= hires_start_ticks.QuadPart; 133 hires_now.QuadPart *= 1000; 134 hires_now.QuadPart /= hires_ticks_per_second.QuadPart; 135 136 return (DWORD) hires_now.QuadPart; 137 } else { 138#ifndef __WINRT__ 139 now = timeGetTime(); 140#endif /* __WINRT__ */ 141 } 142 143 return (now - start); 144} 145 146Uint64 147SDL_GetPerformanceCounter(void) 148{ 149 LARGE_INTEGER counter; 150 151 if (!QueryPerformanceCounter(&counter)) { 152 return SDL_GetTicks(); 153 } 154 return counter.QuadPart; 155} 156 157Uint64 158SDL_GetPerformanceFrequency(void) 159{ 160 LARGE_INTEGER frequency; 161 162 if (!QueryPerformanceFrequency(&frequency)) { 163 return 1000; 164 } 165 return frequency.QuadPart; 166} 167 168void 169SDL_Delay(Uint32 ms) 170{ 171 /* Sleep() is not publicly available to apps in early versions of WinRT. 172 * 173 * Visual C++ 2013 Update 4 re-introduced Sleep() for Windows 8.1 and 174 * Windows Phone 8.1. 175 * 176 * Use the compiler version to determine availability. 177 * 178 * NOTE #1: _MSC_FULL_VER == 180030723 for Visual C++ 2013 Update 3. 179 * NOTE #2: Visual C++ 2013, when compiling for Windows 8.0 and 180 * Windows Phone 8.0, uses the Visual C++ 2012 compiler to build 181 * apps and libraries. 182 */ 183#if defined(__WINRT__) && defined(_MSC_FULL_VER) && (_MSC_FULL_VER <= 180030723) 184 static HANDLE mutex = 0; 185 if (!mutex) { 186 mutex = CreateEventEx(0, 0, 0, EVENT_ALL_ACCESS); 187 } 188 WaitForSingleObjectEx(mutex, ms, FALSE); 189#else 190 if (!ticks_started) { 191 SDL_TicksInit(); 192 } 193 194 Sleep(ms); 195#endif 196} 197 198#endif /* SDL_TIMER_WINDOWS */ 199 200/* vi: set ts=4 sw=4 expandtab: */ 201[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.