aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
m---------lib/sdl20
m---------lib/sdl_image0
m---------lib/sdl_ttf0
m---------lib/soloud0
-rw-r--r--src/crepe/api/CMakeLists.txt4
-rw-r--r--src/crepe/api/LoopManager.cpp61
-rw-r--r--src/crepe/api/LoopManager.h66
-rw-r--r--src/crepe/api/LoopTimer.cpp59
-rw-r--r--src/crepe/api/LoopTimer.h81
-rw-r--r--src/example/CMakeLists.txt1
-rw-r--r--src/example/gameLoop.cpp8
-rw-r--r--src/makefile5
12 files changed, 284 insertions, 1 deletions
diff --git a/lib/sdl2 b/lib/sdl2
-Subproject 9519b9916cd29a14587af0507292f2bd31dd575
+Subproject c98c4fbff6d8f3016a3ce6685bf8f43433c3efc
diff --git a/lib/sdl_image b/lib/sdl_image
-Subproject abcf63aa71b4e3ac32120fa9870a6500ddcdcc8
+Subproject 56560190a6c5b5740e5afdce747e2a2bfbf16db
diff --git a/lib/sdl_ttf b/lib/sdl_ttf
-Subproject 4a318f8dfaa1bb6f10e0c5e54052e25d3c7f344
+Subproject a3d0895c1b60c41ff9e85d9203ddd7485c014da
diff --git a/lib/soloud b/lib/soloud
-Subproject c8e339fdce5c7107bdb3e64bbf707c8fd3449be
+Subproject e82fd32c1f62183922f08c14c814a02b58db187
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 3b20142..e7894d7 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -16,6 +16,8 @@ target_sources(crepe PUBLIC
Scene.cpp
SceneManager.cpp
Vector2.cpp
+ LoopManager.cpp
+ LoopTimer.cpp
)
target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -38,4 +40,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
Metadata.h
SceneManager.h
SceneManager.hpp
+ LoopManager.h
+ LoopTimer.h
)
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp
new file mode 100644
index 0000000..746e9ce
--- /dev/null
+++ b/src/crepe/api/LoopManager.cpp
@@ -0,0 +1,61 @@
+
+
+#include "../system/RenderSystem.h"
+#include "../system/ScriptSystem.h"
+
+#include "LoopManager.h"
+#include "LoopTimer.h"
+
+namespace crepe {
+
+void LoopManager::process_input() {
+ SDLContext::get_instance().handle_events(this->gameRunning);
+}
+void LoopManager::start(){
+ this->setup();
+ this->loop();
+}
+void LoopManager::set_running(bool running) { this->gameRunning = running; }
+
+void LoopManager::fixed_update() {
+}
+
+void LoopManager::loop() {
+ LoopTimer & timer = LoopTimer::getInstance();
+ timer.start();
+
+ while (gameRunning) {
+ timer.update();
+
+ while (timer.get_lag() >= timer.get_fixed_delta_time()) {
+ process_input();
+ fixed_update();
+ timer.advance_fixed_update();
+ }
+
+ update();
+ render();
+
+ timer.enforce_frame_rate();
+ }
+}
+
+
+void LoopManager::setup() {
+ this->gameRunning = true;
+ LoopTimer::getInstance().start();
+ LoopTimer::getInstance().set_fps(60);
+}
+
+void LoopManager::render() {
+ if (gameRunning) {
+ RenderSystem::get_instance().update();
+ }
+}
+
+void LoopManager::update() {
+ LoopTimer & timer = LoopTimer::getInstance();
+ ScriptSystem::get_instance().update();
+}
+
+} // namespace crepe
diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h
new file mode 100644
index 0000000..a5c88c3
--- /dev/null
+++ b/src/crepe/api/LoopManager.h
@@ -0,0 +1,66 @@
+#pragma once
+
+namespace crepe {
+
+class LoopManager {
+ public:
+ void start();
+
+ private:
+ /**
+ * \brief Setup function for one-time initialization.
+ *
+ * This function initializes necessary components for the game.
+ */
+ void setup();
+ /**
+ * \brief Main game loop function.
+ *
+ * This function runs the main loop, handling game updates and rendering.
+ */
+ void loop();
+
+ /**
+ * \brief Function for handling input-related system calls.
+ *
+ * Processes user inputs from keyboard and mouse.
+ */
+ void process_input();
+
+ /**
+ * \brief Per-frame update.
+ *
+ * Updates the game state based on the elapsed time since the last frame.
+ */
+ void update();
+
+ /**
+ * \brief Late update which is called after update().
+ *
+ * This function can be used for final adjustments before rendering.
+ */
+ void late_update();
+
+ /**
+ * \brief Fixed update executed at a fixed rate.
+ *
+ * This function updates physics and game logic based on LoopTimer's fixed_delta_time.
+ */
+ void fixed_update();
+ /**
+ * \brief Set game running variable
+ *
+ * \param running running (false = game shutdown, true = game running)
+ */
+ void set_running(bool running);
+ /**
+ * \brief Function for executing render-related systems.
+ *
+ * Renders the current state of the game to the screen.
+ */
+ void render();
+
+ bool gameRunning = false;
+ };
+
+} // namespace crepe
diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp
new file mode 100644
index 0000000..5e432fc
--- /dev/null
+++ b/src/crepe/api/LoopTimer.cpp
@@ -0,0 +1,59 @@
+
+#include "../facade/SDLContext.h"
+
+#include "api/LoopTimer.h"
+
+
+using namespace crepe;
+LoopTimer::LoopTimer() {}
+
+LoopTimer & LoopTimer::getInstance() {
+ static LoopTimer instance;
+ return instance;
+}
+
+void LoopTimer::start() {
+ last_frame_time = SDLContext::get_instance().get_ticks();
+ elapsed_time = 0;
+ elapsed_fixed_time = 0;
+ delta_time = 0;
+}
+
+void LoopTimer::update() {
+ uint64_t current_frame_time = SDLContext::get_instance().get_ticks();
+ delta_time = (current_frame_time - last_frame_time) / 1000.0;
+
+ if (delta_time > maximum_delta_time) {
+ delta_time = maximum_delta_time;
+ }
+ delta_time = game_scale;
+ elapsed_time += delta_time;
+ last_frame_time = current_frame_time;
+}
+
+double LoopTimer::get_delta_time() const { return delta_time; }
+int LoopTimer::get_current_time() const { return elapsed_time; }
+
+void LoopTimer::advance_fixed_update() { elapsed_fixed_time += fixed_delta_time; }
+
+double LoopTimer::get_fixed_delta_time() const { return fixed_delta_time; }
+
+void LoopTimer::set_fps(int fps) {
+ this->fps = fps;
+ frame_target_time = 1.0 / fps;
+}
+
+int LoopTimer::get_fps() const { return fps; }
+void LoopTimer::set_game_scale(double value) { game_scale = value; };
+double LoopTimer::get_game_scale() const { return game_scale; }
+void LoopTimer::enforce_frame_rate() {
+ uint64_t current_frame_time = SDLContext::get_instance().get_ticks();
+ double frame_duration = (current_frame_time - last_frame_time) / 1000.0;
+
+ if (frame_duration < frame_target_time) {
+ uint32_t delay_time
+ = (uint32_t) ((frame_target_time - frame_duration) / 1000.0);
+ SDLContext::get_instance().delay(delay_time);
+ }
+}
+double LoopTimer::get_lag() const { return elapsed_time - elapsed_fixed_time; }
diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h
new file mode 100644
index 0000000..584a408
--- /dev/null
+++ b/src/crepe/api/LoopTimer.h
@@ -0,0 +1,81 @@
+#pragma once
+
+#include <cstdint>
+
+namespace crepe{
+class LoopTimer {
+public:
+/**
+ * \brief Get the singleton instance of LoopTimer.
+ *
+ * \return A reference to the LoopTimer instance.
+ */
+static LoopTimer& getInstance();
+
+/**
+ * \brief Get the current delta time for the current frame.
+ *
+ * \return Delta time in seconds since the last frame.
+ */
+double get_delta_time() const;
+
+/**
+ * \brief Get the current game time.
+ *
+ * \note The current game time may vary from the real-world elapsed time.
+ * It is the cumulative sum of each frame's delta time.
+ *
+ * \return Elapsed game time in milliseconds.
+ */
+int get_current_time() const;
+
+/**
+ * \brief Set the target frames per second (FPS).
+ *
+ * \param fps The number of frames that should be rendered per second.
+ */
+void set_fps(int fps);
+
+/**
+ * \brief Get the current frames per second (FPS).
+ *
+ * \return Current FPS.
+ */
+int get_fps() const;
+
+/**
+ * \brief Get the current game scale.
+ *
+ * \return The current game scale, where 0 = paused, 1 = normal speed, and values > 1 speed up the game.
+ */
+double get_game_scale() const;
+
+/**
+ * \brief Set the game scale.
+ *
+ * \param game_scale The desired game scale (0 = pause, 1 = normal speed, > 1 = speed up).
+ */
+void set_game_scale(double game_scale);
+
+private:
+friend class LoopManager;
+void start();
+void enforce_frame_rate();
+double get_fixed_delta_time() const;
+double get_lag() const;
+LoopTimer();
+void update();
+void advance_fixed_update();
+private:
+int fps = 50; ///< Current frames per second
+double game_scale = 1; ///< Current game scale
+double maximum_delta_time = 0.25; ///< Maximum delta time to avoid large jumps
+double delta_time = 0; ///< Delta time for the current frame
+double frame_target_time = 1.0 / fps; ///< Target time per frame in seconds
+double fixed_delta_time = 0.02; ///< Fixed delta time for fixed updates
+double elapsed_time = 0; ///< Total elapsed game time
+double elapsed_fixed_time = 0; ///< Total elapsed time for fixed updates
+uint64_t last_frame_time = 0; ///< Time of the last frame
+};
+
+} // namespace crepe::api
diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt
index 36f9d4d..751b556 100644
--- a/src/example/CMakeLists.txt
+++ b/src/example/CMakeLists.txt
@@ -28,4 +28,5 @@ add_example(proxy)
add_example(db)
add_example(ecs)
add_example(scene_manager)
+add_example(gameLoop)
diff --git a/src/example/gameLoop.cpp b/src/example/gameLoop.cpp
new file mode 100644
index 0000000..f3edbdb
--- /dev/null
+++ b/src/example/gameLoop.cpp
@@ -0,0 +1,8 @@
+#include "crepe/api/LoopManager.h"
+using namespace crepe;
+
+int main(){
+ LoopManager loop;
+ loop.start();
+ return 1;
+}
diff --git a/src/makefile b/src/makefile
index b9c44c8..5e525e8 100644
--- a/src/makefile
+++ b/src/makefile
@@ -94,7 +94,10 @@ LOEK += example/script.cpp
LOEK += test/audio.cpp
LOEK += test/dummy.cpp
JARO += test/PhysicsTest.cpp
-
+WOUTER += crepe/api/LoopManager.cpp
+WOUTER += crepe/api/LoopManager.h
+WOUTER += crepe/api/LoopTimer.cpp
+WOUTER += crepe/api/LoopTimer.h
FMT := $(JARO) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
format: FORCE
clang-tidy -p build/compile_commands.json --fix-errors $(FMT)