aboutsummaryrefslogtreecommitdiff
path: root/src/crepe
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe')
-rw-r--r--src/crepe/api/Animator.cpp23
-rw-r--r--src/crepe/api/Animator.h87
-rw-r--r--src/crepe/api/CMakeLists.txt4
-rw-r--r--src/crepe/api/Camera.cpp15
-rw-r--r--src/crepe/api/Camera.h70
-rw-r--r--src/crepe/api/Color.cpp3
-rw-r--r--src/crepe/api/Color.h17
-rw-r--r--src/crepe/api/Sprite.cpp4
-rw-r--r--src/crepe/api/Sprite.h75
-rw-r--r--src/crepe/api/Texture.cpp17
-rw-r--r--src/crepe/api/Texture.h60
-rw-r--r--src/crepe/facade/SDLContext.cpp144
-rw-r--r--src/crepe/facade/SDLContext.h126
-rw-r--r--src/crepe/system/AnimatorSystem.cpp39
-rw-r--r--src/crepe/system/AnimatorSystem.h53
-rw-r--r--src/crepe/system/CMakeLists.txt2
-rw-r--r--src/crepe/system/RenderSystem.cpp35
-rw-r--r--src/crepe/system/RenderSystem.h69
18 files changed, 742 insertions, 101 deletions
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