diff options
author | heavydemon21 <nielsstunnebrink1@gmail.com> | 2024-11-08 11:44:21 +0100 |
---|---|---|
committer | heavydemon21 <nielsstunnebrink1@gmail.com> | 2024-11-08 11:44:21 +0100 |
commit | 9432900158e6a31815345fcf0af8d28ae34c6da9 (patch) | |
tree | 36f799da46ba8f5e921349d0f004b08d6d2f29ea /src | |
parent | 1c4156ee127b14760ed3b1a0cd16ad12180c7ac6 (diff) |
code style
Diffstat (limited to 'src')
-rwxr-xr-x | src/compile.sh | 17 | ||||
-rw-r--r-- | src/crepe/api/Animator.cpp | 23 | ||||
-rw-r--r-- | src/crepe/api/Animator.h | 87 | ||||
-rw-r--r-- | src/crepe/api/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/crepe/api/Camera.cpp | 15 | ||||
-rw-r--r-- | src/crepe/api/Camera.h | 70 | ||||
-rw-r--r-- | src/crepe/api/Color.cpp | 3 | ||||
-rw-r--r-- | src/crepe/api/Color.h | 17 | ||||
-rw-r--r-- | src/crepe/api/Sprite.cpp | 4 | ||||
-rw-r--r-- | src/crepe/api/Sprite.h | 75 | ||||
-rw-r--r-- | src/crepe/api/Texture.cpp | 17 | ||||
-rw-r--r-- | src/crepe/api/Texture.h | 60 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 144 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 126 | ||||
-rw-r--r-- | src/crepe/system/AnimatorSystem.cpp | 39 | ||||
-rw-r--r-- | src/crepe/system/AnimatorSystem.h | 53 | ||||
-rw-r--r-- | src/crepe/system/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/crepe/system/RenderSystem.cpp | 35 | ||||
-rw-r--r-- | src/crepe/system/RenderSystem.h | 69 |
19 files changed, 759 insertions, 101 deletions
diff --git a/src/compile.sh b/src/compile.sh new file mode 100755 index 0000000..844f2d9 --- /dev/null +++ b/src/compile.sh @@ -0,0 +1,17 @@ + + + +cmake -B build -G Ninja + +ninja -C build + +#ninja -C build viewport + +#ninja -C build rendering + +#ninja -C build events + +#ninja -C build camera + +#ninja -C build animator + diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp new file mode 100644 index 0000000..3834e0b --- /dev/null +++ b/src/crepe/api/Animator.cpp @@ -0,0 +1,23 @@ + + +#include "Animator.h" +#include "Component.h" +#include "api/Sprite.h" + +#include "util/log.h" +#include <cstdint> + +using namespace crepe; + +Animator::Animator(uint32_t id, Sprite & ss, int row, int col, int col_animator) + : Component(id), spritesheet(ss), row(row), col(col){ + dbg_trace(); + + animator_rect = spritesheet.sprite_rect; + animator_rect.h /= col; + animator_rect.w /= row; + animator_rect.x = 0; + animator_rect.y = col_animator * animator_rect.h; + this->active = false; +} +Animator::~Animator() { dbg_trace(); } diff --git a/src/crepe/api/Animator.h b/src/crepe/api/Animator.h new file mode 100644 index 0000000..3493623 --- /dev/null +++ b/src/crepe/api/Animator.h @@ -0,0 +1,87 @@ +#pragma once + +#include "Component.h" +#include "api/Sprite.h" +#include <cstdint> + +namespace crepe { +class AnimatorSystem; +class SDLContext; + + +/** + * \brief The Animator component is used to animate sprites by managing the movement + * and frame changes within a sprite sheet. + * + * This component allows for controlling sprite animation through rows and columns of a sprite sheet. + * It can be used to play animations, loop them, or stop them. + */ +class Animator : public Component { + +public: + //TODO: need to implement this + void loop(); + void stop(); + +public: + /** + * \brief Constructs an Animator object that will control animations for a sprite sheet. + * + * \param[in] id The unique identifier for the component, typically assigned automatically. + * \param[in] spritesheet A reference to the Sprite object which holds the sprite sheet for animation. + * \param[in] row The maximum number of rows in the sprite sheet. + * \param[in] col The maximum number of columns in the sprite sheet. + * \param[in] col__animate The specific col index of the sprite sheet to animate. This allows selecting which col to animate from multiple col in the sheet. + * + * This constructor sets up the Animator with the given parameters, and initializes the animation system. + */ + Animator(uint32_t id, Sprite & spritesheet, int row, int col, + int col_animate); + + /** + * \brief Destroys the Animator object and cleans up any resources. + * + * This destructor will handle any necessary cleanup when the Animator component is no longer needed. + */ + ~Animator(); + + //! Deleted copy constructor to prevent copying of the Animator instance. + Animator(const Animator &) = delete; + + //! Deleted move constructor to prevent moving of the Animator instance. + Animator(Animator &&) = delete; + + //! Deleted copy assignment operator to prevent copying the Animator instance. + Animator & operator=(const Animator &) = delete; + + //! Deleted move assignment operator to prevent moving the Animator instance. + Animator & operator=(Animator &&) = delete; + +private: + //! A reference to the Sprite sheet containing the animation frames. + Sprite & spritesheet; + + //! The maximum number of columns in the sprite sheet. + const int col; + + //! The maximum number of rows in the sprite sheet. + const int row; + + //! The current col being animated. + int curr_col = 0; + + //! The current row being animated. + int curr_row = 0; + + Rect animator_rect; + + //TODO: Is this necessary? + //int fps; + +private: + //! Friend class that can directly access the private members of the Animator. + friend class AnimatorSystem; + friend class SDLContext; +}; +} // namespace crepe +// diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 3b20142..87cbb09 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 + Camera.cpp + Animator.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 + Camera.h + Animator.h ) diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp new file mode 100644 index 0000000..46a56b2 --- /dev/null +++ b/src/crepe/api/Camera.cpp @@ -0,0 +1,15 @@ + + +#include "Camera.h" +#include "Component.h" +#include "api/Color.h" +#include "util/log.h" +#include <cstdint> + +using namespace crepe; + +Camera::Camera(uint32_t id, const Color& color) : Component(id), bg_color(color), aspect_width(640), aspect_height(480), zoom(1), x(0),y(0){ + dbg_trace(); +} + +Camera::~Camera() { dbg_trace(); } diff --git a/src/crepe/api/Camera.h b/src/crepe/api/Camera.h new file mode 100644 index 0000000..022496d --- /dev/null +++ b/src/crepe/api/Camera.h @@ -0,0 +1,70 @@ +#pragma once + +#include "Component.h" +#include "api/Color.h" +#include <cstdint> + +namespace crepe { + +/** + * \class Camera + * \brief Represents a camera component for rendering in the game. + * + * The Camera class defines the view parameters, including background color, + * aspect ratio, position, and zoom level. It controls what part of the game + * world is visible on the screen. + */ +class Camera : public Component { + +public: + /** + * \brief Constructs a Camera with the specified ID and background color. + * \param id Unique identifier for the camera component. + * \param bg_color Background color for the camera view. + */ + Camera(uint32_t id, const Color & bg_color); + + /** + * \brief Destroys the Camera instance. + */ + ~Camera(); + +public: + /** + * \brief Background color of the camera view. + */ + Color bg_color; + + /** + * \brief Aspect ratio height for the camera. + */ + double aspect_height; + + /** + * \brief Aspect ratio width for the camera. + */ + double aspect_width; + + /** + * \brief X-coordinate of the camera position. + */ + double x; + + /** + * \brief Y-coordinate of the camera position. + */ + double y; + + /** + * \brief Zoom level of the camera view. + */ + double zoom; + +public: + /** + * \brief Gets the maximum number of camera instances allowed. + * \return Maximum instance count as an integer. + */ + virtual int get_instances_max() const { return 10; } +}; +} // namespace crepe diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp index fc6313d..9e5f187 100644 --- a/src/crepe/api/Color.cpp +++ b/src/crepe/api/Color.cpp @@ -11,8 +11,7 @@ Color Color::cyan = Color(0, 255, 255, 0); Color Color::yellow = Color(255, 255, 0, 0); Color Color::magenta = Color(255, 0, 255, 0); -// FIXME: do we really need double precision for color values? -Color::Color(double red, double green, double blue, double alpha) { +Color::Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha) { this->a = alpha; this->r = red; this->g = green; diff --git a/src/crepe/api/Color.h b/src/crepe/api/Color.h index 6b54888..4ebe3a3 100644 --- a/src/crepe/api/Color.h +++ b/src/crepe/api/Color.h @@ -1,6 +1,8 @@ #pragma once -namespace crepe { +#include <cstdint> + +namespace crepe{ class Color { @@ -8,7 +10,7 @@ class Color { // instead? public: - Color(double red, double green, double blue, double alpha); + Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha); static const Color & get_white(); static const Color & get_red(); static const Color & get_green(); @@ -19,10 +21,10 @@ public: static const Color & get_black(); private: - double r; - double g; - double b; - double a; + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t a; static Color white; static Color red; @@ -32,6 +34,9 @@ private: static Color magenta; static Color yellow; static Color black; + +private: + friend class SDLContext; }; } // namespace crepe diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp index d3465c7..3db8f2b 100644 --- a/src/crepe/api/Sprite.cpp +++ b/src/crepe/api/Sprite.cpp @@ -6,6 +6,7 @@ #include "Component.h" #include "Sprite.h" #include "Texture.h" +#include "facade/SDLContext.h" using namespace std; using namespace crepe; @@ -14,6 +15,9 @@ Sprite::Sprite(game_object_id_t id, shared_ptr<Texture> image, const Color & color, const FlipSettings & flip) : Component(id), color(color), flip(flip), sprite_image(image) { dbg_trace(); + + this->sprite_rect.w = sprite_image->get_width(); + this->sprite_rect.h = sprite_image->get_height(); } Sprite::~Sprite() { dbg_trace(); } diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h index 00dcb27..2e8b52a 100644 --- a/src/crepe/api/Sprite.h +++ b/src/crepe/api/Sprite.h @@ -1,6 +1,5 @@ #pragma once -#include <SDL2/SDL_rect.h> #include <cstdint> #include <memory> @@ -11,22 +10,92 @@ namespace crepe { +/** + * \struct Rect + * \brief Represents a rectangle area for rendering. + * + * Everything within the defined rectangle will be rendered. + * The SDLContext will translate this into the library's rectangle structure. + */ +struct Rect { + int w = 0; + int h = 0; + int x = 0; + int y = 0; +}; + +/** + * \struct FlipSettings + * \brief Flip settings for the sprite. + * + * Defines the horizontal and vertical flip settings for a sprite, which the + * SDLContext will translate into the corresponding settings for the library. + */ struct FlipSettings { - bool flip_x = true; - bool flip_y = true; + bool flip_x = false; + bool flip_y = false; }; +//! Forward declaration of the SDLContext facade. +class SDLContext; + +//! Forward declaration of the Animator class. +class Animator; + +//! Forward declaration of the AnimatorSystem class. +class AnimatorSystem; + +/** + * \class Sprite + * \brief Represents a renderable sprite component. + * + * A renderable sprite that can be displayed in the game. It includes a texture, + * color, and flip settings, and is managed in layers with defined sorting orders. + */ class Sprite : public Component { public: + /** + * \brief Constructs a Sprite with specified parameters. + * \param game_id Unique identifier for the game object this sprite belongs to. + * \param image Shared pointer to the texture for this sprite. + * \param color Color tint applied to the sprite. + * \param flip Flip settings for horizontal and vertical orientation. + */ Sprite(game_object_id_t id, std::shared_ptr<Texture> image, const Color & color, const FlipSettings & flip); + + /** + * \brief Destroys the Sprite instance. + */ ~Sprite(); + + + //! Texture used for the sprite std::shared_ptr<Texture> sprite_image; + //! Color tint of the sprite Color color; + //! Flip settings for the sprite FlipSettings flip; + //! Layer sorting level of the sprite uint8_t sorting_in_layer; + //! Order within the sorting layer uint8_t order_in_layer; + +public: + /** + * \brief Gets the maximum number of instances allowed for this sprite. + * \return Maximum instance count as an integer. + */ + virtual int get_instances_max() const { return 10; } + +private: + friend class SDLContext; + friend class Animator; + friend class AnimatorSystem; + + //! Render area of the sprite + Rect sprite_rect; }; } // namespace crepe diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp index 8fc5c13..5519e5e 100644 --- a/src/crepe/api/Texture.cpp +++ b/src/crepe/api/Texture.cpp @@ -30,3 +30,20 @@ void Texture::load(unique_ptr<Asset> res) { SDLContext & ctx = SDLContext::get_instance(); this->texture = ctx.texture_from_path(res->canonical()); } + +int Texture::get_width() const{ + if (this->texture) { + return SDLContext::get_instance().get_width(*this); + } + else { + return 0; + } +} +int Texture::get_height() const{ + if (this->texture) { + return SDLContext::get_instance().get_height(*this); + } + else { + return 0; + } +} diff --git a/src/crepe/api/Texture.h b/src/crepe/api/Texture.h index 9a86f6f..6d99a93 100644 --- a/src/crepe/api/Texture.h +++ b/src/crepe/api/Texture.h @@ -3,31 +3,75 @@ // FIXME: this header can't be included because this is an API header, and SDL2 // development headers won't be bundled with crepe. Why is this facade in the // API namespace? + #include <SDL2/SDL_render.h> #include <memory> #include "Asset.h" namespace crepe { + +//! Forward declaration of SDLContext class. class SDLContext; -} -namespace crepe { +//! Forward declaration of Animator class. +class Animator; +/** + * \class Texture + * \brief Manages texture loading and properties. + * + * The Texture class is responsible for loading an image from a source + * and providing access to its dimensions. Textures can be used for rendering. + */ class Texture { public: - Texture(const char * src); - Texture(std::unique_ptr<Asset> res); - ~Texture(); + /** + * \brief Constructs a Texture from a file path. + * \param src Path to the image file to be loaded as a texture. + */ + Texture(const char * src); + + /** + * \brief Constructs a Texture from an Asset resource. + * \param res Unique pointer to an Asset resource containing texture data. + */ + Texture(std::unique_ptr<Asset> res); + + /** + * \brief Destroys the Texture instance, freeing associated resources. + */ + ~Texture(); + + /** + * \brief Gets the width of the texture. + * \return Width of the texture in pixels. + */ + int get_width() const; + + /** + * \brief Gets the height of the texture. + * \return Height of the texture in pixels. + */ + int get_height() const; private: - void load(std::unique_ptr<Asset> res); + /** + * \brief Loads the texture from an Asset resource. + * \param res Unique pointer to an Asset resource to load the texture from. + */ + void load(std::unique_ptr<Asset> res); private: - SDL_Texture * texture = nullptr; + //! The texture of the class from the library + SDL_Texture * texture = nullptr; + + //! Grants SDLContext access to private members. + friend class SDLContext; - friend class crepe::SDLContext; + //! Grants Animator access to private members. + friend class Animator; }; } // namespace crepe diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 8da93e9..bbeb3a9 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -1,5 +1,6 @@ #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> +#include <SDL2/SDL_rect.h> #include <SDL2/SDL_render.h> #include <SDL2/SDL_surface.h> #include <SDL2/SDL_video.h> @@ -21,34 +22,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 @@ -62,7 +35,7 @@ SDLContext::SDLContext() { this->game_window = SDL_CreateWindow( "Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - 1920, 1080, SDL_WINDOW_SHOWN); + this->viewport.w, this->viewport.h, 0); if (!this->game_window) { // FIXME: throw exception std::cerr << "Window could not be created! SDL_Error: " @@ -87,55 +60,92 @@ SDLContext::SDLContext() { } } +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::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); } void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer); } -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) ((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<int>(transform.position.x), - .y = static_cast<int>(transform.position.y), - .w = static_cast<int>(w * transform.scale), - .h = static_cast<int>(h * transform.scale), + .x = static_cast<int>(adjusted_x), + .y = static_cast<int>(adjusted_y), + .w = static_cast<int>(adjusted_w), + .h = static_cast<int>(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_Texture * SDLContext::setTextureFromPath(const char * path, SDL_Rect & clip, - const int row, const int col) { - dbg_trace(); + SDL_RenderCopyEx(this->game_renderer, sprite.sprite_image->texture, + &srcrect, - SDL_Surface * tmp = IMG_Load(path); - if (!tmp) { - std::cerr << "Error surface " << IMG_GetError << std::endl; - } - - clip. - w = tmp->w / col; - clip.h = tmp->h / row; - - SDL_Texture * CreatedTexture - = SDL_CreateTextureFromSurface(this->game_renderer, tmp); + &dstrect, degrees, NULL, render_flip); +} - if (!CreatedTexture) { - std::cerr << "Error could not create texture " << IMG_GetError - << std::endl; - } - SDL_FreeSurface(tmp); +void SDLContext::camera(const Camera & cam) { + this->viewport.w = static_cast<int>(cam.aspect_width); + this->viewport.h = static_cast<int>(cam.aspect_height); + this->viewport.x = static_cast<int>(cam.x) - (SCREEN_WIDTH / 2); + this->viewport.y = static_cast<int>(cam.y) - (SCREEN_HEIGHT / 2); - return CreatedTexture; + SDL_SetRenderDrawColor(this->game_renderer, cam.bg_color.r, cam.bg_color.g, + cam.bg_color.b, cam.bg_color.a); } -*/ + +const uint64_t SDLContext::get_ticks() const { return SDL_GetTicks64(); } SDL_Texture * SDLContext::texture_from_path(const char * path) { dbg_trace(); @@ -155,3 +165,13 @@ SDL_Texture * SDLContext::texture_from_path(const char * path) { return created_texture; } +int SDLContext::get_width(const Texture & ctx) { + int w; + SDL_QueryTexture(ctx.texture, NULL, NULL, &w, NULL); + return w; +} +int SDLContext::get_height(const Texture & ctx) { + int h; + SDL_QueryTexture(ctx.texture, NULL, NULL, NULL, &h); + return h; +} diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index f1ba8a6..a08d0d8 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -1,48 +1,160 @@ #pragma once +#include <SDL2/SDL_keycode.h> #include <SDL2/SDL_render.h> #include <SDL2/SDL_video.h> #include "../api/Sprite.h" #include "../api/Transform.h" -#include "../system/RenderSystem.h" +#include "api/Camera.h" + +typedef SDL_Keycode CREPE_KEYCODES; + +//FIXME: this needs to be removed +const int SCREEN_WIDTH = 640; +const int SCREEN_HEIGHT = 480; namespace crepe { 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(); + + /** + * \brief Deleted copy constructor. + */ SDLContext(const SDLContext &) = delete; + + /** + * \brief Deleted move constructor. + */ SDLContext(SDLContext &&) = delete; + + /** + * \brief Deleted copy assignment operator. + * \return Reference to the SDLContext instance. + */ SDLContext & operator=(const SDLContext &) = delete; - SDLContext & operator=(SDLContext &&) = delete; - //TODO decide events wouter? + /** + * \brief Deleted move assignment operator. + * \return Reference to the SDLContext instance. + */ + SDLContext & operator=(SDLContext &&) = delete; private: + 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: + friend class AnimatorSystem; + + /** + * \brief Gets the current SDL ticks since the program started. + * \return Current ticks in milliseconds as a constant uint64_t. + */ + const uint64_t get_ticks() const; + + +private: + /** + * \brief Constructs an SDLContext instance. + * Initializes SDL, creates a window and renderer. + */ SDLContext(); + + /** + * \brief Destroys the SDLContext instance. + * Cleans up SDL resources, including the window and renderer. + */ virtual ~SDLContext(); + + private: + friend class Texture; - SDL_Texture * texture_from_path(const char *); - //SDL_Texture* setTextureFromPath(const char*, SDL_Rect& clip, const int row, const int col); + 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. + */ + SDL_Texture * texture_from_path(const char * 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 & ); + + /** + * \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 &); + private: + 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); + + /** + * \brief Clears the screen, preparing for a new frame. + */ void clear_screen(); + + /** + * \brief 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 SDL_Window * game_window = nullptr; + //! renderer for the crepe engine SDL_Renderer * game_renderer = nullptr; + + //! viewport for the camera window + SDL_Rect viewport = {0, 0, 640, 480}; }; } // namespace crepe diff --git a/src/crepe/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp new file mode 100644 index 0000000..052d264 --- /dev/null +++ b/src/crepe/system/AnimatorSystem.cpp @@ -0,0 +1,39 @@ + + +#include "AnimatorSystem.h" +#include "ComponentManager.h" +#include "facade/SDLContext.h" +#include "util/log.h" + +#include "api/Animator.h" + +#include <cstdint> +#include <functional> +#include <vector> + +using namespace crepe; + +AnimatorSystem::AnimatorSystem() { dbg_trace(); } + +AnimatorSystem::~AnimatorSystem() { dbg_trace(); } + +AnimatorSystem & AnimatorSystem::get_instance() { + static AnimatorSystem instance; + return instance; +} + +void AnimatorSystem::update() { + ComponentManager& mgr = ComponentManager::get_instance(); + + std::vector<std::reference_wrapper<Animator>> animations = mgr.get_components_by_type<Animator>(); + + uint64_t tick = SDLContext::get_instance().get_ticks(); + for(Animator& a : animations){ + if (a.active) { + a.curr_row = (tick / 100) % a.row; + a.animator_rect.x = (a.curr_row * a.animator_rect.w) + a.curr_col; + a.spritesheet.sprite_rect = a.animator_rect; + } + } +} + diff --git a/src/crepe/system/AnimatorSystem.h b/src/crepe/system/AnimatorSystem.h new file mode 100644 index 0000000..553b456 --- /dev/null +++ b/src/crepe/system/AnimatorSystem.h @@ -0,0 +1,53 @@ +#pragma once + +#include "System.h" + +namespace crepe { + +/** + * \brief The AnimatorSystem is responsible for managing and updating all Animator components. + * + * This system is responsible for controlling the behavior of the animations for all entities + * that have the Animator component attached. It updates the animations by controlling their + * frame changes, looping behavior, and overall animation state. + */ +class AnimatorSystem : public System { + +public: + /** + * \brief Retrieves the singleton instance of the AnimatorSystem. + * + * \return A reference to the single instance of the AnimatorSystem. + * + * This method ensures that there is only one instance of the AnimatorSystem, following the + * singleton design pattern. It can be used to access the system globally. + */ + static AnimatorSystem & get_instance(); + + /** + * \brief Updates the Animator components. + * + * This method is called periodically (likely every frame) to update the state of all + * Animator components, moving the animations forward and managing their behavior (e.g., looping). + */ + void update() override; + +private: + /** + * \brief Private constructor for the AnimatorSystem. + * + * The constructor is private to enforce the singleton pattern, ensuring that only + * one instance of this system can exist. + */ + AnimatorSystem(); + + /** + * \brief Private destructor for the AnimatorSystem. + * + * The destructor cleans up any resources used by the AnimatorSystem. It is private + * to maintain the singleton pattern and prevent direct deletion. + */ + ~AnimatorSystem(); +}; + +} // namespace crepe diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt index ff6f66f..4c18b87 100644 --- a/src/crepe/system/CMakeLists.txt +++ b/src/crepe/system/CMakeLists.txt @@ -4,6 +4,7 @@ target_sources(crepe PUBLIC PhysicsSystem.cpp CollisionSystem.cpp RenderSystem.cpp + AnimatorSystem.cpp ) target_sources(crepe PUBLIC FILE_SET HEADERS FILES @@ -12,4 +13,5 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES PhysicsSystem.h CollisionSystem.h RenderSystem.h + AnimatorSystem.h ) diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 5a07cc2..149af68 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -20,7 +20,23 @@ RenderSystem & RenderSystem::get_instance() { return instance; } -void RenderSystem::update() { +void RenderSystem::clear_screen() { SDLContext::get_instance().clear_screen(); } + +void RenderSystem::present_screen() { + SDLContext::get_instance().present_screen(); +} +void RenderSystem::update_camera() { + ComponentManager & mgr = ComponentManager::get_instance(); + + std::vector<std::reference_wrapper<Camera>> cameras + = mgr.get_components_by_type<Camera>(); + + for (Camera & cam : cameras) { + SDLContext::get_instance().camera(cam); + this->curr_cam = &cam; + } +} +void RenderSystem::render_sprites() { ComponentManager & mgr = ComponentManager::get_instance(); @@ -28,14 +44,15 @@ void RenderSystem::update() { = mgr.get_components_by_type<Sprite>(); SDLContext & render = SDLContext::get_instance(); - render.clear_screen(); - for (const Sprite & sprite : sprites) { - std::vector<std::reference_wrapper<Transform>> transforms - = mgr.get_components_by_id<Transform>(sprite.game_object_id); - for (const Transform & transform : transforms) { - render.draw(sprite, transform); - } + auto transforms = mgr.get_components_by_id<Transform>(sprite.game_object_id); + render.draw(sprite, transforms[0] , *curr_cam); } - render.present_screen(); +} + +void RenderSystem::update() { + this->clear_screen(); + this->update_camera(); + this->render_sprites(); + this->present_screen(); } diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h index 4b910a4..684776b 100644 --- a/src/crepe/system/RenderSystem.h +++ b/src/crepe/system/RenderSystem.h @@ -1,17 +1,78 @@ #pragma once #include "System.h" +#include "api/Camera.h" namespace crepe { +/** + * \class RenderSystem + * \brief Manages rendering operations for all game objects. + * + * RenderSystem is responsible for rendering sprites, clearing and presenting the screen, + * and managing the active camera. It functions as a singleton, providing centralized + * rendering services for the application. + */ class RenderSystem : public System { public: - static RenderSystem & get_instance(); - void update(); + /** + * \brief Gets the singleton instance of RenderSystem. + * \return Reference to the RenderSystem instance. + */ + static RenderSystem & get_instance(); + + /** + * \brief Updates the RenderSystem for the current frame. + * This method is called to perform all rendering operations for the current game frame. + */ + void update() override; + +private: + /** + * \brief Constructs a RenderSystem instance. + * Private constructor to enforce singleton pattern. + */ + RenderSystem(); + + /** + * \brief Destroys the RenderSystem instance. + */ + ~RenderSystem(); + + /** + * \brief Clears the screen in preparation for rendering. + */ + void clear_screen(); + + /** + * \brief Presents the rendered frame to the display. + */ + void present_screen(); + + /** + * \brief Updates the active camera used for rendering. + */ + void update_camera(); + + /** + * \brief Renders all active sprites to the screen. + */ + void render_sprites(); + + /** + * \todo Include color handling for sprites. + * \todo Implement particle emitter rendering with sprites. + * \todo Add text rendering using SDL_ttf for text components. + * \todo Implement a text component and a button component. + * \todo Ensure each sprite is checked for active status before rendering. + * \todo Sort all layers by order before rendering. + * \todo Consider adding text input functionality. + */ private: - RenderSystem(); - ~RenderSystem(); + //! Pointer to the current active camera for rendering + // \todo needs a better solution + Camera * curr_cam; }; } // namespace crepe |