Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
  3.  * It is copyright by its individual contributors, as recorded in the
  4.  * project's Git history.  See COPYING.txt at the top level for license
  5.  * terms and a link to the Git history.
  6.  */
  7. /*
  8.  *
  9.  * SDL library timer functions
  10.  *
  11.  */
  12.  
  13. #include <SDL.h>
  14.  
  15. #include "maths.h"
  16. #include "timer.h"
  17. #include "config.h"
  18. #include "multi.h"
  19.  
  20. namespace dcx {
  21.  
  22. static fix64 F64_RunTime = 0;
  23.  
  24. fix64 timer_update()
  25. {
  26.         static bool already_initialized;
  27.         static fix64 last_tv;
  28.         const fix64 cur_tv = static_cast<fix64>(SDL_GetTicks()) * F1_0 / 1000;
  29.         const fix64 prev_tv = last_tv;
  30.         fix64 runtime = F64_RunTime;
  31.         last_tv = cur_tv;
  32.         if (unlikely(!already_initialized))
  33.         {
  34.                 already_initialized = true;
  35.         }
  36.         else if (likely(prev_tv < cur_tv)) // in case SDL_GetTicks wraps, don't update and have a little hickup
  37.                 F64_RunTime = (runtime += (cur_tv - prev_tv)); // increment! this value will overflow long after we are all dead... so why bother checking?
  38.         return runtime;
  39. }
  40.  
  41. fix64 timer_query(void)
  42. {
  43.         return (F64_RunTime);
  44. }
  45.  
  46. void timer_delay_ms(unsigned milliseconds)
  47. {
  48.         SDL_Delay(milliseconds);
  49. }
  50.  
  51. // Replacement for timer_delay which considers calc time the program needs between frames (not reentrant)
  52. void timer_delay_bound(const unsigned caller_bound)
  53. {
  54.         static uint32_t FrameStart;
  55.  
  56.         uint32_t start = FrameStart;
  57.         const auto multiplayer = Game_mode & GM_MULTI;
  58.         const auto vsync = CGameCfg.VSync;
  59.         const auto bound = vsync ? 1000u / MAXIMUM_FPS : caller_bound;
  60.         for (;;)
  61.         {
  62.                 const uint32_t tv_now = SDL_GetTicks();
  63.                 if (multiplayer)
  64.                         multi_do_frame(); // during long wait, keep packets flowing
  65.                 if (!vsync)
  66.                         SDL_Delay(1);
  67.                 if (unlikely(start > tv_now))
  68.                         start = tv_now;
  69.                 if (unlikely(tv_now - start >= bound))
  70.                 {
  71.                         FrameStart = tv_now;
  72.                         break;
  73.                 }
  74.         }
  75. }
  76.  
  77. }
  78.