diff options
Diffstat (limited to 'src/common/timer.cpp')
| -rw-r--r-- | src/common/timer.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/common/timer.cpp b/src/common/timer.cpp new file mode 100644 index 000000000..90604292e --- /dev/null +++ b/src/common/timer.cpp | |||
| @@ -0,0 +1,226 @@ | |||
| 1 | // Copyright 2013 Dolphin Emulator Project | ||
| 2 | // Licensed under GPLv2 | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <time.h> | ||
| 6 | |||
| 7 | #ifdef _WIN32 | ||
| 8 | #include <Windows.h> | ||
| 9 | #include <mmsystem.h> | ||
| 10 | #include <sys/timeb.h> | ||
| 11 | #else | ||
| 12 | #include <sys/time.h> | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #include "common.h" | ||
| 16 | #include "timer.h" | ||
| 17 | #include "string_util.h" | ||
| 18 | |||
| 19 | namespace Common | ||
| 20 | { | ||
| 21 | |||
| 22 | u32 Timer::GetTimeMs() | ||
| 23 | { | ||
| 24 | #ifdef _WIN32 | ||
| 25 | return timeGetTime(); | ||
| 26 | #else | ||
| 27 | struct timeval t; | ||
| 28 | (void)gettimeofday(&t, NULL); | ||
| 29 | return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); | ||
| 30 | #endif | ||
| 31 | } | ||
| 32 | |||
| 33 | // -------------------------------------------- | ||
| 34 | // Initiate, Start, Stop, and Update the time | ||
| 35 | // -------------------------------------------- | ||
| 36 | |||
| 37 | // Set initial values for the class | ||
| 38 | Timer::Timer() | ||
| 39 | : m_LastTime(0), m_StartTime(0), m_Running(false) | ||
| 40 | { | ||
| 41 | Update(); | ||
| 42 | } | ||
| 43 | |||
| 44 | // Write the starting time | ||
| 45 | void Timer::Start() | ||
| 46 | { | ||
| 47 | m_StartTime = GetTimeMs(); | ||
| 48 | m_Running = true; | ||
| 49 | } | ||
| 50 | |||
| 51 | // Stop the timer | ||
| 52 | void Timer::Stop() | ||
| 53 | { | ||
| 54 | // Write the final time | ||
| 55 | m_LastTime = GetTimeMs(); | ||
| 56 | m_Running = false; | ||
| 57 | } | ||
| 58 | |||
| 59 | // Update the last time variable | ||
| 60 | void Timer::Update() | ||
| 61 | { | ||
| 62 | m_LastTime = GetTimeMs(); | ||
| 63 | //TODO(ector) - QPF | ||
| 64 | } | ||
| 65 | |||
| 66 | // ------------------------------------- | ||
| 67 | // Get time difference and elapsed time | ||
| 68 | // ------------------------------------- | ||
| 69 | |||
| 70 | // Get the number of milliseconds since the last Update() | ||
| 71 | u64 Timer::GetTimeDifference() | ||
| 72 | { | ||
| 73 | return GetTimeMs() - m_LastTime; | ||
| 74 | } | ||
| 75 | |||
| 76 | // Add the time difference since the last Update() to the starting time. | ||
| 77 | // This is used to compensate for a paused game. | ||
| 78 | void Timer::AddTimeDifference() | ||
| 79 | { | ||
| 80 | m_StartTime += GetTimeDifference(); | ||
| 81 | } | ||
| 82 | |||
| 83 | // Get the time elapsed since the Start() | ||
| 84 | u64 Timer::GetTimeElapsed() | ||
| 85 | { | ||
| 86 | // If we have not started yet, return 1 (because then I don't | ||
| 87 | // have to change the FPS calculation in CoreRerecording.cpp . | ||
| 88 | if (m_StartTime == 0) return 1; | ||
| 89 | |||
| 90 | // Return the final timer time if the timer is stopped | ||
| 91 | if (!m_Running) return (m_LastTime - m_StartTime); | ||
| 92 | |||
| 93 | return (GetTimeMs() - m_StartTime); | ||
| 94 | } | ||
| 95 | |||
| 96 | // Get the formatted time elapsed since the Start() | ||
| 97 | std::string Timer::GetTimeElapsedFormatted() const | ||
| 98 | { | ||
| 99 | // If we have not started yet, return zero | ||
| 100 | if (m_StartTime == 0) | ||
| 101 | return "00:00:00:000"; | ||
| 102 | |||
| 103 | // The number of milliseconds since the start. | ||
| 104 | // Use a different value if the timer is stopped. | ||
| 105 | u64 Milliseconds; | ||
| 106 | if (m_Running) | ||
| 107 | Milliseconds = GetTimeMs() - m_StartTime; | ||
| 108 | else | ||
| 109 | Milliseconds = m_LastTime - m_StartTime; | ||
| 110 | // Seconds | ||
| 111 | u32 Seconds = (u32)(Milliseconds / 1000); | ||
| 112 | // Minutes | ||
| 113 | u32 Minutes = Seconds / 60; | ||
| 114 | // Hours | ||
| 115 | u32 Hours = Minutes / 60; | ||
| 116 | |||
| 117 | std::string TmpStr = StringFromFormat("%02i:%02i:%02i:%03i", | ||
| 118 | Hours, Minutes % 60, Seconds % 60, Milliseconds % 1000); | ||
| 119 | return TmpStr; | ||
| 120 | } | ||
| 121 | |||
| 122 | // Get current time | ||
| 123 | void Timer::IncreaseResolution() | ||
| 124 | { | ||
| 125 | #ifdef _WIN32 | ||
| 126 | timeBeginPeriod(1); | ||
| 127 | #endif | ||
| 128 | } | ||
| 129 | |||
| 130 | void Timer::RestoreResolution() | ||
| 131 | { | ||
| 132 | #ifdef _WIN32 | ||
| 133 | timeEndPeriod(1); | ||
| 134 | #endif | ||
| 135 | } | ||
| 136 | |||
| 137 | // Get the number of seconds since January 1 1970 | ||
| 138 | u64 Timer::GetTimeSinceJan1970() | ||
| 139 | { | ||
| 140 | time_t ltime; | ||
| 141 | time(<ime); | ||
| 142 | return((u64)ltime); | ||
| 143 | } | ||
| 144 | |||
| 145 | u64 Timer::GetLocalTimeSinceJan1970() | ||
| 146 | { | ||
| 147 | time_t sysTime, tzDiff, tzDST; | ||
| 148 | struct tm * gmTime; | ||
| 149 | |||
| 150 | time(&sysTime); | ||
| 151 | |||
| 152 | // Account for DST where needed | ||
| 153 | gmTime = localtime(&sysTime); | ||
| 154 | if(gmTime->tm_isdst == 1) | ||
| 155 | tzDST = 3600; | ||
| 156 | else | ||
| 157 | tzDST = 0; | ||
| 158 | |||
| 159 | // Lazy way to get local time in sec | ||
| 160 | gmTime = gmtime(&sysTime); | ||
| 161 | tzDiff = sysTime - mktime(gmTime); | ||
| 162 | |||
| 163 | return (u64)(sysTime + tzDiff + tzDST); | ||
| 164 | } | ||
| 165 | |||
| 166 | // Return the current time formatted as Minutes:Seconds:Milliseconds | ||
| 167 | // in the form 00:00:000. | ||
| 168 | std::string Timer::GetTimeFormatted() | ||
| 169 | { | ||
| 170 | time_t sysTime; | ||
| 171 | struct tm * gmTime; | ||
| 172 | char formattedTime[13]; | ||
| 173 | char tmp[13]; | ||
| 174 | |||
| 175 | time(&sysTime); | ||
| 176 | gmTime = localtime(&sysTime); | ||
| 177 | |||
| 178 | strftime(tmp, 6, "%M:%S", gmTime); | ||
| 179 | |||
| 180 | // Now tack on the milliseconds | ||
| 181 | #ifdef _WIN32 | ||
| 182 | struct timeb tp; | ||
| 183 | (void)::ftime(&tp); | ||
| 184 | sprintf(formattedTime, "%s:%03i", tmp, tp.millitm); | ||
| 185 | #else | ||
| 186 | struct timeval t; | ||
| 187 | (void)gettimeofday(&t, NULL); | ||
| 188 | sprintf(formattedTime, "%s:%03d", tmp, (int)(t.tv_usec / 1000)); | ||
| 189 | #endif | ||
| 190 | |||
| 191 | return std::string(formattedTime); | ||
| 192 | } | ||
| 193 | |||
| 194 | // Returns a timestamp with decimals for precise time comparisons | ||
| 195 | // ---------------- | ||
| 196 | double Timer::GetDoubleTime() | ||
| 197 | { | ||
| 198 | #ifdef _WIN32 | ||
| 199 | struct timeb tp; | ||
| 200 | (void)::ftime(&tp); | ||
| 201 | #else | ||
| 202 | struct timeval t; | ||
| 203 | (void)gettimeofday(&t, NULL); | ||
| 204 | #endif | ||
| 205 | // Get continuous timestamp | ||
| 206 | u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); | ||
| 207 | |||
| 208 | // Remove a few years. We only really want enough seconds to make | ||
| 209 | // sure that we are detecting actual actions, perhaps 60 seconds is | ||
| 210 | // enough really, but I leave a year of seconds anyway, in case the | ||
| 211 | // user's clock is incorrect or something like that. | ||
| 212 | TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); | ||
| 213 | |||
| 214 | // Make a smaller integer that fits in the double | ||
| 215 | u32 Seconds = (u32)TmpSeconds; | ||
| 216 | #ifdef _WIN32 | ||
| 217 | double ms = tp.millitm / 1000.0 / 1000.0; | ||
| 218 | #else | ||
| 219 | double ms = t.tv_usec / 1000000.0; | ||
| 220 | #endif | ||
| 221 | double TmpTime = Seconds + ms; | ||
| 222 | |||
| 223 | return TmpTime; | ||
| 224 | } | ||
| 225 | |||
| 226 | } // Namespace Common | ||