Lua: Don't lua_error() out of context with pending dtors
[lsnes.git] / src / video / avi / timer.cpp
blobeec0be3886e0cd9bf7c348fe7583e994cc10dc74
1 #include "video/avi/timer.hpp"
2 #include "library/minmax.hpp"
4 timer::timer(uint32_t rate_n, uint32_t rate_d)
6 w = n = 0;
7 set_step(rate_n, rate_d);
10 void timer::rate(uint32_t rate_n, uint32_t rate_d)
12 double old_d = d;
13 uint64_t old_d2 = d;
14 set_step(rate_n, rate_d);
15 //Adjust n.
16 if(d == old_d2)
17 return;
18 n = n * (d / old_d) + 0.5;
19 w += (n / d);
20 n %= d;
23 // The highest value rate_n can safely have: 9,223,372,036,854,775,808
24 // The highest value rate_d can safely have: 18,446,744,073
25 void timer::set_step(uint32_t rate_n, uint32_t rate_d)
27 uint64_t maxnscl = 9223372036854775808ULL / rate_n;
28 uint64_t maxdscl = 18446744073ULL / rate_d;
29 uint64_t maxscl = min(maxnscl, maxdscl);
30 uint64_t _rate_n = maxscl * rate_n;
31 uint64_t _rate_d = maxscl * rate_d;
32 d = _rate_n;
33 sw = 1000000000ULL * _rate_d / _rate_n;
34 sn = 1000000000ULL * _rate_d % _rate_n;
37 uint64_t timer::read_next()
39 uint64_t tmp_w = w + sw;
40 uint64_t tmp_n = n + sn;
41 tmp_w += (tmp_n / d);
42 tmp_n %= d;
43 return tmp_w;
46 void timer::reset()
48 w = n = 0;