| 150 | } |
| 151 | |
| 152 | u64 get_timebased_time() { |
| 153 | if (u64 freq = utils::get_tsc_freq()) { |
| 154 | const u64 tsc = rx::get_tsc(); |
| 155 | |
| 156 | #if _MSC_VER |
| 157 | const u64 result = |
| 158 | static_cast<u64>(u128_from_mul(tsc, g_timebase_freq) / freq) * |
| 159 | g_cfg.core.clocks_scale / 100u; |
| 160 | #else |
| 161 | const u64 result = |
| 162 | (tsc / freq * g_timebase_freq + tsc % freq * g_timebase_freq / freq) * |
| 163 | g_cfg.core.clocks_scale / 100u; |
| 164 | #endif |
| 165 | return result - g_timebase_offs; |
| 166 | } |
| 167 | |
| 168 | while (true) { |
| 169 | #ifdef _WIN32 |
| 170 | LARGE_INTEGER count; |
| 171 | ensure(QueryPerformanceCounter(&count)); |
| 172 | |
| 173 | const u64 time = count.QuadPart; |
| 174 | const u64 freq = s_time_aux_info.perf_freq; |
| 175 | |
| 176 | #if _MSC_VER |
| 177 | const u64 result = static_cast<u64>( |
| 178 | u128_from_mul(time * g_cfg.core.clocks_scale, g_timebase_freq) / freq / |
| 179 | 100u); |
| 180 | #else |
| 181 | const u64 result = |
| 182 | (time / freq * g_timebase_freq + time % freq * g_timebase_freq / freq) * |
| 183 | g_cfg.core.clocks_scale / 100u; |
| 184 | #endif |
| 185 | #else |
| 186 | struct timespec ts; |
| 187 | ensure(::clock_gettime(CLOCK_MONOTONIC, &ts) == 0); |
| 188 | |
| 189 | const u64 result = |
| 190 | (static_cast<u64>(ts.tv_sec) * g_timebase_freq + |
| 191 | static_cast<u64>(ts.tv_nsec) * g_timebase_freq / 1000000000ull) * |
| 192 | g_cfg.core.clocks_scale / 100u; |
| 193 | #endif |
| 194 | if (result) |
| 195 | return result - g_timebase_offs; |
| 196 | } |
| 197 | } |
| 198 | |
| 199 | // Add an offset to get_timebased_time to avoid leaking PC's uptime into the |
| 200 | // game As if PS3 starts at value 0 (base time) when the game boots If none-zero |
no test coverage detected