summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2023-11-28 14:42:02 -0500
committerJonathan Bradley <jcb@pikum.xyz>2023-11-28 14:42:02 -0500
commit6d9bea3e71137a94ba64fd0b5661d341304b2dc1 (patch)
treee7b67115a7b5cb6358dc961e63d5e16be20cd99d
parent662e13106e2f726e47d09dc66c01d9449eceb623 (diff)
refactor core game loop out of main.cpp and into game.cpp
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/game.cpp112
-rw-r--r--src/game.hpp3
-rw-r--r--src/main.cpp125
-rw-r--r--src/window-types.hpp9
-rw-r--r--src/window.cpp1
-rw-r--r--src/window.hpp6
7 files changed, 130 insertions, 127 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index eb275ea..cf7d3e3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -54,6 +54,7 @@ set(PKE_SOURCE_FILES
src/vendor/stb_image_include.cpp
src/window.hpp
src/window.cpp
+ src/window-types.hpp
)
include(FetchContent)
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);
diff --git a/src/game.hpp b/src/game.hpp
index a449ed4..d28bc9c 100644
--- a/src/game.hpp
+++ b/src/game.hpp
@@ -1,6 +1,9 @@
#ifndef PKE_GAME_HPP
#define PKE_GAME_HPP
+#include "window-types.hpp"
+
+void Game_Main(PKEWindowProperties *windowProps);
void Game_Init();
void Game_Tick(double delta);
void Game_Teardown();
diff --git a/src/main.cpp b/src/main.cpp
index 045fdfe..0d4ef9f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,20 +1,8 @@
-
-#include <chrono>
-#include <cstdio>
-#include <cmath>
-#include <exception>
-#include <thread>
#include <csignal>
-#include "physics.hpp"
-#include "player-input.hpp"
-#include "asset-manager.hpp"
-#include "ecs.hpp"
-#include "entities.hpp"
-#include "game-settings.hpp"
-#include "game-type-defs.hpp"
#include "game.hpp"
-#include "window.hpp"
+#include "game-settings.hpp"
+#include "window-types.hpp"
void signal_handler(int signal_num) {
fprintf(stdout, "Received signal: %d - shutting down\n", signal_num);
@@ -23,117 +11,10 @@ void signal_handler(int signal_num) {
PKEWindowProperties windowProps{};
-void Tick(double delta) {
- Game_Tick(delta);
-}
-
int main() {
signal(SIGTERM, signal_handler);
-
fprintf(stdout, "PKE 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;
- 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, "EXCEPTION: %s\n", exc.what());
- } catch (const char *err) {
- fprintf(stdout, "UNHANDLED EXCEPTION: %s\n", err);
- } catch (...) {
- fprintf(stdout, "UNHANDLED EXCEPTION\n");
- }
- fprintf(stdout, "PKE SHUTDOWN INITIATED\n");
- Game_Teardown();
- Event_Teardown();
- EntityType_Teardown();
- PkeInput_Teardown();
- Physics_Teardown();
- ECS_Teardown();
- AM_DebugPrint();
- AM_Teardown();
- DestroyWindow();
- Pke_DebugPrint();
+ Game_Main(&windowProps);
fprintf(stdout, "PKE EXITING\n");
return 0;
}
diff --git a/src/window-types.hpp b/src/window-types.hpp
new file mode 100644
index 0000000..3b6a19d
--- /dev/null
+++ b/src/window-types.hpp
@@ -0,0 +1,9 @@
+#ifndef PKE_WINDOW_TYPES_HPP
+#define PKE_WINDOW_TYPES_HPP
+
+struct PKEWindowProperties {
+ unsigned int width = 1280;
+ unsigned int height = 720;
+};
+
+#endif /* PKE_WINDOW_TYPES_HPP */
diff --git a/src/window.cpp b/src/window.cpp
index 3fdc425..0827da5 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -11,6 +11,7 @@
#include "memory.hpp"
#include "static/cube.hpp"
#include "window.hpp"
+#include "window-types.hpp"
#include "glm/ext/matrix_transform.hpp"
#include "glm/gtc/matrix_transform.hpp"
diff --git a/src/window.hpp b/src/window.hpp
index 83f7e68..0194a18 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -8,6 +8,7 @@
#include "imgui.h"
#include "memory.hpp"
#include "ecs.hpp"
+#include "window-types.hpp"
#include "glm/mat4x4.hpp"
#include <cstring>
@@ -46,11 +47,6 @@ extern VkRenderPass presentRenderPass;
extern VkRenderPass renderRenderPass;
extern VkSampleCountFlagBits renderSampleCount;
-struct PKEWindowProperties {
- unsigned int width = 1280;
- unsigned int height = 720;
-};
-
struct UniformBufferObject {
glm::mat4 model;
glm::mat4 view;