From d3ed3f4daa335bb881dbcf55aa425c602ddbd2f4 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 9 Nov 2024 12:58:26 +0100 Subject: changed variables --- lib/sdl2 | 2 +- lib/sdl_image | 2 +- lib/sdl_ttf | 2 +- lib/soloud | 2 +- src/crepe/api/CMakeLists.txt | 4 +++ src/crepe/api/LoopManager.cpp | 61 ++++++++++++++++++++++++++++++++ src/crepe/api/LoopManager.h | 66 +++++++++++++++++++++++++++++++++++ src/crepe/api/LoopTimer.cpp | 59 +++++++++++++++++++++++++++++++ src/crepe/api/LoopTimer.h | 81 +++++++++++++++++++++++++++++++++++++++++++ src/example/CMakeLists.txt | 1 + src/example/gameLoop.cpp | 8 +++++ src/makefile | 5 ++- 12 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 src/crepe/api/LoopManager.cpp create mode 100644 src/crepe/api/LoopManager.h create mode 100644 src/crepe/api/LoopTimer.cpp create mode 100644 src/crepe/api/LoopTimer.h create mode 100644 src/example/gameLoop.cpp diff --git a/lib/sdl2 b/lib/sdl2 index 9519b99..c98c4fb 160000 --- a/lib/sdl2 +++ b/lib/sdl2 @@ -1 +1 @@ -Subproject commit 9519b9916cd29a14587af0507292f2bd31dd5752 +Subproject commit c98c4fbff6d8f3016a3ce6685bf8f43433c3efcc diff --git a/lib/sdl_image b/lib/sdl_image index abcf63a..5656019 160000 --- a/lib/sdl_image +++ b/lib/sdl_image @@ -1 +1 @@ -Subproject commit abcf63aa71b4e3ac32120fa9870a6500ddcdcc89 +Subproject commit 56560190a6c5b5740e5afdce747e2a2bfbf16db1 diff --git a/lib/sdl_ttf b/lib/sdl_ttf index 4a318f8..a3d0895 160000 --- a/lib/sdl_ttf +++ b/lib/sdl_ttf @@ -1 +1 @@ -Subproject commit 4a318f8dfaa1bb6f10e0c5e54052e25d3c7f3440 +Subproject commit a3d0895c1b60c41ff9e85d9203ddd7485c014dae diff --git a/lib/soloud b/lib/soloud index c8e339f..e82fd32 160000 --- a/lib/soloud +++ b/lib/soloud @@ -1 +1 @@ -Subproject commit c8e339fdce5c7107bdb3e64bbf707c8fd3449beb +Subproject commit e82fd32c1f62183922f08c14c814a02b58db1873 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 + +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) -- cgit v1.2.3 From d3f39a67d62473661f7a76237ebf6df66e26d506 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 9 Nov 2024 13:17:47 +0100 Subject: more cleanup --- src/crepe/api/LoopManager.cpp | 12 ++++++------ src/crepe/api/LoopManager.h | 2 +- src/crepe/api/LoopTimer.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 746e9ce..0e22522 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -3,19 +3,20 @@ #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" +#include "../facade/SDLContext.h" #include "LoopManager.h" #include "LoopTimer.h" namespace crepe { void LoopManager::process_input() { - SDLContext::get_instance().handle_events(this->gameRunning); + SDLContext::get_instance().handle_events(this->game_running); } void LoopManager::start(){ this->setup(); this->loop(); } -void LoopManager::set_running(bool running) { this->gameRunning = running; } +void LoopManager::set_running(bool running) { this->game_running = running; } void LoopManager::fixed_update() { } @@ -24,7 +25,7 @@ void LoopManager::loop() { LoopTimer & timer = LoopTimer::getInstance(); timer.start(); - while (gameRunning) { + while (game_running) { timer.update(); while (timer.get_lag() >= timer.get_fixed_delta_time()) { @@ -42,20 +43,19 @@ void LoopManager::loop() { void LoopManager::setup() { - this->gameRunning = true; + this->game_running = true; LoopTimer::getInstance().start(); LoopTimer::getInstance().set_fps(60); } void LoopManager::render() { - if (gameRunning) { + if (game_running) { 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 index a5c88c3..8899bfd 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -60,7 +60,7 @@ class LoopManager { */ void render(); - bool gameRunning = false; + bool game_running = false; }; } // namespace crepe diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index 5e432fc..912493a 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -1,7 +1,7 @@ #include "../facade/SDLContext.h" -#include "api/LoopTimer.h" +#include "LoopTimer.h" using namespace crepe; -- cgit v1.2.3 From acfa153789d9b55f3453a1d32f249da04ad6b5c1 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 9 Nov 2024 13:21:34 +0100 Subject: changed comment --- src/crepe/api/LoopTimer.h | 2 +- src/crepe/facade/SDLContext.cpp | 203 ++++++++++++++++++++++++---------------- src/crepe/facade/SDLContext.h | 127 +++++++++++++++++++++++-- 3 files changed, 239 insertions(+), 93 deletions(-) diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index 584a408..8d95921 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -78,4 +78,4 @@ 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 +} // namespace crepe diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 8da93e9..17ced0c 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -1,16 +1,22 @@ #include #include +#include #include #include #include #include #include +#include #include +#include +#include +#include #include "../api/Sprite.h" #include "../api/Texture.h" #include "../api/Transform.h" #include "../util/log.h" +#include "Exception.h" #include "SDLContext.h" @@ -21,34 +27,6 @@ SDLContext & SDLContext::get_instance() { return instance; } -void SDLContext::handle_events(bool & running) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - if (event.type == SDL_QUIT) { - running = false; - } - } -} - -SDLContext::~SDLContext() { - dbg_trace(); - - if (this->game_renderer != nullptr) - SDL_DestroyRenderer(this->game_renderer); - - if (this->game_window != nullptr) { - SDL_DestroyWindow(this->game_window); - } - - // TODO: how are we going to ensure that these are called from the same - // thread that SDL_Init() was called on? This has caused problems for me - // before. - IMG_Quit(); - SDL_Quit(); -} - -void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer); } - SDLContext::SDLContext() { dbg_trace(); // FIXME: read window defaults from config manager @@ -59,26 +37,32 @@ SDLContext::SDLContext() { << std::endl; return; } - - this->game_window = SDL_CreateWindow( + SDL_Window * tmp_window = SDL_CreateWindow( "Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - 1920, 1080, SDL_WINDOW_SHOWN); - if (!this->game_window) { + this->viewport.w, this->viewport.h, 0); + if (!tmp_window) { // FIXME: throw exception std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl; + return; } + this->game_window + = {tmp_window, [](SDL_Window * window) { SDL_DestroyWindow(window); }}; - this->game_renderer - = SDL_CreateRenderer(this->game_window, -1, SDL_RENDERER_ACCELERATED); - if (!this->game_renderer) { + SDL_Renderer * tmp_renderer = SDL_CreateRenderer( + this->game_window.get(), -1, SDL_RENDERER_ACCELERATED); + if (!tmp_renderer) { // FIXME: throw exception std::cerr << "Renderer could not be created! SDL_Error: " << SDL_GetError() << std::endl; - SDL_DestroyWindow(this->game_window); + SDL_DestroyWindow(this->game_window.get()); return; } + this->game_renderer = {tmp_renderer, [](SDL_Renderer * renderer) { + SDL_DestroyRenderer(renderer); + }}; + int img_flags = IMG_INIT_PNG; if (!(IMG_Init(img_flags) & img_flags)) { // FIXME: throw exception @@ -87,71 +71,126 @@ SDLContext::SDLContext() { } } -void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer); } +SDLContext::~SDLContext() { + dbg_trace(); + + this->game_renderer.reset(); + this->game_window.reset(); + + // TODO: how are we going to ensure that these are called from the same + // thread that SDL_Init() was called on? This has caused problems for me + // before. + IMG_Quit(); + SDL_Quit(); +} + +void SDLContext::handle_events(bool & running) { + //TODO: wouter i need events + /* + SDL_Event event; + SDL_PollEvent(&event); + switch (event.type) { + case SDL_QUIT: + running = false; + break; + case SDL_KEYDOWN: + triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym))); + break; + case SDL_MOUSEBUTTONDOWN: + int x, y; + SDL_GetMouseState(&x, &y); + triggerEvent(MousePressedEvent(x, y)); + break; + } + */ +} + +void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } +void SDLContext::present_screen() { + SDL_RenderPresent(this->game_renderer.get()); +} -void SDLContext::draw(const Sprite & sprite, const Transform & transform) { +void SDLContext::draw(const Sprite & sprite, const Transform & transform, + const Camera & cam) { - static SDL_RendererFlip render_flip + SDL_RendererFlip render_flip = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x) | (SDL_FLIP_VERTICAL * sprite.flip.flip_y)); - int w, h; - SDL_QueryTexture(sprite.sprite_image->texture, NULL, NULL, &w, &h); - // needs maybe camera for position + double adjusted_x = (transform.position.x - cam.x) * cam.zoom; + double adjusted_y = (transform.position.y - cam.y) * cam.zoom; + double adjusted_w = sprite.sprite_rect.w * transform.scale * cam.zoom; + double adjusted_h = sprite.sprite_rect.h * transform.scale * cam.zoom; + + SDL_Rect srcrect = { + .x = sprite.sprite_rect.x, + .y = sprite.sprite_rect.y, + .w = sprite.sprite_rect.w, + .h = sprite.sprite_rect.h, + }; + SDL_Rect dstrect = { - .x = static_cast(transform.position.x), - .y = static_cast(transform.position.y), - .w = static_cast(w * transform.scale), - .h = static_cast(h * transform.scale), + .x = static_cast(adjusted_x), + .y = static_cast(adjusted_y), + .w = static_cast(adjusted_w), + .h = static_cast(adjusted_h), }; - double degrees = transform.rotation * 180 / M_PI; - SDL_RenderCopyEx(this->game_renderer, sprite.sprite_image->texture, NULL, - &dstrect, degrees, NULL, render_flip); + SDL_RenderCopyEx(this->game_renderer.get(), + sprite.sprite_image->texture.get(), &srcrect, + + &dstrect, transform.rotation, NULL, render_flip); } -/* -SDL_Texture * SDLContext::setTextureFromPath(const char * path, SDL_Rect & clip, - const int row, const int col) { - dbg_trace(); +void SDLContext::camera(const Camera & cam) { + this->viewport.w = static_cast(cam.aspect_width); + this->viewport.h = static_cast(cam.aspect_height); + this->viewport.x = static_cast(cam.x) - (SCREEN_WIDTH / 2); + this->viewport.y = static_cast(cam.y) - (SCREEN_HEIGHT / 2); - SDL_Surface * tmp = IMG_Load(path); - if (!tmp) { - std::cerr << "Error surface " << IMG_GetError << std::endl; - } + SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, + cam.bg_color.g, cam.bg_color.b, cam.bg_color.a); +} - clip. - w = tmp->w / col; - clip.h = tmp->h / row; +uint64_t SDLContext::get_ticks() const { return SDL_GetTicks64(); } - SDL_Texture * CreatedTexture - = SDL_CreateTextureFromSurface(this->game_renderer, tmp); +std::unique_ptr> +SDLContext::texture_from_path(const std::string & path) { - if (!CreatedTexture) { - std::cerr << "Error could not create texture " << IMG_GetError - << std::endl; + SDL_Surface * tmp = IMG_Load(path.c_str()); + if (tmp == nullptr) { + throw Exception("surface cannot be load from %s", path.c_str()); } - SDL_FreeSurface(tmp); - return CreatedTexture; -} -*/ + std::unique_ptr> + img_surface; + img_surface + = {tmp, [](SDL_Surface * surface) { SDL_FreeSurface(surface); }}; -SDL_Texture * SDLContext::texture_from_path(const char * path) { - dbg_trace(); + SDL_Texture * tmp_texture = SDL_CreateTextureFromSurface( + this->game_renderer.get(), img_surface.get()); - SDL_Surface * tmp = IMG_Load(path); - if (!tmp) { - std::cerr << "Error surface " << IMG_GetError << std::endl; + if (tmp_texture == nullptr) { + throw Exception("Texture cannot be load from %s", path.c_str()); } - SDL_Texture * created_texture - = SDL_CreateTextureFromSurface(this->game_renderer, tmp); - if (!created_texture) { - std::cerr << "Error could not create texture " << IMG_GetError - << std::endl; - } - SDL_FreeSurface(tmp); + std::unique_ptr> + img_texture; + img_texture = {tmp_texture, + [](SDL_Texture * texture) { SDL_DestroyTexture(texture); }}; - return created_texture; + return img_texture; +} +int SDLContext::get_width(const Texture & ctx) const { + int w; + SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &w, NULL); + return w; +} +int SDLContext::get_height(const Texture & ctx) const { + int h; + SDL_QueryTexture(ctx.texture.get(), NULL, NULL, NULL, &h); + return h; +} +void SDLContext::delay(int ms) const{ + SDL_Delay(ms); } diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index f1ba8a6..6c57ef9 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -1,48 +1,155 @@ #pragma once +#include #include #include +#include +#include +#include #include "../api/Sprite.h" #include "../api/Transform.h" -#include "../system/RenderSystem.h" +#include "api/Camera.h" + +// FIXME: this needs to be removed +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; namespace crepe { +// TODO: SDL_Keycode is defined in a header not distributed with crepe, which +// means this typedef is unusable when crepe is packaged. Wouter will fix this +// later. +typedef SDL_Keycode CREPE_KEYCODES; + class Texture; +class LoopManager; + +/** + * \class SDLContext + * \brief Facade for the SDL library + * + * SDLContext is a singleton that handles the SDL window and renderer, provides methods + * for event handling, and rendering to the screen. It is never used directly by the user + */ class SDLContext { public: - // singleton + /** + * \brief Gets the singleton instance of SDLContext. + * \return Reference to the SDLContext instance. + */ static SDLContext & get_instance(); + SDLContext(const SDLContext &) = delete; SDLContext(SDLContext &&) = delete; SDLContext & operator=(const SDLContext &) = delete; SDLContext & operator=(SDLContext &&) = delete; - //TODO decide events wouter? - private: + //! will only use handle_events + friend class LoopManager; + /** + * \brief Handles SDL events such as window close and input. + * \param running Reference to a boolean flag that controls the main loop. + */ void handle_events(bool & running); private: + //! Will only use get_ticks + friend class AnimatorSystem; + friend class LoopTimer; + /** + * \brief Gets the current SDL ticks since the program started. + * \return Current ticks in milliseconds as a constant uint64_t. + */ + uint64_t get_ticks() const; + /** + * \brief Pauses the execution for a specified duration. + * + * This function uses SDL's delay function to halt the program execution + * for a given number of milliseconds, allowing for frame rate control + * or other timing-related functionality. + * + * \param ms Duration of the delay in milliseconds. + */ + void delay(int ms) const; +private: + /** + * \brief Constructs an SDLContext instance. + * Initializes SDL, creates a window and renderer. + */ SDLContext(); - virtual ~SDLContext(); + + /** + * \brief Destroys the SDLContext instance. + * Cleans up SDL resources, including the window and renderer. + */ + ~SDLContext(); private: + //! Will use the funtions: texture_from_path, get_width,get_height. friend class Texture; - SDL_Texture * texture_from_path(const char *); - //SDL_Texture* setTextureFromPath(const char*, SDL_Rect& clip, const int row, const int col); + + //! Will use the funtions: texture_from_path, get_width,get_height. + friend class Animator; + + /** + * \brief Loads a texture from a file path. + * \param path Path to the image file. + * \return Pointer to the created SDL_Texture. + */ + std::unique_ptr> + texture_from_path(const std::string & path); + /** + * \brief Gets the width of a texture. + * \param texture Reference to the Texture object. + * \return Width of the texture as an integer. + */ + int get_width(const Texture &) const; + + /** + * \brief Gets the height of a texture. + * \param texture Reference to the Texture object. + * \return Height of the texture as an integer. + */ + int get_height(const Texture &) const; private: + //! Will use draw,clear_screen, present_screen, camera. friend class RenderSystem; - void draw(const Sprite &, const Transform &); + + /** + * \brief Draws a sprite to the screen using the specified transform and camera. + * \param sprite Reference to the Sprite to draw. + * \param transform Reference to the Transform for positioning. + * \param camera Reference to the Camera for view adjustments. + */ + void draw(const Sprite & sprite, const Transform & transform, + const Camera & camera); + + //! Clears the screen, preparing for a new frame. void clear_screen(); + + //! Presents the rendered frame to the screen. void present_screen(); + /** + * \brief Sets the current camera for rendering. + * \param camera Reference to the Camera object. + */ + void camera(const Camera & camera); + private: - SDL_Window * game_window = nullptr; - SDL_Renderer * game_renderer = nullptr; + //! sdl Window + std::unique_ptr> game_window; + + //! renderer for the crepe engine + std::unique_ptr> + game_renderer; + + //! viewport for the camera window + SDL_Rect viewport = {0, 0, 640, 480}; }; } // namespace crepe -- cgit v1.2.3 From d23b23610f75797ff37cfd73881c6fd7d5a21c88 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 9 Nov 2024 13:35:25 +0100 Subject: cleanup code --- lib/sdl2 | 2 +- lib/sdl_image | 2 +- lib/sdl_ttf | 2 +- lib/soloud | 2 +- src/crepe/api/CMakeLists.txt | 4 ---- src/crepe/api/LoopManager.cpp | 1 - src/crepe/api/LoopTimer.cpp | 1 - src/example/CMakeLists.txt | 1 - src/example/gameLoop.cpp | 8 -------- src/makefile | 6 +++--- 10 files changed, 7 insertions(+), 22 deletions(-) delete mode 100644 src/example/gameLoop.cpp diff --git a/lib/sdl2 b/lib/sdl2 index c98c4fb..9519b99 160000 --- a/lib/sdl2 +++ b/lib/sdl2 @@ -1 +1 @@ -Subproject commit c98c4fbff6d8f3016a3ce6685bf8f43433c3efcc +Subproject commit 9519b9916cd29a14587af0507292f2bd31dd5752 diff --git a/lib/sdl_image b/lib/sdl_image index 5656019..abcf63a 160000 --- a/lib/sdl_image +++ b/lib/sdl_image @@ -1 +1 @@ -Subproject commit 56560190a6c5b5740e5afdce747e2a2bfbf16db1 +Subproject commit abcf63aa71b4e3ac32120fa9870a6500ddcdcc89 diff --git a/lib/sdl_ttf b/lib/sdl_ttf index a3d0895..4a318f8 160000 --- a/lib/sdl_ttf +++ b/lib/sdl_ttf @@ -1 +1 @@ -Subproject commit a3d0895c1b60c41ff9e85d9203ddd7485c014dae +Subproject commit 4a318f8dfaa1bb6f10e0c5e54052e25d3c7f3440 diff --git a/lib/soloud b/lib/soloud index e82fd32..c8e339f 160000 --- a/lib/soloud +++ b/lib/soloud @@ -1 +1 @@ -Subproject commit e82fd32c1f62183922f08c14c814a02b58db1873 +Subproject commit c8e339fdce5c7107bdb3e64bbf707c8fd3449beb diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index e7894d7..3b20142 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -16,8 +16,6 @@ target_sources(crepe PUBLIC Scene.cpp SceneManager.cpp Vector2.cpp - LoopManager.cpp - LoopTimer.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -40,6 +38,4 @@ 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 index 0e22522..99763e4 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -1,5 +1,4 @@ - #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index 912493a..c6ffe9d 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -3,7 +3,6 @@ #include "LoopTimer.h" - using namespace crepe; LoopTimer::LoopTimer() {} diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 751b556..36f9d4d 100644 --- a/src/example/CMakeLists.txt +++ b/src/example/CMakeLists.txt @@ -28,5 +28,4 @@ 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 deleted file mode 100644 index f3edbdb..0000000 --- a/src/example/gameLoop.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#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 5e525e8..ce5a29f 100644 --- a/src/makefile +++ b/src/makefile @@ -94,11 +94,11 @@ 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/LoopManager.cpp WOUTER += crepe/api/LoopTimer.h -FMT := $(JARO) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2 +WOUTER += crepe/api/LoopTimer.cpp +FMT := $(WOUTER) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2 format: FORCE clang-tidy -p build/compile_commands.json --fix-errors $(FMT) -- cgit v1.2.3 From b03f3a6300668550afa4d318e520a628a40fc76e Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 9 Nov 2024 13:39:23 +0100 Subject: added gameloop example --- src/example/CMakeLists.txt | 1 + src/example/gameloop.cpp | 7 +++++++ 2 files changed, 8 insertions(+) create mode 100644 src/example/gameloop.cpp diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt index 36f9d4d..c8a4b85 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..6cd0301 --- /dev/null +++ b/src/example/gameloop.cpp @@ -0,0 +1,7 @@ +#include "crepe/api/LoopManager.h" +using namespace crepe; +int main(){ + LoopManager gameloop; + gameloop.start(); + return 1; +} -- cgit v1.2.3 From aa4fbb5d2778ea40c3f996c9b07bcdbb155cbcd0 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 9 Nov 2024 13:42:18 +0100 Subject: make format changes --- src/crepe/api/LoopManager.cpp | 8 ++++---- src/crepe/api/LoopTimer.cpp | 2 +- src/crepe/api/LoopTimer.h | 2 +- src/crepe/facade/SDLContext.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 99763e4..e737f78 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -21,7 +21,7 @@ void LoopManager::fixed_update() { } void LoopManager::loop() { - LoopTimer & timer = LoopTimer::getInstance(); + LoopTimer & timer = LoopTimer::get_instance(); timer.start(); while (game_running) { @@ -43,8 +43,8 @@ void LoopManager::loop() { void LoopManager::setup() { this->game_running = true; - LoopTimer::getInstance().start(); - LoopTimer::getInstance().set_fps(60); + LoopTimer::get_instance().start(); + LoopTimer::get_instance().set_fps(60); } void LoopManager::render() { @@ -54,7 +54,7 @@ void LoopManager::render() { } void LoopManager::update() { - LoopTimer & timer = LoopTimer::getInstance(); + LoopTimer & timer = LoopTimer::get_instance(); } } // namespace crepe diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index c6ffe9d..98ce08d 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -6,7 +6,7 @@ using namespace crepe; LoopTimer::LoopTimer() {} -LoopTimer & LoopTimer::getInstance() { +LoopTimer & LoopTimer::get_instance() { static LoopTimer instance; return instance; } diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index 8d95921..5b7d3f2 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -10,7 +10,7 @@ public: * * \return A reference to the LoopTimer instance. */ -static LoopTimer& getInstance(); +static LoopTimer& get_instance(); /** * \brief Get the current delta time for the current frame. diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 6c57ef9..67e330b 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -9,7 +9,7 @@ #include "../api/Sprite.h" #include "../api/Transform.h" -#include "api/Camera.h" +// #include "../api/Camera.h" // FIXME: this needs to be removed const int SCREEN_WIDTH = 640; -- cgit v1.2.3 From 89c96e6478535c3a73aaa6c29591e008399b1a09 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Sat, 9 Nov 2024 13:43:28 +0100 Subject: added line break --- src/crepe/api/LoopManager.cpp | 2 +- src/crepe/facade/SDLContext.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index e737f78..5c79920 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -1,8 +1,8 @@ #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" - #include "../facade/SDLContext.h" + #include "LoopManager.h" #include "LoopTimer.h" diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 67e330b..6c57ef9 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -9,7 +9,7 @@ #include "../api/Sprite.h" #include "../api/Transform.h" -// #include "../api/Camera.h" +#include "api/Camera.h" // FIXME: this needs to be removed const int SCREEN_WIDTH = 640; -- cgit v1.2.3 From 44a04278496008a89ffa7044bc52c7cdb9f4d425 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 09:11:19 +0100 Subject: added more doxygen comments --- src/crepe/api/LoopTimer.cpp | 7 +++- src/crepe/api/LoopTimer.h | 80 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index 98ce08d..aaba8b3 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -1,10 +1,14 @@ #include "../facade/SDLContext.h" +#include "../util/log.h" #include "LoopTimer.h" using namespace crepe; -LoopTimer::LoopTimer() {} + +LoopTimer::LoopTimer() { + dbg_trace(); +} LoopTimer & LoopTimer::get_instance() { static LoopTimer instance; @@ -55,4 +59,5 @@ void LoopTimer::enforce_frame_rate() { 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 index 5b7d3f2..e1cfc35 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -3,6 +3,7 @@ #include namespace crepe{ + class LoopTimer { public: /** @@ -59,23 +60,84 @@ void set_game_scale(double game_scale); private: friend class LoopManager; + +/** + * \brief Start the loop timer. + * + * Initializes the timer to begin tracking frame times. + */ void start(); + +/** + * \brief Enforce the frame rate limit. + * + * Ensures that the game loop does not exceed the target FPS by delaying + * frame updates as necessary. + */ void enforce_frame_rate(); + +/** + * \brief Get the fixed delta time for consistent updates. + * + * Fixed delta time is used for operations that require uniform time steps, + * such as physics calculations. + * + * \return Fixed delta time in seconds. + */ double get_fixed_delta_time() const; + +/** + * \brief Get the accumulated lag in the game loop. + * + * Lag represents the difference between the target frame time and the + * actual frame time, useful for managing fixed update intervals. + * + * \return Accumulated lag in seconds. + */ double get_lag() const; + +/** + * \brief Construct a new LoopTimer object. + * + * Private constructor for singleton pattern to restrict instantiation + * outside the class. + */ LoopTimer(); + +/** + * \brief Update the timer to the current frame. + * + * Calculates and updates the delta time for the current frame and adds it to + * the cumulative game time. + */ void update(); + +/** + * \brief Advance the game loop by a fixed update interval. + * + * This method progresses the game state by a consistent, fixed time step, + * allowing for stable updates independent of frame rate fluctuations. + */ 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 +//! Current frames per second +int fps = 50; +///< Current game scale +double game_scale = 1; +//! Maximum delta time to avoid large jumps +double maximum_delta_time = 0.25; +//! Delta time for the current frame +double delta_time = 0; +//! Target time per frame in seconds +double frame_target_time = 1.0 / fps; +//! Fixed delta time for fixed updates +double fixed_delta_time = 0.02; +//! Total elapsed game time +double elapsed_time = 0; +//! Total elapsed time for fixed updates +double elapsed_fixed_time = 0; +//! Time of the last frame +uint64_t last_frame_time = 0; }; } // namespace crepe -- cgit v1.2.3 From 68fa604568e6dafac383a88d252c125f97431567 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 09:43:53 +0100 Subject: fixed spacing --- src/crepe/api/LoopManager.h | 106 +++++++++--------- src/crepe/api/LoopTimer.h | 264 ++++++++++++++++++++++---------------------- 2 files changed, 185 insertions(+), 185 deletions(-) diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 8899bfd..af60d44 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -3,64 +3,64 @@ namespace crepe { class LoopManager { - public: - void start(); +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(); +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 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 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 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(); + /** + * \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 game_running = false; - }; + bool game_running = false; +}; } // namespace crepe diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index e1cfc35..0089b24 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -3,141 +3,141 @@ #include namespace crepe{ - + class LoopTimer { public: -/** - * \brief Get the singleton instance of LoopTimer. - * - * \return A reference to the LoopTimer instance. - */ -static LoopTimer& get_instance(); - -/** - * \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; - -/** - * \brief Start the loop timer. - * - * Initializes the timer to begin tracking frame times. - */ -void start(); - -/** - * \brief Enforce the frame rate limit. - * - * Ensures that the game loop does not exceed the target FPS by delaying - * frame updates as necessary. - */ -void enforce_frame_rate(); - -/** - * \brief Get the fixed delta time for consistent updates. - * - * Fixed delta time is used for operations that require uniform time steps, - * such as physics calculations. - * - * \return Fixed delta time in seconds. - */ -double get_fixed_delta_time() const; - -/** - * \brief Get the accumulated lag in the game loop. - * - * Lag represents the difference between the target frame time and the - * actual frame time, useful for managing fixed update intervals. - * - * \return Accumulated lag in seconds. - */ -double get_lag() const; - -/** - * \brief Construct a new LoopTimer object. - * - * Private constructor for singleton pattern to restrict instantiation - * outside the class. - */ -LoopTimer(); - -/** - * \brief Update the timer to the current frame. - * - * Calculates and updates the delta time for the current frame and adds it to - * the cumulative game time. - */ -void update(); - -/** - * \brief Advance the game loop by a fixed update interval. - * - * This method progresses the game state by a consistent, fixed time step, - * allowing for stable updates independent of frame rate fluctuations. - */ -void advance_fixed_update(); + /** + * \brief Get the singleton instance of LoopTimer. + * + * \return A reference to the LoopTimer instance. + */ + static LoopTimer& get_instance(); + + /** + * \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; + + /** + * \brief Start the loop timer. + * + * Initializes the timer to begin tracking frame times. + */ + void start(); + + /** + * \brief Enforce the frame rate limit. + * + * Ensures that the game loop does not exceed the target FPS by delaying + * frame updates as necessary. + */ + void enforce_frame_rate(); + + /** + * \brief Get the fixed delta time for consistent updates. + * + * Fixed delta time is used for operations that require uniform time steps, + * such as physics calculations. + * + * \return Fixed delta time in seconds. + */ + double get_fixed_delta_time() const; + + /** + * \brief Get the accumulated lag in the game loop. + * + * Lag represents the difference between the target frame time and the + * actual frame time, useful for managing fixed update intervals. + * + * \return Accumulated lag in seconds. + */ + double get_lag() const; + + /** + * \brief Construct a new LoopTimer object. + * + * Private constructor for singleton pattern to restrict instantiation + * outside the class. + */ + LoopTimer(); + + /** + * \brief Update the timer to the current frame. + * + * Calculates and updates the delta time for the current frame and adds it to + * the cumulative game time. + */ + void update(); + + /** + * \brief Advance the game loop by a fixed update interval. + * + * This method progresses the game state by a consistent, fixed time step, + * allowing for stable updates independent of frame rate fluctuations. + */ + void advance_fixed_update(); private: -//! Current frames per second -int fps = 50; -///< Current game scale -double game_scale = 1; -//! Maximum delta time to avoid large jumps -double maximum_delta_time = 0.25; -//! Delta time for the current frame -double delta_time = 0; -//! Target time per frame in seconds -double frame_target_time = 1.0 / fps; -//! Fixed delta time for fixed updates -double fixed_delta_time = 0.02; -//! Total elapsed game time -double elapsed_time = 0; -//! Total elapsed time for fixed updates -double elapsed_fixed_time = 0; -//! Time of the last frame -uint64_t last_frame_time = 0; + //! Current frames per second + int fps = 50; + ///< Current game scale + double game_scale = 1; + //! Maximum delta time to avoid large jumps + double maximum_delta_time = 0.25; + //! Delta time for the current frame + double delta_time = 0; + //! Target time per frame in seconds + double frame_target_time = 1.0 / fps; + //! Fixed delta time for fixed updates + double fixed_delta_time = 0.02; + //! Total elapsed game time + double elapsed_time = 0; + //! Total elapsed time for fixed updates + double elapsed_fixed_time = 0; + //! Time of the last frame + uint64_t last_frame_time = 0; }; } // namespace crepe -- cgit v1.2.3 From 30c1eeeb9f1ca5a643a30edb4e7010f8a60bdd30 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 18:09:39 +0100 Subject: code cleanup changes --- src/crepe/api/LoopManager.cpp | 19 +++++++++++----- src/crepe/api/LoopManager.h | 15 +++++++++++- src/crepe/api/LoopTimer.cpp | 53 ++++++++++++++++++++++++------------------- src/crepe/api/LoopTimer.h | 2 +- 4 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index 5c79920..abf1f7e 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -7,7 +7,14 @@ #include "LoopTimer.h" namespace crepe { - +LoopManager::LoopManager(const RenderSystem& renderSystem, const SDLContext& sdlContext, + const LoopTimer& loopTimer, const ScriptSystem& scriptSystem, + const SoundSystem& soundSystem, const ParticleSystem& particleSystem, + const PhysicsSystem& physicsSystem, const AnimatorSystem& animatorSystem, + const CollisionSystem& collisionSystem) { + // Initialize systems if needed + // Example: this->renderSystem = renderSystem; +} void LoopManager::process_input() { SDLContext::get_instance().handle_events(this->game_running); } @@ -28,13 +35,13 @@ void LoopManager::loop() { timer.update(); while (timer.get_lag() >= timer.get_fixed_delta_time()) { - process_input(); - fixed_update(); + this->process_input(); + this->fixed_update(); timer.advance_fixed_update(); } - update(); - render(); + this->update(); + this->render(); timer.enforce_frame_rate(); } @@ -48,7 +55,7 @@ void LoopManager::setup() { } void LoopManager::render() { - if (game_running) { + if (this->game_running) { RenderSystem::get_instance().update(); } } diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index af60d44..79abae6 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -1,11 +1,24 @@ #pragma once + namespace crepe { +class RenderSystem; +class SDLContext; +class LoopTimer; +class ScriptSystem; +class SoundSystem; +class ParticleSystem; +class PhysicsSystem; +class AnimatorSystem; +class CollisionSystem; + class LoopManager { public: void start(); - + LoopManager(const RenderSystem&, const SDLContext&, const LoopTimer&, const ScriptSystem&, + const SoundSystem&, const ParticleSystem&, const PhysicsSystem&, const AnimatorSystem&, + const CollisionSystem&); private: /** * \brief Setup function for one-time initialization. diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index aaba8b3..f4be510 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -4,6 +4,8 @@ #include "LoopTimer.h" +#define MS_PER_SECOND 1000.0 + using namespace crepe; LoopTimer::LoopTimer() { @@ -16,48 +18,53 @@ LoopTimer & LoopTimer::get_instance() { } void LoopTimer::start() { - last_frame_time = SDLContext::get_instance().get_ticks(); - elapsed_time = 0; - elapsed_fixed_time = 0; - delta_time = 0; + this->last_frame_time = SDLContext::get_instance().get_ticks(); + this->elapsed_time = 0; + this->elapsed_fixed_time = 0; + this->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; + this->delta_time = (current_frame_time - last_frame_time) / MS_PER_SECOND; - if (delta_time > maximum_delta_time) { - delta_time = maximum_delta_time; + if (this->delta_time > this->maximum_delta_time) { + this->delta_time = this->maximum_delta_time; } - delta_time = game_scale; - elapsed_time += delta_time; - last_frame_time = current_frame_time; + this->delta_time = this->game_scale; + this->elapsed_time += this->delta_time; + this->last_frame_time = current_frame_time; } -double LoopTimer::get_delta_time() const { return delta_time; } -int LoopTimer::get_current_time() const { return elapsed_time; } +double LoopTimer::get_delta_time() const { return this->delta_time; } + +int LoopTimer::get_current_time() const { return this->elapsed_time; } -void LoopTimer::advance_fixed_update() { elapsed_fixed_time += fixed_delta_time; } +void LoopTimer::advance_fixed_update() { this->elapsed_fixed_time += this->fixed_delta_time; } -double LoopTimer::get_fixed_delta_time() const { return fixed_delta_time; } +double LoopTimer::get_fixed_delta_time() const { return this->fixed_delta_time; } void LoopTimer::set_fps(int fps) { this->fps = fps; - frame_target_time = 1.0 / fps; + this->frame_target_time = 1.0 / this->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; } +int LoopTimer::get_fps() const { return this->fps; } + +void LoopTimer::set_game_scale(double value) { this->game_scale = value; }; + +double LoopTimer::get_game_scale() const { return this->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; + double frame_duration = (current_frame_time - this->last_frame_time) / MS_PER_SECOND; - if (frame_duration < frame_target_time) { - uint32_t delay_time - = (uint32_t) ((frame_target_time - frame_duration) / 1000.0); + if (frame_duration < this->frame_target_time) { + uint32_t delay_time = static_cast((this->frame_target_time - frame_duration) * MS_PER_SECOND); SDLContext::get_instance().delay(delay_time); } + + this->last_frame_time = current_frame_time; } -double LoopTimer::get_lag() const { return elapsed_time - elapsed_fixed_time; } +double LoopTimer::get_lag() const { return this->elapsed_time - this->elapsed_fixed_time; } diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index 0089b24..4ce0053 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -122,7 +122,7 @@ public: private: //! Current frames per second int fps = 50; - ///< Current game scale + //! Current game scale double game_scale = 1; //! Maximum delta time to avoid large jumps double maximum_delta_time = 0.25; -- cgit v1.2.3 From 31a6448f8c97934dd9974758d9b5049650040bc7 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 18:16:28 +0100 Subject: changed seconds into ms --- lib/sdl2 | 2 +- lib/sdl_image | 2 +- lib/sdl_ttf | 2 +- src/crepe/api/LoopManager.cpp | 3 +- src/crepe/api/LoopTimer.cpp | 27 ++--- src/crepe/api/LoopTimer.h | 265 +++++++++++++++++++++--------------------- 6 files changed, 146 insertions(+), 155 deletions(-) diff --git a/lib/sdl2 b/lib/sdl2 index 9519b99..c98c4fb 160000 --- a/lib/sdl2 +++ b/lib/sdl2 @@ -1 +1 @@ -Subproject commit 9519b9916cd29a14587af0507292f2bd31dd5752 +Subproject commit c98c4fbff6d8f3016a3ce6685bf8f43433c3efcc diff --git a/lib/sdl_image b/lib/sdl_image index abcf63a..5656019 160000 --- a/lib/sdl_image +++ b/lib/sdl_image @@ -1 +1 @@ -Subproject commit abcf63aa71b4e3ac32120fa9870a6500ddcdcc89 +Subproject commit 56560190a6c5b5740e5afdce747e2a2bfbf16db1 diff --git a/lib/sdl_ttf b/lib/sdl_ttf index 4a318f8..a3d0895 160000 --- a/lib/sdl_ttf +++ b/lib/sdl_ttf @@ -1 +1 @@ -Subproject commit 4a318f8dfaa1bb6f10e0c5e54052e25d3c7f3440 +Subproject commit a3d0895c1b60c41ff9e85d9203ddd7485c014dae diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index abf1f7e..d4345d0 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -6,7 +6,7 @@ #include "LoopManager.h" #include "LoopTimer.h" -namespace crepe { +using namespace crepe; LoopManager::LoopManager(const RenderSystem& renderSystem, const SDLContext& sdlContext, const LoopTimer& loopTimer, const ScriptSystem& scriptSystem, const SoundSystem& soundSystem, const ParticleSystem& particleSystem, @@ -64,4 +64,3 @@ void LoopManager::update() { LoopTimer & timer = LoopTimer::get_instance(); } -} // namespace crepe diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index f4be510..dd4d7e5 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -1,18 +1,14 @@ - #include "../facade/SDLContext.h" #include "../util/log.h" - #include "LoopTimer.h" -#define MS_PER_SECOND 1000.0 - using namespace crepe; LoopTimer::LoopTimer() { - dbg_trace(); + dbg_trace(); } -LoopTimer & LoopTimer::get_instance() { +LoopTimer& LoopTimer::get_instance() { static LoopTimer instance; return instance; } @@ -26,41 +22,36 @@ void LoopTimer::start() { void LoopTimer::update() { uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); - this->delta_time = (current_frame_time - last_frame_time) / MS_PER_SECOND; + this->delta_time = (current_frame_time - last_frame_time); if (this->delta_time > this->maximum_delta_time) { this->delta_time = this->maximum_delta_time; } - this->delta_time = this->game_scale; + this->delta_time *= this->game_scale; this->elapsed_time += this->delta_time; this->last_frame_time = current_frame_time; } double LoopTimer::get_delta_time() const { return this->delta_time; } - -int LoopTimer::get_current_time() const { return this->elapsed_time; } - +double LoopTimer::get_current_time() const { return this->elapsed_time; } void LoopTimer::advance_fixed_update() { this->elapsed_fixed_time += this->fixed_delta_time; } - double LoopTimer::get_fixed_delta_time() const { return this->fixed_delta_time; } void LoopTimer::set_fps(int fps) { this->fps = fps; - this->frame_target_time = 1.0 / this->fps; + this->frame_target_time = 1000.0 / this->fps; } int LoopTimer::get_fps() const { return this->fps; } - -void LoopTimer::set_game_scale(double value) { this->game_scale = value; }; - +void LoopTimer::set_game_scale(double value) { this->game_scale = value; } double LoopTimer::get_game_scale() const { return this->game_scale; } void LoopTimer::enforce_frame_rate() { uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); - double frame_duration = (current_frame_time - this->last_frame_time) / MS_PER_SECOND; + double frame_duration = (current_frame_time - this->last_frame_time); if (frame_duration < this->frame_target_time) { - uint32_t delay_time = static_cast((this->frame_target_time - frame_duration) * MS_PER_SECOND); + uint32_t delay_time = static_cast(this->frame_target_time - frame_duration); SDLContext::get_instance().delay(delay_time); } diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index 4ce0053..5f9b6a7 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -2,142 +2,143 @@ #include -namespace crepe{ +namespace crepe { class LoopTimer { public: - /** - * \brief Get the singleton instance of LoopTimer. - * - * \return A reference to the LoopTimer instance. - */ - static LoopTimer& get_instance(); - - /** - * \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; - - /** - * \brief Start the loop timer. - * - * Initializes the timer to begin tracking frame times. - */ - void start(); - - /** - * \brief Enforce the frame rate limit. - * - * Ensures that the game loop does not exceed the target FPS by delaying - * frame updates as necessary. - */ - void enforce_frame_rate(); - - /** - * \brief Get the fixed delta time for consistent updates. - * - * Fixed delta time is used for operations that require uniform time steps, - * such as physics calculations. - * - * \return Fixed delta time in seconds. - */ - double get_fixed_delta_time() const; - - /** - * \brief Get the accumulated lag in the game loop. - * - * Lag represents the difference between the target frame time and the - * actual frame time, useful for managing fixed update intervals. - * - * \return Accumulated lag in seconds. - */ - double get_lag() const; - - /** - * \brief Construct a new LoopTimer object. - * - * Private constructor for singleton pattern to restrict instantiation - * outside the class. - */ - LoopTimer(); - - /** - * \brief Update the timer to the current frame. - * - * Calculates and updates the delta time for the current frame and adds it to - * the cumulative game time. - */ - void update(); - - /** - * \brief Advance the game loop by a fixed update interval. - * - * This method progresses the game state by a consistent, fixed time step, - * allowing for stable updates independent of frame rate fluctuations. - */ - void advance_fixed_update(); + /** + * \brief Get the singleton instance of LoopTimer. + * + * \return A reference to the LoopTimer instance. + */ + static LoopTimer& get_instance(); + + /** + * \brief Get the current delta time for the current frame. + * + * \return Delta time in milliseconds since the last frame. + */ + double get_delta_time() const; + + /** + * \brief Get the current game time. + * + * \note The current game time may vary from real-world elapsed time. + * It is the cumulative sum of each frame's delta time. + * + * \return Elapsed game time in milliseconds. + */ + double get_current_time() const; + + /** + * \brief Set the target frames per second (FPS). + * + * \param fps The desired frames 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; + + /** + * \brief Start the loop timer. + * + * Initializes the timer to begin tracking frame times. + */ + void start(); + + /** + * \brief Enforce the frame rate limit. + * + * Ensures that the game loop does not exceed the target FPS by delaying + * frame updates as necessary. + */ + void enforce_frame_rate(); + + /** + * \brief Get the fixed delta time for consistent updates. + * + * Fixed delta time is used for operations that require uniform time steps, + * such as physics calculations. + * + * \return Fixed delta time in milliseconds. + */ + double get_fixed_delta_time() const; + + /** + * \brief Get the accumulated lag in the game loop. + * + * Lag represents the difference between the target frame time and the + * actual frame time, useful for managing fixed update intervals. + * + * \return Accumulated lag in milliseconds. + */ + double get_lag() const; + + /** + * \brief Construct a new LoopTimer object. + * + * Private constructor for singleton pattern to restrict instantiation + * outside the class. + */ + LoopTimer(); + + /** + * \brief Update the timer to the current frame. + * + * Calculates and updates the delta time for the current frame and adds it to + * the cumulative game time. + */ + void update(); + + /** + * \brief Advance the game loop by a fixed update interval. + * + * This method progresses the game state by a consistent, fixed time step, + * allowing for stable updates independent of frame rate fluctuations. + */ + void advance_fixed_update(); + private: - //! Current frames per second - int fps = 50; - //! Current game scale - double game_scale = 1; - //! Maximum delta time to avoid large jumps - double maximum_delta_time = 0.25; - //! Delta time for the current frame - double delta_time = 0; - //! Target time per frame in seconds - double frame_target_time = 1.0 / fps; - //! Fixed delta time for fixed updates - double fixed_delta_time = 0.02; - //! Total elapsed game time - double elapsed_time = 0; - //! Total elapsed time for fixed updates - double elapsed_fixed_time = 0; - //! Time of the last frame - uint64_t last_frame_time = 0; + //! Current frames per second + int fps = 50; + //! Current game scale + double game_scale = 1; + //! Maximum delta time in milliseconds to avoid large jumps + double maximum_delta_time = 250; + //! Delta time for the current frame in milliseconds + double delta_time = 0; + //! Target time per frame in milliseconds + double frame_target_time = 1000.0 / fps; + //! Fixed delta time for fixed updates in milliseconds + double fixed_delta_time = 20; + //! Total elapsed game time in milliseconds + double elapsed_time = 0; + //! Total elapsed time for fixed updates in milliseconds + double elapsed_fixed_time = 0; + //! Time of the last frame in milliseconds + uint64_t last_frame_time = 0; }; } // namespace crepe -- cgit v1.2.3 From e7dc31dad155b7b623374d3bb0ffbb8a8f579d2a Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 18:18:54 +0100 Subject: ran make format --- mwe/events/include/event.h | 2 +- src/crepe/api/LoopManager.cpp | 72 +++++++++++++++---------------- src/crepe/api/LoopManager.h | 9 ++-- src/crepe/api/LoopTimer.cpp | 68 +++++++++++++++-------------- src/crepe/api/LoopTimer.h | 94 ++++++++++++++++++++--------------------- src/crepe/facade/SDLContext.cpp | 4 +- src/crepe/facade/SDLContext.h | 1 + src/example/gameloop.cpp | 2 +- src/makefile | 6 +-- 9 files changed, 128 insertions(+), 130 deletions(-) diff --git a/mwe/events/include/event.h b/mwe/events/include/event.h index 16c75bf..3e70201 100644 --- a/mwe/events/include/event.h +++ b/mwe/events/include/event.h @@ -152,7 +152,7 @@ private: }; class ShutDownEvent : public Event { public: - ShutDownEvent() : Event("ShutDownEvent") {}; + ShutDownEvent() : Event("ShutDownEvent"){}; REGISTER_EVENT_TYPE(ShutDownEvent) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index d4345d0..b4382a6 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -1,66 +1,62 @@ +#include "../facade/SDLContext.h" #include "../system/RenderSystem.h" #include "../system/ScriptSystem.h" -#include "../facade/SDLContext.h" #include "LoopManager.h" #include "LoopTimer.h" using namespace crepe; -LoopManager::LoopManager(const RenderSystem& renderSystem, const SDLContext& sdlContext, - const LoopTimer& loopTimer, const ScriptSystem& scriptSystem, - const SoundSystem& soundSystem, const ParticleSystem& particleSystem, - const PhysicsSystem& physicsSystem, const AnimatorSystem& animatorSystem, - const CollisionSystem& collisionSystem) { - // Initialize systems if needed - // Example: this->renderSystem = renderSystem; +LoopManager::LoopManager( + const RenderSystem & renderSystem, const SDLContext & sdlContext, + const LoopTimer & loopTimer, const ScriptSystem & scriptSystem, + const SoundSystem & soundSystem, const ParticleSystem & particleSystem, + const PhysicsSystem & physicsSystem, const AnimatorSystem & animatorSystem, + const CollisionSystem & collisionSystem) { + // Initialize systems if needed + // Example: this->renderSystem = renderSystem; } void LoopManager::process_input() { - SDLContext::get_instance().handle_events(this->game_running); + SDLContext::get_instance().handle_events(this->game_running); } -void LoopManager::start(){ - this->setup(); - this->loop(); +void LoopManager::start() { + this->setup(); + this->loop(); } void LoopManager::set_running(bool running) { this->game_running = running; } -void LoopManager::fixed_update() { -} +void LoopManager::fixed_update() {} void LoopManager::loop() { - LoopTimer & timer = LoopTimer::get_instance(); - timer.start(); + LoopTimer & timer = LoopTimer::get_instance(); + timer.start(); - while (game_running) { - timer.update(); + while (game_running) { + timer.update(); - while (timer.get_lag() >= timer.get_fixed_delta_time()) { - this->process_input(); - this->fixed_update(); - timer.advance_fixed_update(); - } + while (timer.get_lag() >= timer.get_fixed_delta_time()) { + this->process_input(); + this->fixed_update(); + timer.advance_fixed_update(); + } - this->update(); - this->render(); + this->update(); + this->render(); - timer.enforce_frame_rate(); - } + timer.enforce_frame_rate(); + } } - void LoopManager::setup() { - this->game_running = true; - LoopTimer::get_instance().start(); - LoopTimer::get_instance().set_fps(60); + this->game_running = true; + LoopTimer::get_instance().start(); + LoopTimer::get_instance().set_fps(60); } void LoopManager::render() { - if (this->game_running) { - RenderSystem::get_instance().update(); - } -} - -void LoopManager::update() { - LoopTimer & timer = LoopTimer::get_instance(); + if (this->game_running) { + RenderSystem::get_instance().update(); + } } +void LoopManager::update() { LoopTimer & timer = LoopTimer::get_instance(); } diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 79abae6..5d8c91b 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -1,6 +1,5 @@ #pragma once - namespace crepe { class RenderSystem; @@ -16,9 +15,11 @@ class CollisionSystem; class LoopManager { public: void start(); - LoopManager(const RenderSystem&, const SDLContext&, const LoopTimer&, const ScriptSystem&, - const SoundSystem&, const ParticleSystem&, const PhysicsSystem&, const AnimatorSystem&, - const CollisionSystem&); + LoopManager(const RenderSystem &, const SDLContext &, const LoopTimer &, + const ScriptSystem &, const SoundSystem &, + const ParticleSystem &, const PhysicsSystem &, + const AnimatorSystem &, const CollisionSystem &); + private: /** * \brief Setup function for one-time initialization. diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index dd4d7e5..f68d75a 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -1,45 +1,48 @@ +#include "LoopTimer.h" #include "../facade/SDLContext.h" #include "../util/log.h" -#include "LoopTimer.h" using namespace crepe; -LoopTimer::LoopTimer() { - dbg_trace(); -} +LoopTimer::LoopTimer() { dbg_trace(); } -LoopTimer& LoopTimer::get_instance() { - static LoopTimer instance; - return instance; +LoopTimer & LoopTimer::get_instance() { + static LoopTimer instance; + return instance; } void LoopTimer::start() { - this->last_frame_time = SDLContext::get_instance().get_ticks(); - this->elapsed_time = 0; - this->elapsed_fixed_time = 0; - this->delta_time = 0; + this->last_frame_time = SDLContext::get_instance().get_ticks(); + this->elapsed_time = 0; + this->elapsed_fixed_time = 0; + this->delta_time = 0; } void LoopTimer::update() { - uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); - this->delta_time = (current_frame_time - last_frame_time); + uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); + this->delta_time = (current_frame_time - last_frame_time); - if (this->delta_time > this->maximum_delta_time) { - this->delta_time = this->maximum_delta_time; - } - this->delta_time *= this->game_scale; - this->elapsed_time += this->delta_time; - this->last_frame_time = current_frame_time; + if (this->delta_time > this->maximum_delta_time) { + this->delta_time = this->maximum_delta_time; + } + this->delta_time *= this->game_scale; + this->elapsed_time += this->delta_time; + this->last_frame_time = current_frame_time; } double LoopTimer::get_delta_time() const { return this->delta_time; } double LoopTimer::get_current_time() const { return this->elapsed_time; } -void LoopTimer::advance_fixed_update() { this->elapsed_fixed_time += this->fixed_delta_time; } -double LoopTimer::get_fixed_delta_time() const { return this->fixed_delta_time; } +void LoopTimer::advance_fixed_update() { + this->elapsed_fixed_time += this->fixed_delta_time; +} +double LoopTimer::get_fixed_delta_time() const { + return this->fixed_delta_time; +} void LoopTimer::set_fps(int fps) { - this->fps = fps; - this->frame_target_time = 1000.0 / this->fps; + this->fps = fps; + //! use fps to calculate frame_target_time in ms + this->frame_target_time = 1000.0 / this->fps; } int LoopTimer::get_fps() const { return this->fps; } @@ -47,15 +50,18 @@ void LoopTimer::set_game_scale(double value) { this->game_scale = value; } double LoopTimer::get_game_scale() const { return this->game_scale; } void LoopTimer::enforce_frame_rate() { - uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); - double frame_duration = (current_frame_time - this->last_frame_time); + uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); + double frame_duration = (current_frame_time - this->last_frame_time); - if (frame_duration < this->frame_target_time) { - uint32_t delay_time = static_cast(this->frame_target_time - frame_duration); - SDLContext::get_instance().delay(delay_time); - } + if (frame_duration < this->frame_target_time) { + uint32_t delay_time + = static_cast(this->frame_target_time - frame_duration); + SDLContext::get_instance().delay(delay_time); + } - this->last_frame_time = current_frame_time; + this->last_frame_time = current_frame_time; } -double LoopTimer::get_lag() const { return this->elapsed_time - this->elapsed_fixed_time; } +double LoopTimer::get_lag() const { + return this->elapsed_time - this->elapsed_fixed_time; +} diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index 5f9b6a7..5309d2f 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -6,21 +6,21 @@ namespace crepe { class LoopTimer { public: - /** + /** * \brief Get the singleton instance of LoopTimer. * * \return A reference to the LoopTimer instance. */ - static LoopTimer& get_instance(); + static LoopTimer & get_instance(); - /** + /** * \brief Get the current delta time for the current frame. * * \return Delta time in milliseconds since the last frame. */ - double get_delta_time() const; + double get_delta_time() const; - /** + /** * \brief Get the current game time. * * \note The current game time may vary from real-world elapsed time. @@ -28,55 +28,55 @@ public: * * \return Elapsed game time in milliseconds. */ - double get_current_time() const; + double get_current_time() const; - /** + /** * \brief Set the target frames per second (FPS). * * \param fps The desired frames rendered per second. */ - void set_fps(int fps); + void set_fps(int fps); - /** + /** * \brief Get the current frames per second (FPS). * * \return Current FPS. */ - int get_fps() const; + 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; + 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); + void set_game_scale(double game_scale); private: - friend class LoopManager; + friend class LoopManager; - /** + /** * \brief Start the loop timer. * * Initializes the timer to begin tracking frame times. */ - void start(); + void start(); - /** + /** * \brief Enforce the frame rate limit. * * Ensures that the game loop does not exceed the target FPS by delaying * frame updates as necessary. */ - void enforce_frame_rate(); + void enforce_frame_rate(); - /** + /** * \brief Get the fixed delta time for consistent updates. * * Fixed delta time is used for operations that require uniform time steps, @@ -84,9 +84,9 @@ private: * * \return Fixed delta time in milliseconds. */ - double get_fixed_delta_time() const; + double get_fixed_delta_time() const; - /** + /** * \brief Get the accumulated lag in the game loop. * * Lag represents the difference between the target frame time and the @@ -94,51 +94,51 @@ private: * * \return Accumulated lag in milliseconds. */ - double get_lag() const; + double get_lag() const; - /** + /** * \brief Construct a new LoopTimer object. * * Private constructor for singleton pattern to restrict instantiation * outside the class. */ - LoopTimer(); + LoopTimer(); - /** + /** * \brief Update the timer to the current frame. * * Calculates and updates the delta time for the current frame and adds it to * the cumulative game time. */ - void update(); + void update(); - /** + /** * \brief Advance the game loop by a fixed update interval. * * This method progresses the game state by a consistent, fixed time step, * allowing for stable updates independent of frame rate fluctuations. */ - void advance_fixed_update(); + void advance_fixed_update(); private: - //! Current frames per second - int fps = 50; - //! Current game scale - double game_scale = 1; - //! Maximum delta time in milliseconds to avoid large jumps - double maximum_delta_time = 250; - //! Delta time for the current frame in milliseconds - double delta_time = 0; - //! Target time per frame in milliseconds - double frame_target_time = 1000.0 / fps; - //! Fixed delta time for fixed updates in milliseconds - double fixed_delta_time = 20; - //! Total elapsed game time in milliseconds - double elapsed_time = 0; - //! Total elapsed time for fixed updates in milliseconds - double elapsed_fixed_time = 0; - //! Time of the last frame in milliseconds - uint64_t last_frame_time = 0; + //! Current frames per second + int fps = 50; + //! Current game scale + double game_scale = 1; + //! Maximum delta time in milliseconds to avoid large jumps + double maximum_delta_time = 250; + //! Delta time for the current frame in milliseconds + double delta_time = 0; + //! Target time per frame in milliseconds + double frame_target_time = 1000.0 / fps; + //! Fixed delta time for fixed updates in milliseconds + double fixed_delta_time = 20; + //! Total elapsed game time in milliseconds + double elapsed_time = 0; + //! Total elapsed time for fixed updates in milliseconds + double elapsed_fixed_time = 0; + //! Time of the last frame in milliseconds + uint64_t last_frame_time = 0; }; } // namespace crepe diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 17ced0c..39d0d4d 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -191,6 +191,4 @@ int SDLContext::get_height(const Texture & ctx) const { SDL_QueryTexture(ctx.texture.get(), NULL, NULL, NULL, &h); return h; } -void SDLContext::delay(int ms) const{ - SDL_Delay(ms); -} +void SDLContext::delay(int ms) const { SDL_Delay(ms); } diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 6c57ef9..90147e0 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -74,6 +74,7 @@ private: * \param ms Duration of the delay in milliseconds. */ void delay(int ms) const; + private: /** * \brief Constructs an SDLContext instance. diff --git a/src/example/gameloop.cpp b/src/example/gameloop.cpp index 6cd0301..a676f20 100644 --- a/src/example/gameloop.cpp +++ b/src/example/gameloop.cpp @@ -1,6 +1,6 @@ #include "crepe/api/LoopManager.h" using namespace crepe; -int main(){ +int main() { LoopManager gameloop; gameloop.start(); return 1; diff --git a/src/makefile b/src/makefile index ce5a29f..a2c2961 100644 --- a/src/makefile +++ b/src/makefile @@ -94,11 +94,7 @@ LOEK += example/script.cpp LOEK += test/audio.cpp LOEK += test/dummy.cpp JARO += test/PhysicsTest.cpp -WOUTER += crepe/api/LoopManager.h -WOUTER += crepe/api/LoopManager.cpp -WOUTER += crepe/api/LoopTimer.h -WOUTER += crepe/api/LoopTimer.cpp -FMT := $(WOUTER) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2 +FMT := $(JARO) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2 format: FORCE clang-tidy -p build/compile_commands.json --fix-errors $(FMT) -- cgit v1.2.3 From ec7a4af3e1cc0ebfe2c6df21f15575a1b1abbd6c Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 18:20:10 +0100 Subject: fixed some headers --- src/crepe/api/LoopManager.cpp | 1 + src/crepe/api/LoopTimer.cpp | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index b4382a6..f477efb 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -7,6 +7,7 @@ #include "LoopTimer.h" using namespace crepe; + LoopManager::LoopManager( const RenderSystem & renderSystem, const SDLContext & sdlContext, const LoopTimer & loopTimer, const ScriptSystem & scriptSystem, diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index f68d75a..16d813f 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -1,7 +1,9 @@ -#include "LoopTimer.h" + #include "../facade/SDLContext.h" #include "../util/log.h" +#include "LoopTimer.h" + using namespace crepe; LoopTimer::LoopTimer() { dbg_trace(); } -- cgit v1.2.3 From 149b3b5dbc8b18a142bf35869e54ab05e8f26d54 Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 20:21:31 +0100 Subject: added chrono::duration --- src/crepe/api/CMakeLists.txt | 4 ++ src/crepe/api/LoopManager.cpp | 9 +--- src/crepe/api/LoopManager.h | 19 ++++++-- src/crepe/api/LoopTimer.cpp | 90 ++++++++++++++++++++++-------------- src/crepe/api/LoopTimer.h | 105 +++++++++++++++++++++--------------------- src/crepe/facade/SDLContext.h | 1 + 6 files changed, 128 insertions(+), 100 deletions(-) diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 87cbb09..85696c4 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -18,6 +18,8 @@ target_sources(crepe PUBLIC Vector2.cpp Camera.cpp Animator.cpp + LoopManager.cpp + LoopTimer.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -42,4 +44,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES SceneManager.hpp Camera.h Animator.h + LoopManager.h + LoopTimer.h ) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index f477efb..ea63bf6 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -8,14 +8,7 @@ using namespace crepe; -LoopManager::LoopManager( - const RenderSystem & renderSystem, const SDLContext & sdlContext, - const LoopTimer & loopTimer, const ScriptSystem & scriptSystem, - const SoundSystem & soundSystem, const ParticleSystem & particleSystem, - const PhysicsSystem & physicsSystem, const AnimatorSystem & animatorSystem, - const CollisionSystem & collisionSystem) { - // Initialize systems if needed - // Example: this->renderSystem = renderSystem; +LoopManager::LoopManager() { } void LoopManager::process_input() { SDLContext::get_instance().handle_events(this->game_running); diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 5d8c91b..d4668b8 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -1,6 +1,6 @@ #pragma once -namespace crepe { +#include class RenderSystem; class SDLContext; @@ -11,14 +11,14 @@ class ParticleSystem; class PhysicsSystem; class AnimatorSystem; class CollisionSystem; +namespace crepe { + + class LoopManager { public: void start(); - LoopManager(const RenderSystem &, const SDLContext &, const LoopTimer &, - const ScriptSystem &, const SoundSystem &, - const ParticleSystem &, const PhysicsSystem &, - const AnimatorSystem &, const CollisionSystem &); + LoopManager(); private: /** @@ -75,6 +75,15 @@ private: void render(); bool game_running = false; + // For later if singletons are removed cant make them now because destructors are private. + // std::unique_ptr render_system; + // std::unique_ptr sdl_context; + // std::unique_ptr loop_timer; + // std::unique_ptr script_system; + // std::unique_ptr particle_system; + // std::unique_ptr physics_system; + // std::unique_ptr animator_system; + // std::unique_ptr collision_system; }; } // namespace crepe diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index 16d813f..039e35e 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -1,3 +1,4 @@ +#include #include "../facade/SDLContext.h" #include "../util/log.h" @@ -6,64 +7,83 @@ using namespace crepe; -LoopTimer::LoopTimer() { dbg_trace(); } +LoopTimer::LoopTimer() { + dbg_trace(); +} LoopTimer & LoopTimer::get_instance() { - static LoopTimer instance; - return instance; + static LoopTimer instance; + return instance; } void LoopTimer::start() { - this->last_frame_time = SDLContext::get_instance().get_ticks(); - this->elapsed_time = 0; - this->elapsed_fixed_time = 0; - this->delta_time = 0; + this->last_frame_time = std::chrono::steady_clock::now(); + this->elapsed_time = std::chrono::milliseconds(0); + this->elapsed_fixed_time = std::chrono::milliseconds(0); + this->delta_time = std::chrono::milliseconds(0); } void LoopTimer::update() { - uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); - this->delta_time = (current_frame_time - last_frame_time); - - if (this->delta_time > this->maximum_delta_time) { - this->delta_time = this->maximum_delta_time; - } - this->delta_time *= this->game_scale; - this->elapsed_time += this->delta_time; - this->last_frame_time = current_frame_time; + auto current_frame_time = std::chrono::steady_clock::now(); + // Convert to duration in seconds for delta time + this->delta_time = std::chrono::duration_cast>(current_frame_time - last_frame_time); + + if (this->delta_time > this->maximum_delta_time) { + this->delta_time = this->maximum_delta_time; + } + + this->delta_time *= this->game_scale; + this->elapsed_time += this->delta_time; + this->last_frame_time = current_frame_time; +} + +double LoopTimer::get_delta_time() const { + return this->delta_time.count(); +} + +double LoopTimer::get_current_time() const { + return this->elapsed_time.count(); } -double LoopTimer::get_delta_time() const { return this->delta_time; } -double LoopTimer::get_current_time() const { return this->elapsed_time; } void LoopTimer::advance_fixed_update() { - this->elapsed_fixed_time += this->fixed_delta_time; + this->elapsed_fixed_time += this->fixed_delta_time; } + double LoopTimer::get_fixed_delta_time() const { - return this->fixed_delta_time; + return this->fixed_delta_time.count(); } void LoopTimer::set_fps(int fps) { - this->fps = fps; - //! use fps to calculate frame_target_time in ms - this->frame_target_time = 1000.0 / this->fps; + this->fps = fps; + // target time per frame in seconds + this->frame_target_time = std::chrono::seconds(1) / fps; +} + +int LoopTimer::get_fps() const { + return this->fps; } -int LoopTimer::get_fps() const { return this->fps; } -void LoopTimer::set_game_scale(double value) { this->game_scale = value; } -double LoopTimer::get_game_scale() const { return this->game_scale; } +void LoopTimer::set_game_scale(double value) { + this->game_scale = value; +} +double LoopTimer::get_game_scale() const { + return this->game_scale; +} void LoopTimer::enforce_frame_rate() { - uint64_t current_frame_time = SDLContext::get_instance().get_ticks(); - double frame_duration = (current_frame_time - this->last_frame_time); + std::chrono::steady_clock::time_point current_frame_time = std::chrono::steady_clock::now(); + std::chrono::milliseconds frame_duration = std::chrono::duration_cast(current_frame_time - this->last_frame_time); - if (frame_duration < this->frame_target_time) { - uint32_t delay_time - = static_cast(this->frame_target_time - frame_duration); - SDLContext::get_instance().delay(delay_time); - } + if (frame_duration < this->frame_target_time) { + std::chrono::milliseconds delay_time = std::chrono::duration_cast(this->frame_target_time - frame_duration); + if (delay_time.count() > 0) { + SDLContext::get_instance().delay(delay_time.count()); + } + } - this->last_frame_time = current_frame_time; + this->last_frame_time = current_frame_time; } double LoopTimer::get_lag() const { - return this->elapsed_time - this->elapsed_fixed_time; + return (this->elapsed_time - this->elapsed_fixed_time).count(); } diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index 5309d2f..ec48e4a 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -1,144 +1,145 @@ -#pragma once + #pragma once #include +#include namespace crepe { class LoopTimer { public: - /** + /** * \brief Get the singleton instance of LoopTimer. * * \return A reference to the LoopTimer instance. */ - static LoopTimer & get_instance(); + static LoopTimer& get_instance(); - /** + /** * \brief Get the current delta time for the current frame. * - * \return Delta time in milliseconds since the last frame. + * \return Delta time in seconds since the last frame. */ - double get_delta_time() const; + double get_delta_time() const; - /** + /** * \brief Get the current game time. * * \note The current game time may vary from real-world elapsed time. * It is the cumulative sum of each frame's delta time. * - * \return Elapsed game time in milliseconds. + * \return Elapsed game time in seconds. */ - double get_current_time() const; + double get_current_time() const; - /** + /** * \brief Set the target frames per second (FPS). * * \param fps The desired frames rendered per second. */ - void set_fps(int fps); + void set_fps(int fps); - /** + /** * \brief Get the current frames per second (FPS). * * \return Current FPS. */ - int get_fps() const; + 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; + 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); + void set_game_scale(double game_scale); private: - friend class LoopManager; + friend class LoopManager; - /** + /** * \brief Start the loop timer. * * Initializes the timer to begin tracking frame times. */ - void start(); + void start(); - /** + /** * \brief Enforce the frame rate limit. * * Ensures that the game loop does not exceed the target FPS by delaying * frame updates as necessary. */ - void enforce_frame_rate(); + void enforce_frame_rate(); - /** + /** * \brief Get the fixed delta time for consistent updates. * * Fixed delta time is used for operations that require uniform time steps, * such as physics calculations. * - * \return Fixed delta time in milliseconds. + * \return Fixed delta time in seconds. */ - double get_fixed_delta_time() const; + double get_fixed_delta_time() const; - /** + /** * \brief Get the accumulated lag in the game loop. * * Lag represents the difference between the target frame time and the * actual frame time, useful for managing fixed update intervals. * - * \return Accumulated lag in milliseconds. + * \return Accumulated lag in seconds. */ - double get_lag() const; + double get_lag() const; - /** + /** * \brief Construct a new LoopTimer object. * * Private constructor for singleton pattern to restrict instantiation * outside the class. */ - LoopTimer(); + LoopTimer(); - /** + /** * \brief Update the timer to the current frame. * * Calculates and updates the delta time for the current frame and adds it to * the cumulative game time. */ - void update(); + void update(); - /** + /** * \brief Advance the game loop by a fixed update interval. * * This method progresses the game state by a consistent, fixed time step, * allowing for stable updates independent of frame rate fluctuations. */ - void advance_fixed_update(); + void advance_fixed_update(); private: - //! Current frames per second - int fps = 50; - //! Current game scale - double game_scale = 1; - //! Maximum delta time in milliseconds to avoid large jumps - double maximum_delta_time = 250; - //! Delta time for the current frame in milliseconds - double delta_time = 0; - //! Target time per frame in milliseconds - double frame_target_time = 1000.0 / fps; - //! Fixed delta time for fixed updates in milliseconds - double fixed_delta_time = 20; - //! Total elapsed game time in milliseconds - double elapsed_time = 0; - //! Total elapsed time for fixed updates in milliseconds - double elapsed_fixed_time = 0; - //! Time of the last frame in milliseconds - uint64_t last_frame_time = 0; + //! Current frames per second + int fps = 50; + //! Current game scale + double game_scale = 1; + //! Maximum delta time in seconds to avoid large jumps + std::chrono::duration maximum_delta_time{0.25}; + //! Delta time for the current frame in seconds + std::chrono::duration delta_time{0.0}; + //! Target time per frame in seconds + std::chrono::duration frame_target_time = std::chrono::seconds(1) / fps; + //! Fixed delta time for fixed updates in seconds + std::chrono::duration fixed_delta_time = std::chrono::seconds(1) / 50; + //! Total elapsed game time in seconds + std::chrono::duration elapsed_time{0.0}; + //! Total elapsed time for fixed updates in seconds + std::chrono::duration elapsed_fixed_time{0.0}; + //! Time of the last frame + std::chrono::steady_clock::time_point last_frame_time; }; } // namespace crepe diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 90147e0..b51fdd5 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -58,6 +58,7 @@ private: private: //! Will only use get_ticks friend class AnimatorSystem; + //! Will use the funtions: get_ticks, delay friend class LoopTimer; /** * \brief Gets the current SDL ticks since the program started. -- cgit v1.2.3 From 4f5597885ce6af93ca4655c193982aa701afb8cf Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Mon, 11 Nov 2024 20:28:29 +0100 Subject: git format --- src/crepe/api/LoopManager.cpp | 3 +- src/crepe/api/LoopManager.h | 18 ++++---- src/crepe/api/LoopTimer.cpp | 95 +++++++++++++++++++-------------------- src/crepe/api/LoopTimer.h | 100 +++++++++++++++++++++--------------------- 4 files changed, 106 insertions(+), 110 deletions(-) diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index ea63bf6..2e9823f 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -8,8 +8,7 @@ using namespace crepe; -LoopManager::LoopManager() { -} +LoopManager::LoopManager() {} void LoopManager::process_input() { SDLContext::get_instance().handle_events(this->game_running); } diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index d4668b8..755e2d2 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -13,8 +13,6 @@ class AnimatorSystem; class CollisionSystem; namespace crepe { - - class LoopManager { public: void start(); @@ -76,14 +74,14 @@ private: bool game_running = false; // For later if singletons are removed cant make them now because destructors are private. - // std::unique_ptr render_system; - // std::unique_ptr sdl_context; - // std::unique_ptr loop_timer; - // std::unique_ptr script_system; - // std::unique_ptr particle_system; - // std::unique_ptr physics_system; - // std::unique_ptr animator_system; - // std::unique_ptr collision_system; + // std::unique_ptr render_system; + // std::unique_ptr sdl_context; + // std::unique_ptr loop_timer; + // std::unique_ptr script_system; + // std::unique_ptr particle_system; + // std::unique_ptr physics_system; + // std::unique_ptr animator_system; + // std::unique_ptr collision_system; }; } // namespace crepe diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp index 039e35e..8f09e41 100644 --- a/src/crepe/api/LoopTimer.cpp +++ b/src/crepe/api/LoopTimer.cpp @@ -7,83 +7,80 @@ using namespace crepe; -LoopTimer::LoopTimer() { - dbg_trace(); -} +LoopTimer::LoopTimer() { dbg_trace(); } LoopTimer & LoopTimer::get_instance() { - static LoopTimer instance; - return instance; + static LoopTimer instance; + return instance; } void LoopTimer::start() { - this->last_frame_time = std::chrono::steady_clock::now(); - this->elapsed_time = std::chrono::milliseconds(0); - this->elapsed_fixed_time = std::chrono::milliseconds(0); - this->delta_time = std::chrono::milliseconds(0); + this->last_frame_time = std::chrono::steady_clock::now(); + this->elapsed_time = std::chrono::milliseconds(0); + this->elapsed_fixed_time = std::chrono::milliseconds(0); + this->delta_time = std::chrono::milliseconds(0); } void LoopTimer::update() { - auto current_frame_time = std::chrono::steady_clock::now(); - // Convert to duration in seconds for delta time - this->delta_time = std::chrono::duration_cast>(current_frame_time - last_frame_time); - - if (this->delta_time > this->maximum_delta_time) { - this->delta_time = this->maximum_delta_time; - } - - this->delta_time *= this->game_scale; - this->elapsed_time += this->delta_time; - this->last_frame_time = current_frame_time; + auto current_frame_time = std::chrono::steady_clock::now(); + // Convert to duration in seconds for delta time + this->delta_time + = std::chrono::duration_cast>( + current_frame_time - last_frame_time); + + if (this->delta_time > this->maximum_delta_time) { + this->delta_time = this->maximum_delta_time; + } + + this->delta_time *= this->game_scale; + this->elapsed_time += this->delta_time; + this->last_frame_time = current_frame_time; } -double LoopTimer::get_delta_time() const { - return this->delta_time.count(); -} +double LoopTimer::get_delta_time() const { return this->delta_time.count(); } double LoopTimer::get_current_time() const { - return this->elapsed_time.count(); + return this->elapsed_time.count(); } void LoopTimer::advance_fixed_update() { - this->elapsed_fixed_time += this->fixed_delta_time; + this->elapsed_fixed_time += this->fixed_delta_time; } double LoopTimer::get_fixed_delta_time() const { - return this->fixed_delta_time.count(); + return this->fixed_delta_time.count(); } void LoopTimer::set_fps(int fps) { - this->fps = fps; + this->fps = fps; // target time per frame in seconds - this->frame_target_time = std::chrono::seconds(1) / fps; + this->frame_target_time = std::chrono::seconds(1) / fps; } -int LoopTimer::get_fps() const { - return this->fps; -} +int LoopTimer::get_fps() const { return this->fps; } -void LoopTimer::set_game_scale(double value) { - this->game_scale = value; -} +void LoopTimer::set_game_scale(double value) { this->game_scale = value; } -double LoopTimer::get_game_scale() const { - return this->game_scale; -} +double LoopTimer::get_game_scale() const { return this->game_scale; } void LoopTimer::enforce_frame_rate() { - std::chrono::steady_clock::time_point current_frame_time = std::chrono::steady_clock::now(); - std::chrono::milliseconds frame_duration = std::chrono::duration_cast(current_frame_time - this->last_frame_time); - - if (frame_duration < this->frame_target_time) { - std::chrono::milliseconds delay_time = std::chrono::duration_cast(this->frame_target_time - frame_duration); - if (delay_time.count() > 0) { - SDLContext::get_instance().delay(delay_time.count()); - } - } - - this->last_frame_time = current_frame_time; + std::chrono::steady_clock::time_point current_frame_time + = std::chrono::steady_clock::now(); + std::chrono::milliseconds frame_duration + = std::chrono::duration_cast( + current_frame_time - this->last_frame_time); + + if (frame_duration < this->frame_target_time) { + std::chrono::milliseconds delay_time + = std::chrono::duration_cast( + this->frame_target_time - frame_duration); + if (delay_time.count() > 0) { + SDLContext::get_instance().delay(delay_time.count()); + } + } + + this->last_frame_time = current_frame_time; } double LoopTimer::get_lag() const { - return (this->elapsed_time - this->elapsed_fixed_time).count(); + return (this->elapsed_time - this->elapsed_fixed_time).count(); } diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h index ec48e4a..85687be 100644 --- a/src/crepe/api/LoopTimer.h +++ b/src/crepe/api/LoopTimer.h @@ -1,27 +1,27 @@ - #pragma once +#pragma once -#include #include +#include namespace crepe { class LoopTimer { public: - /** + /** * \brief Get the singleton instance of LoopTimer. * * \return A reference to the LoopTimer instance. */ - static LoopTimer& get_instance(); + static LoopTimer & get_instance(); - /** + /** * \brief Get the current delta time for the current frame. * * \return Delta time in seconds since the last frame. */ - double get_delta_time() const; + double get_delta_time() const; - /** + /** * \brief Get the current game time. * * \note The current game time may vary from real-world elapsed time. @@ -29,55 +29,55 @@ public: * * \return Elapsed game time in seconds. */ - double get_current_time() const; + double get_current_time() const; - /** + /** * \brief Set the target frames per second (FPS). * * \param fps The desired frames rendered per second. */ - void set_fps(int fps); + void set_fps(int fps); - /** + /** * \brief Get the current frames per second (FPS). * * \return Current FPS. */ - int get_fps() const; + 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; + 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); + void set_game_scale(double game_scale); private: - friend class LoopManager; + friend class LoopManager; - /** + /** * \brief Start the loop timer. * * Initializes the timer to begin tracking frame times. */ - void start(); + void start(); - /** + /** * \brief Enforce the frame rate limit. * * Ensures that the game loop does not exceed the target FPS by delaying * frame updates as necessary. */ - void enforce_frame_rate(); + void enforce_frame_rate(); - /** + /** * \brief Get the fixed delta time for consistent updates. * * Fixed delta time is used for operations that require uniform time steps, @@ -85,9 +85,9 @@ private: * * \return Fixed delta time in seconds. */ - double get_fixed_delta_time() const; + double get_fixed_delta_time() const; - /** + /** * \brief Get the accumulated lag in the game loop. * * Lag represents the difference between the target frame time and the @@ -95,51 +95,53 @@ private: * * \return Accumulated lag in seconds. */ - double get_lag() const; + double get_lag() const; - /** + /** * \brief Construct a new LoopTimer object. * * Private constructor for singleton pattern to restrict instantiation * outside the class. */ - LoopTimer(); + LoopTimer(); - /** + /** * \brief Update the timer to the current frame. * * Calculates and updates the delta time for the current frame and adds it to * the cumulative game time. */ - void update(); + void update(); - /** + /** * \brief Advance the game loop by a fixed update interval. * * This method progresses the game state by a consistent, fixed time step, * allowing for stable updates independent of frame rate fluctuations. */ - void advance_fixed_update(); + void advance_fixed_update(); private: - //! Current frames per second - int fps = 50; - //! Current game scale - double game_scale = 1; - //! Maximum delta time in seconds to avoid large jumps - std::chrono::duration maximum_delta_time{0.25}; - //! Delta time for the current frame in seconds - std::chrono::duration delta_time{0.0}; - //! Target time per frame in seconds - std::chrono::duration frame_target_time = std::chrono::seconds(1) / fps; - //! Fixed delta time for fixed updates in seconds - std::chrono::duration fixed_delta_time = std::chrono::seconds(1) / 50; - //! Total elapsed game time in seconds - std::chrono::duration elapsed_time{0.0}; - //! Total elapsed time for fixed updates in seconds - std::chrono::duration elapsed_fixed_time{0.0}; - //! Time of the last frame - std::chrono::steady_clock::time_point last_frame_time; + //! Current frames per second + int fps = 50; + //! Current game scale + double game_scale = 1; + //! Maximum delta time in seconds to avoid large jumps + std::chrono::duration maximum_delta_time{0.25}; + //! Delta time for the current frame in seconds + std::chrono::duration delta_time{0.0}; + //! Target time per frame in seconds + std::chrono::duration frame_target_time + = std::chrono::seconds(1) / fps; + //! Fixed delta time for fixed updates in seconds + std::chrono::duration fixed_delta_time + = std::chrono::seconds(1) / 50; + //! Total elapsed game time in seconds + std::chrono::duration elapsed_time{0.0}; + //! Total elapsed time for fixed updates in seconds + std::chrono::duration elapsed_fixed_time{0.0}; + //! Time of the last frame + std::chrono::steady_clock::time_point last_frame_time; }; } // namespace crepe -- cgit v1.2.3 From 113e2d299d22921212a793eb7cd55afbd49ba22e Mon Sep 17 00:00:00 2001 From: WBoerenkamps Date: Tue, 12 Nov 2024 15:13:19 +0100 Subject: changed doxygen comment of friend class --- src/crepe/api/LoopManager.h | 10 +--------- src/crepe/facade/SDLContext.h | 2 +- src/makefile | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 755e2d2..2f03193 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -73,15 +73,7 @@ private: void render(); bool game_running = false; - // For later if singletons are removed cant make them now because destructors are private. - // std::unique_ptr render_system; - // std::unique_ptr sdl_context; - // std::unique_ptr loop_timer; - // std::unique_ptr script_system; - // std::unique_ptr particle_system; - // std::unique_ptr physics_system; - // std::unique_ptr animator_system; - // std::unique_ptr collision_system; + //#TODO add system instances }; } // namespace crepe diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index b51fdd5..536dec5 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -58,7 +58,7 @@ private: private: //! Will only use get_ticks friend class AnimatorSystem; - //! Will use the funtions: get_ticks, delay + //! Will only use delay friend class LoopTimer; /** * \brief Gets the current SDL ticks since the program started. diff --git a/src/makefile b/src/makefile index a2c2961..bd05b2e 100644 --- a/src/makefile +++ b/src/makefile @@ -94,10 +94,10 @@ LOEK += example/script.cpp LOEK += test/audio.cpp LOEK += test/dummy.cpp JARO += test/PhysicsTest.cpp -FMT := $(JARO) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2 +FMT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') format: FORCE clang-tidy -p build/compile_commands.json --fix-errors $(FMT) -# FMT += $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') +# FMT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp') # TODO: re-enable linter after all corrections -- cgit v1.2.3