diff options
Diffstat (limited to 'src/game.cpp')
| -rw-r--r-- | src/game.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/game.cpp b/src/game.cpp index dd038ad..74f2220 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -20,6 +20,7 @@ #include <cstring> #include <iomanip> #include <ostream> +#include <thread> const uint64_t consoleBufferCount = 30; const uint64_t consoleLineLength = 128; @@ -1114,6 +1115,117 @@ void RecordImGuiEditor() { } } +void Game_Main(PKEWindowProperties *windowProps) { + fprintf(stdout, "Game_Main Entering\n"); + try { + AM_Init(); + Physics_Init(); + Game_Init(); + ECS_Init(); + CreateWindow(windowProps); + PkeInput_Init(); + EntityType_Init(); + + GameTimePoint lastTimePoint = pkeSettings.steadyClock.now(); + double deltaTillNextRender = pkeSettings.deltaPerFrame; + GameTimePoint lastLogTimePoint = pkeSettings.steadyClock.now(); + int64_t tickCount = 0; + int64_t renderCount = 0; + + int64_t nsAhead = 0.0; + + while (pkeSettings.isGameRunning) { + + glfwPollEvents(); + + int64_t nsAheadHolder = 0.0; + if (nsAhead > 0) { + nsAheadHolder = nsAhead; + std::this_thread::sleep_for(GameTimeDuration(nsAhead)); + nsAhead = 0; + } + if (vidMode.refreshRate != pkeSettings.targetFPS) { + pkeSettings.targetFPS = vidMode.refreshRate; + pkeSettings.deltaPerFrame = 1 / double(pkeSettings.targetFPS); + } + + GameTimePoint currentTimePoint = pkeSettings.steadyClock.now(); + double deltaThisTick = ((currentTimePoint - lastTimePoint).count() - nsAheadHolder) / NANO_DENOM_DOUBLE; + deltaThisTick = std::min(deltaThisTick, pkeSettings.minimumDeltaPerFrame); + lastTimePoint = currentTimePoint; + + deltaTillNextRender -= deltaThisTick; + bool shouldRender = pkeSettings.graphicsSettings.isFramerateUnlocked + || pkeSettings.graphicsSettings.isWaitingForVsync + || deltaTillNextRender <= 0.0; + + if (shouldRender == false && (deltaTillNextRender > 0.0 && deltaTillNextRender - (deltaThisTick * 2.0) <= 0.0)) { + /* + * We are ahead of the render schedule + * && the current tick's speed would put us behind schedule next tick. + * Simulate the extra time we are ahead and prepare to sleep the difference + * before the next tick. + */ + nsAhead = std::floor(deltaTillNextRender * NANO_DENOM_DOUBLE); + deltaThisTick += deltaTillNextRender; + shouldRender = true; + } + + tickCount += 1; + Game_Tick(deltaThisTick); + + if (shouldRender) { + Render(); + renderCount += 1; + double msBehind = deltaTillNextRender * -1000; + int64_t behindCount = 0; + while (deltaTillNextRender < pkeSettings.deltaPerFrame) { + behindCount += 1; + deltaTillNextRender += pkeSettings.deltaPerFrame; + } + if (behindCount > 2) { + fprintf(stderr, "[PKE::main] late render - simulated ahead: %fms - delta behind: %fms - missed frames:%ld\n", nsAheadHolder / (NANO_DENOM_DOUBLE / 1000), msBehind, behindCount - 1); + fflush(stderr); + } + } + + if ((currentTimePoint - lastLogTimePoint).count() > std::chrono::nanoseconds::period::den) { + lastLogTimePoint = currentTimePoint; + fprintf(stdout, "TPS: ~%ld - actual:%ld - presents:%ld\n", int64_t(1 / deltaThisTick), tickCount, renderCount); + fflush(stdout); + tickCount = 0; + renderCount = 0; + } + + pkeSettings.isGameRunning = !glfwWindowShouldClose(window); + } + + vkDeviceWaitIdle(vkDevice); + + } catch (const std::exception &exc) { + fprintf(stdout, "Game_Main EXCEPTION: %s\n", exc.what()); + } catch (const char *err) { + fprintf(stdout, "Game_Main UNHANDLED EXCEPTION: %s\n", err); + } catch (...) { + fprintf(stdout, "Game_Main UNHANDLED EXCEPTION\n"); + } + fprintf(stdout, "Game_Main SHUTDOWN INITIATED\n"); +#ifndef NDEBUG + Pke_DebugPrint(); +#endif + Game_Teardown(); + Event_Teardown(); + EntityType_Teardown(); + PkeInput_Teardown(); + Physics_Teardown(); + ECS_Teardown(); + AM_DebugPrint(); + AM_Teardown(); + DestroyWindow(); + Pke_DebugPrint(); + fprintf(stdout, "Game_Main Exiting\n"); +} + void Game_Init() { pkeSettings.mem.bkt = Pke_BeginTransientBucket(1UL << 26); |
