diff options
| -rw-r--r-- | src/game.hpp | 6 | ||||
| -rw-r--r-- | src/main.cpp | 61 |
2 files changed, 66 insertions, 1 deletions
diff --git a/src/game.hpp b/src/game.hpp index 80c971f..4ab021b 100644 --- a/src/game.hpp +++ b/src/game.hpp @@ -6,13 +6,17 @@ using GameTimeDuration = std::chrono::duration<int64_t, std::nano>; using GameTimePoint = std::chrono::steady_clock::time_point; +#define NANO_DENOM std::chrono::nanoseconds::period::den +#define NANO_DENOM_DOUBLE double(std::chrono::nanoseconds::period::den) struct GameSettings { bool isGameRunning = true; bool isGamePaused = false; bool isFramerateUnlocked = true; int64_t targetFPS = 144; - GameTimeDuration nanosecondsPerFrame = GameTimeDuration(std::chrono::nanoseconds::period::den / targetFPS); + int64_t minFPS = 20; + double deltaPerFrame = 1 / double(targetFPS); + double minimumDeltaPerFrame = 1 / double(minFPS); }; extern GameSettings pkeSettings; diff --git a/src/main.cpp b/src/main.cpp index be70826..b1c33aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,17 +1,78 @@ +#include <chrono> #include <cstdio> +#include <cmath> #include <exception> +#include <thread> #include "asset-manager.hpp" +#include "game.hpp" #include "window.hpp" PKEWindowProperties windowProps{}; +void Tick(double delta) { + /* no-op */ +} + int main() { printf("PKE ENTERING\n"); try { AssetManagerInit(); CreateWindow(&windowProps); + + auto steadyClock = std::chrono::steady_clock(); + GameTimePoint lastTimePoint = steadyClock.now(); + double deltaTillNextRender = pkeSettings.deltaPerFrame; + GameTimePoint lastLogTimePoint = steadyClock.now(); + int64_t tickCount = 0; + + int64_t nsAhead = 0.0; + + while (pkeSettings.isGameRunning) { + + if (nsAhead > 0) { + std::this_thread::sleep_until(lastTimePoint + GameTimeDuration(nsAhead + 1)); + nsAhead = 0; + } + + GameTimePoint currentTimePoint = steadyClock.now(); + double deltaThisTick = (currentTimePoint - lastTimePoint).count() / NANO_DENOM_DOUBLE; + deltaThisTick = std::min(deltaThisTick, pkeSettings.minimumDeltaPerFrame); + deltaTillNextRender -= deltaThisTick; + bool shouldRender = deltaTillNextRender < deltaThisTick; + lastTimePoint = currentTimePoint; + + if (shouldRender) { + if (deltaTillNextRender > 0.0 && deltaThisTick < pkeSettings.deltaPerFrame) { + /* + * We are ahead of schedule && the current tick is faster than our target FPS. + * Simulate the extra time we are ahead and prepare to sleep the difference + * before the next tick. + */ + nsAhead = std::ceil(deltaTillNextRender * NANO_DENOM_DOUBLE); + deltaThisTick += deltaTillNextRender; + } + deltaTillNextRender += pkeSettings.deltaPerFrame; + } + + tickCount += 1; + Tick(deltaThisTick); + + if (shouldRender) { + PreRender(); + Render(); + PostRender(); + } + + if (shouldRender == false && (currentTimePoint - lastLogTimePoint).count() > std::chrono::nanoseconds::period::den) { + lastLogTimePoint = currentTimePoint; + printf("TPS: ~%ld - actual:%ld\n", int64_t(1 / deltaThisTick), tickCount); + tickCount = 0; + } + + } + } catch (const std::exception &exc) { printf("EXCEPTION: %s\n", exc.what()); } catch (...) { |
