diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/crepe/api/LoopManager.cpp | 61 | ||||
| -rw-r--r-- | src/crepe/api/LoopManager.h | 66 | ||||
| -rw-r--r-- | src/crepe/api/LoopTimer.cpp | 59 | ||||
| -rw-r--r-- | src/crepe/api/LoopTimer.h | 81 | ||||
| -rw-r--r-- | src/example/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/example/gameLoop.cpp | 8 | ||||
| -rw-r--r-- | src/makefile | 5 | 
8 files changed, 284 insertions, 1 deletions
| 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) |