Timer.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /******************************************************************************
  2. Flt Error for big values, obtained using the formula:
  3. Dbl sec=1, min=60*sec, hour=60*min, day=hour*24, month=day*30, year=month*12;
  4. Flt t=.., t1=t; IncRealByBit(t1); Flt dt=t1-t;
  5. 1 day : 0.0078125s
  6. 1 month: 0.25s
  7. 1 year : 2.0s
  8. 2 years: 4.0s
  9. 4 years: 8.0s
  10. 8 years: 16.0s
  11. /******************************************************************************
  12. Slow to Fast (1000000 calls)
  13. -clock (0.036s)
  14. -timeGetTime (0.018s)
  15. -GetTickCount (0.004s)
  16. -GetTickCount64 (0.004s)
  17. Precision:
  18. -clock ( 1ms)
  19. -timeGetTime ( 1ms)
  20. -GetTickCount (16ms)
  21. -GetTickCount64 (16ms)
  22. Measured with:
  23. Dbl t0[]={Time.curTime(), clock(), timeGetTime(), GetTickCount(), GetTickCount64()};
  24. REP(1000)
  25. {
  26. Dbl t1[]={Time.curTime(), clock(), timeGetTime(), GetTickCount(), GetTickCount64()};
  27. Dbl td[]={(t1[0]-t0[0])*1000, t1[1]-t0[1], t1[2]-t0[2], t1[3]-t0[3], t1[4]-t0[4]};
  28. LogName(S);
  29. LogConsole();
  30. LogN(S+td[0]+' '+td[1]+' '+td[2]+' '+td[3]+' '+td[4]);
  31. Copy(t0, t1);
  32. }
  33. /******************************************************************************/
  34. #include "stdafx.h"
  35. namespace EE{
  36. /******************************************************************************/
  37. TimeClass Time;
  38. /******************************************************************************/
  39. // TIME
  40. /******************************************************************************/
  41. TimeClass::TimeClass()
  42. {
  43. _pc=false;
  44. _skip=0;
  45. _start_time_ms=_frame=_frames_drawn=0;
  46. _start_time=0;
  47. _fps=_fps_time=_state_update=_state_draw=0;
  48. _rd_2=_rd_1=_rd=_ad=_d=_rt=_at=_st=_t=0;
  49. _time_mul=0;
  50. _speed=1;
  51. }
  52. /******************************************************************************/
  53. Dbl TimeClass::curTime()C
  54. {
  55. #if WINDOWS
  56. if(_pc)
  57. {
  58. LARGE_INTEGER pc; QueryPerformanceCounter(&pc);
  59. return (pc.QuadPart-_start_time)*_time_mul;
  60. }
  61. #if WINDOWS_OLD
  62. return (timeGetTime()-_start_time_ms)*_time_mul;
  63. #elif WINDOWS_NEW
  64. return (clock()-_start_time_ms)*_time_mul;
  65. #endif
  66. #elif APPLE
  67. return (mach_absolute_time()-_start_time)*_time_mul;
  68. #elif LINUX || ANDROID
  69. struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time);
  70. return (ULong(time.tv_sec)*1000000000+time.tv_nsec-_start_time)/1000000000.;
  71. #elif WEB
  72. return (emscripten_get_now()-_start_time)/1000;
  73. #endif
  74. }
  75. UInt TimeClass::curTimeMs()C
  76. {
  77. #if WINDOWS_OLD
  78. return timeGetTime()-_start_time_ms;
  79. #elif WINDOWS_NEW
  80. return clock()-_start_time_ms; ASSERT(CLOCKS_PER_SEC==1000);
  81. #elif APPLE
  82. return TruncU((mach_absolute_time()-_start_time)*_time_mul*1000);
  83. #elif LINUX || ANDROID
  84. struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time);
  85. return TruncU((ULong(time.tv_sec)*1000000000+time.tv_nsec-_start_time)*(1000/1000000000.));
  86. #elif WEB
  87. return TruncU(emscripten_get_now()-_start_time);
  88. #endif
  89. }
  90. /******************************************************************************/
  91. void TimeClass::speed(Flt speed)
  92. {
  93. if(T._speed!=speed)
  94. {
  95. T._speed=speed;
  96. SpeedSound();
  97. }
  98. }
  99. /******************************************************************************/
  100. void TimeClass::skipUpdate(Byte frames ) {MAX(_skip, frames);}
  101. void TimeClass::wait (Int milliseconds)
  102. {
  103. if(milliseconds>0)
  104. {
  105. #if WINDOWS
  106. Sleep(milliseconds);
  107. #else
  108. usleep(milliseconds*1000);
  109. #endif
  110. }
  111. }
  112. /******************************************************************************/
  113. void (*SteamSetTime)(); // have to use variable so we don't call 'Steam' manually (because that would force require DLL), but rather Steam methods set this pointer
  114. void TimeClass::create()
  115. {
  116. if(LogInit)LogN("TimeClass.create");
  117. #if WINDOWS
  118. LARGE_INTEGER value;
  119. if(_pc=(QueryPerformanceFrequency(&value)!=0))
  120. {
  121. _time_mul=1.0/value.QuadPart; // ticks per second
  122. QueryPerformanceCounter(&value); _start_time=value.QuadPart;
  123. }else
  124. {
  125. _time_mul=1.0/1000;
  126. }
  127. #if WINDOWS_OLD
  128. _start_time_ms=timeGetTime();
  129. #elif WINDOWS_NEW
  130. _start_time_ms=clock();
  131. #endif
  132. #elif APPLE
  133. mach_timebase_info_data_t info;
  134. mach_timebase_info(&info);
  135. _time_mul =info.numer/1000000000./info.denom; // use info and convert from nanoseconds to seconds
  136. _start_time=mach_absolute_time();
  137. #elif LINUX || ANDROID
  138. struct timespec time; clock_gettime(CLOCK_MONOTONIC, &time);
  139. _start_time=ULong(time.tv_sec)*1000000000+time.tv_nsec;
  140. #elif WEB
  141. _start_time=TruncUL(emscripten_get_now());
  142. #endif
  143. if(SteamSetTime)SteamSetTime();
  144. }
  145. /******************************************************************************/
  146. void TimeClass::update()
  147. {
  148. // this is no longer needed after adding 'new_rd' test below: if(!_rt)skipUpdate(); // if it's the first time we're updating the timer, then skip setting time delta's (if we won't do this, then the time delta would be equal to loading the whole application, which can take sometimes few seconds, that's too much for frame time delta)
  149. Dbl cur_time=curTime(), new_rd=cur_time-_rt;
  150. // detect slow downs
  151. if(!_skip && new_rd>_rd*3) // if new delta is 3x bigger than old one, then most probably there's some system slow down or app loaded something, so skip update, it's important to check this on RD and then set it either way, because if we would be checking D or AD then skipping could go on and on (for example if we've just entered more complex level, and rendering takes now longer in each frame, then all subsequent frames would have delta much bigger than originally, and it would never stop skipping, however with RD we're just checking first frame of sudden drop, which then all next frames will be processed normally without skipping)
  152. if(D.sync() ? new_rd>(Abs(_rd-_rd_1)+Abs(_rd_1-_rd_2)+Abs(_rd-_rd_2))*5 : true) // when sync is enabled check also the deviations between frame deltas, because sometimes rendering can be jerky (1st frame is 15ms, 2nd frame is 2ms and 3rd is 48ms and so on) so by checking the amount of deviations we're preventing slow downs because of jerky rendering
  153. _skip=true;
  154. _rt=cur_time; _rd_2=_rd_1; _rd_1=_rd; _rd=new_rd; // set new values
  155. if(_skip)_skip--;else _ad=_sv_ad.update(_rd);
  156. _d =_ad*_speed;
  157. _at+=_ad;
  158. _st+=_ad;
  159. _t+= _d;
  160. _frame++;
  161. _frames_drawn++; if((_fps_time+=_rd)>=1)
  162. {
  163. _fps =_frames_drawn/_fps_time;
  164. _fps_time =0;
  165. _frames_drawn=0;
  166. }
  167. }
  168. /******************************************************************************/
  169. // MAIN
  170. /******************************************************************************/
  171. Bool EventOccurred(Flt event_time, Flt start_time, Flt dt)
  172. {
  173. return start_time<=event_time && start_time+dt>event_time;
  174. }
  175. Bool EventBetween(Flt event_time_from, Flt event_time_to, Flt start_time, Flt dt)
  176. {
  177. return start_time<=event_time_to && start_time+dt>=event_time_from;
  178. }
  179. /******************************************************************************/
  180. }
  181. /******************************************************************************/