[WASAPI] set stream audio category
[xbmc.git] / xbmc / cores / RetroPlayer / playback / GameLoop.cpp
blob1abf258ce74534db9fc563160c90b239729c7f22
1 /*
2 * Copyright (C) 2016-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "GameLoop.h"
11 #include <chrono>
12 #include <cmath>
14 using namespace KODI;
15 using namespace RETRO;
16 using namespace std::chrono_literals;
18 #define DEFAULT_FPS 60 // In case fps is 0 (shouldn't happen)
19 #define FOREVER_MS (7 * 24 * 60 * 60 * 1000) // 1 week is large enough
21 CGameLoop::CGameLoop(IGameLoopCallback* callback, double fps)
22 : CThread("GameLoop"), m_callback(callback), m_fps(fps ? fps : DEFAULT_FPS), m_speedFactor(0.0)
26 CGameLoop::~CGameLoop()
28 Stop();
31 void CGameLoop::Start()
33 Create();
36 void CGameLoop::Stop()
38 StopThread(false);
39 m_sleepEvent.Set();
40 StopThread(true);
43 void CGameLoop::SetSpeed(double speedFactor)
45 m_speedFactor = speedFactor;
47 m_sleepEvent.Set();
50 void CGameLoop::PauseAsync()
52 SetSpeed(0.0);
55 void CGameLoop::Process(void)
57 while (!m_bStop)
59 if (m_speedFactor == 0.0)
61 m_lastFrameMs = 0.0;
62 m_sleepEvent.Wait(5000ms);
64 else
66 if (m_speedFactor > 0.0)
67 m_callback->FrameEvent();
68 else if (m_speedFactor < 0.0)
69 m_callback->RewindEvent();
71 if (m_lastFrameMs > 0.0)
73 m_lastFrameMs += FrameTimeMs();
74 m_adjustTime = m_lastFrameMs - NowMs();
76 else
78 m_lastFrameMs = NowMs();
79 m_adjustTime = 0.0;
82 // Calculate sleep time
83 double sleepTimeMs = SleepTimeMs();
85 // Sleep at least 1 ms to avoid sleeping forever
86 while (sleepTimeMs > 1.0)
88 m_sleepEvent.Wait(std::chrono::milliseconds(static_cast<unsigned int>(sleepTimeMs)));
90 if (m_bStop)
91 break;
93 // Speed may have changed, update sleep time
94 sleepTimeMs = SleepTimeMs();
100 double CGameLoop::FrameTimeMs() const
102 if (m_speedFactor != 0.0)
103 return 1000.0 / m_fps / std::abs(m_speedFactor);
104 else
105 return 1000.0 / m_fps / 1.0;
108 double CGameLoop::SleepTimeMs() const
110 // Calculate next frame time
111 const double nextFrameMs = m_lastFrameMs + FrameTimeMs();
113 // Calculate sleep time
114 double sleepTimeMs = (nextFrameMs - NowMs()) + m_adjustTime;
116 // Reset adjust time
117 m_adjustTime = 0.0;
119 // Positive or zero
120 sleepTimeMs = (sleepTimeMs >= 0.0 ? sleepTimeMs : 0.0);
122 return sleepTimeMs;
125 double CGameLoop::NowMs() const
127 return std::chrono::duration<double, std::milli>(
128 std::chrono::steady_clock::now().time_since_epoch())
129 .count();