aboutsummaryrefslogtreecommitdiff
path: root/src/crepe
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-12-06 19:26:27 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-12-06 19:26:27 +0100
commite8d9e38b4c265e0efde32c38d01b511cb572a34d (patch)
tree0af9b8f5e7c9e59de2e3c9ebc175ce31e9a86c20 /src/crepe
parentcfd578dd0b7d5894ff0b0a0796d85cd5e9ae6e56 (diff)
parentf3adf300c5ba9b382f74e5b704501fd047399062 (diff)
Merge branch 'niels/decoupling_pixel_and_pos' of github.com:lonkaars/crepe
Diffstat (limited to 'src/crepe')
-rw-r--r--src/crepe/api/Animator.cpp48
-rw-r--r--src/crepe/api/Animator.h118
-rw-r--r--src/crepe/api/Camera.cpp11
-rw-r--r--src/crepe/api/Camera.h38
-rw-r--r--src/crepe/api/Config.h4
-rw-r--r--src/crepe/api/LoopManager.cpp2
-rw-r--r--src/crepe/api/Sprite.cpp16
-rw-r--r--src/crepe/api/Sprite.h96
-rw-r--r--src/crepe/api/Transform.h6
-rw-r--r--src/crepe/facade/SDLContext.cpp130
-rw-r--r--src/crepe/facade/SDLContext.h53
-rw-r--r--src/crepe/manager/Mediator.h4
-rw-r--r--src/crepe/system/AnimatorSystem.cpp31
-rw-r--r--src/crepe/system/AnimatorSystem.h3
-rw-r--r--src/crepe/system/InputSystem.cpp8
-rw-r--r--src/crepe/system/RenderSystem.cpp39
-rw-r--r--src/crepe/system/RenderSystem.h15
17 files changed, 416 insertions, 206 deletions
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index 45f67f6..154135f 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -7,21 +7,53 @@
using namespace crepe;
-Animator::Animator(game_object_id_t id, Sprite & ss, int row, int col, int col_animator)
+Animator::Animator(uint32_t id, Sprite & ss, unsigned int max_row, unsigned int max_col,
+ const Animator::Data & data)
: Component(id),
spritesheet(ss),
- row(row),
- col(col) {
+ max_rows(max_row),
+ max_columns(max_col),
+ data(data) {
dbg_trace();
- this->spritesheet.mask.h /= col;
- this->spritesheet.mask.w /= row;
- this->spritesheet.mask.x = 0;
- this->spritesheet.mask.y = col_animator * this->spritesheet.mask.h;
- this->active = false;
+ this->spritesheet.mask.h /= this->max_columns;
+ this->spritesheet.mask.w /= this->max_rows;
+ this->spritesheet.mask.x = this->data.row * this->spritesheet.mask.w;
+ this->spritesheet.mask.y = this->data.col * this->spritesheet.mask.h;
// need to do this for to get the aspect ratio for a single clipping in the spritesheet
this->spritesheet.aspect_ratio
= static_cast<double>(this->spritesheet.mask.w) / this->spritesheet.mask.h;
}
+
Animator::~Animator() { dbg_trace(); }
+
+void Animator::loop() { this->data.looping = true; }
+
+void Animator::play() { this->active = true; }
+
+void Animator::pause() { this->active = false; }
+
+void Animator::stop() {
+ this->active = false;
+ this->data.col = 0;
+ this->data.row = 0;
+}
+void Animator::set_fps(int fps) { this->data.fps = fps; }
+
+void Animator::set_cycle_range(int start, int end) {
+ this->data.cycle_start = start, this->data.cycle_end = end;
+}
+
+void Animator::set_anim(int col) {
+ Animator::Data & ctx = this->data;
+ this->spritesheet.mask.x = ctx.row = 0;
+ ctx.col = col;
+ this->spritesheet.mask.y = ctx.col * this->spritesheet.mask.h;
+}
+
+void Animator::next_anim() {
+ Animator::Data & ctx = this->data;
+ ctx.row = ctx.row++ % this->max_rows;
+ this->spritesheet.mask.x = ctx.row * this->spritesheet.mask.w;
+}
diff --git a/src/crepe/api/Animator.h b/src/crepe/api/Animator.h
index 6c506aa..23d29f6 100644
--- a/src/crepe/api/Animator.h
+++ b/src/crepe/api/Animator.h
@@ -1,7 +1,10 @@
#pragma once
+#include <sys/types.h>
+
#include "Component.h"
#include "Sprite.h"
+#include "types.h"
namespace crepe {
@@ -16,56 +19,117 @@ class SDLContext;
* sheet. It can be used to play animations, loop them, or stop them.
*/
class Animator : public Component {
+public:
+ struct Data {
+
+ //! frames per second for animation
+ unsigned int fps = 1;
+
+ //! The current col being animated.
+ unsigned int col = 0;
+
+ //! The current row being animated.
+ unsigned int row = 0;
+
+ //! should the animation loop
+ bool looping = false;
+
+ //! starting frame for cycling
+ unsigned int cycle_start = 0;
+
+ //! end frame for cycling (-1 --> use last frame)
+ int cycle_end = -1;
+
+ //! offset in pixels.
+ // TODO implement
+ unsigned int white_space = 0;
+ };
public:
- //TODO: need to implement this
+ /**
+ * \brief Animator will repeat the animation
+ *
+ */
void loop();
+
+ /**
+ * \brief starts the animation
+ *
+ */
+ void play();
+ /**
+ * \brief pauses the animation
+ *
+ * sets the active false
+ *
+ */
+ void pause();
+
+ /**
+ * \brief stops the animation
+ *
+ * sets the active on false and resets all the current rows and columns
+ *
+ */
void stop();
+ /**
+ * \brief set frames per second
+ *
+ * \param fps frames per second
+ */
+ void set_fps(int fps);
+ /**
+ * \brief set the range in the row
+ *
+ * \param start of row animation
+ * \param end of row animation
+ */
+ void set_cycle_range(int start, int end);
+ /**
+ * \brief select which column to animate from
+ *
+ * \param col animation column
+ */
+ void set_anim(int col);
+
+ /**
+ * \brief will go to the next animaiton of current row
+ *
+ */
+ void next_anim();
public:
/**
* \brief Constructs an Animator object that will control animations for a sprite sheet.
*
* \param id The unique identifier for the component, typically assigned automatically.
- * \param spritesheet A reference to the Sprite object which holds the sprite sheet for
- * animation.
- * \param row The maximum number of rows in the sprite sheet.
- * \param col The maximum number of columns in the sprite sheet.
- * \param 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.
+ * \param ss the reference to the spritesheet
+ * \param max_row maximum of rows inside the given spritesheet
+ * \param max_col maximum of columns inside the given spritesheet
+ * \param data extra animation data for more control
*
* 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);
-
+ Animator(game_object_id_t id, Sprite & ss, unsigned int max_row, unsigned int max_col,
+ const Animator::Data & data);
~Animator(); // dbg_trace
-private:
- //! A reference to the Sprite sheet containing the animation frames.
- Sprite & spritesheet;
-
+public:
//! The maximum number of columns in the sprite sheet.
- const int col;
+ const unsigned int max_columns;
//! The maximum number of rows in the sprite sheet.
- const int row;
-
- //! The current col being animated.
- int curr_col = 0;
+ const unsigned int max_rows;
- //! The current row being animated.
- int curr_row = 0;
-
- //TODO: Is this necessary?
- //int fps;
+ Animator::Data data;
private:
- //! AnimatorSystem adjust the private member parameters of Animator;
- friend class AnimatorSystem;
+ //! A reference to the Sprite sheet containing.
+ Sprite & spritesheet;
- //! SDLContext reads the Animator member var's
- friend class SDLContext;
+ // uses the spritesheet
+ friend AnimatorSystem;
};
} // namespace crepe
//
diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp
index 39d8ab0..179dc18 100644
--- a/src/crepe/api/Camera.cpp
+++ b/src/crepe/api/Camera.cpp
@@ -1,20 +1,17 @@
-#include "types.h"
#include "util/Log.h"
#include "Camera.h"
-#include "Color.h"
#include "Component.h"
+#include "types.h"
using namespace crepe;
-Camera::Camera(game_object_id_t id, const Color & bg_color, const ivec2 & screen,
- const vec2 & viewport_size, const double & zoom, const vec2 & offset)
+Camera::Camera(game_object_id_t id, const ivec2 & screen, const vec2 & viewport_size,
+ const Data & data)
: Component(id),
- bg_color(bg_color),
- offset(offset),
screen(screen),
viewport_size(viewport_size),
- zoom(zoom) {
+ data(data) {
dbg_trace();
}
diff --git a/src/crepe/api/Camera.h b/src/crepe/api/Camera.h
index 2d8fa48..54d9a73 100644
--- a/src/crepe/api/Camera.h
+++ b/src/crepe/api/Camera.h
@@ -14,23 +14,42 @@ namespace crepe {
* position, and zoom level. It controls what part of the game world is visible on the screen.
*/
class Camera : public Component {
+public:
+ struct Data {
+ /**
+ * \bg_color background color of the game
+ *
+ * This will make the background the same color as the given value.
+ */
+ const Color bg_color = Color::BLACK;
+
+ /**
+ * \zoom Zooming level of the game
+ *
+ * zoom = 1 --> no zoom.
+ * zoom < 1 --> zoom out
+ * zoom > 1 --> zoom in
+ */
+ double zoom = 1;
+
+ //! offset postion from the game object transform component
+ vec2 postion_offset;
+ };
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.
+ * \param screen is the actual screen size in pixels
+ * \param viewport_size is the view of the world in game units
+ * \param data the camera component data
*/
- Camera(game_object_id_t id, const Color & bg_color, const ivec2 & screen,
- const vec2 & viewport_size, const double & zoom, const vec2 & offset = {0, 0});
+ Camera(game_object_id_t id, const ivec2 & screen, const vec2 & viewport_size,
+ const Camera::Data & data);
~Camera(); // dbg_trace only
public:
- //! Background color of the camera view.
- const Color bg_color;
-
- //! offset postion from the game object transform component
- vec2 offset;
+ Camera::Data data;
//! screen the display size in pixels ( output resolution )
const ivec2 screen;
@@ -38,9 +57,6 @@ public:
//! viewport is the area of the world visible through the camera (in world units)
const vec2 viewport_size;
- //! Zoom level of the camera view.
- const double zoom;
-
public:
/**
* \brief Gets the maximum number of camera instances allowed.
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index 225e9b9..f1bca62 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -66,8 +66,8 @@ public:
//! default window settings
struct {
- //TODO make this constexpr because this will never change
- ivec2 default_size = {1080, 720};
+ //! default screen size in pixels
+ ivec2 default_size = {1280, 720};
std::string window_title = "Jetpack joyride clone";
} window_settings;
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp
index 8ccc0a4..044f096 100644
--- a/src/crepe/api/LoopManager.cpp
+++ b/src/crepe/api/LoopManager.cpp
@@ -65,11 +65,13 @@ void LoopManager::setup() {
this->scene_manager.load_next_scene();
timer.start();
timer.set_fps(200);
+ this->scene_manager.load_next_scene();
}
void LoopManager::render() {
if (!this->game_running) return;
+ this->get_system<AnimatorSystem>().update();
this->get_system<RenderSystem>().update();
}
diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp
index 0a2ad4c..cc0e20a 100644
--- a/src/crepe/api/Sprite.cpp
+++ b/src/crepe/api/Sprite.cpp
@@ -6,24 +6,20 @@
#include "Component.h"
#include "Sprite.h"
#include "Texture.h"
+#include "types.h"
using namespace std;
using namespace crepe;
-Sprite::Sprite(game_object_id_t id, Texture & image, const Color & color,
- const FlipSettings & flip, int sort_layer, int order_layer, int height)
+Sprite::Sprite(game_object_id_t id, Texture & texture, const Sprite::Data & data)
: Component(id),
- color(color),
- flip(flip),
- sprite_image(std::move(image)),
- sorting_in_layer(sort_layer),
- order_in_layer(order_layer),
- height(height) {
+ texture(std::move(texture)),
+ data(data) {
dbg_trace();
- this->mask.w = sprite_image.get_size().x;
- this->mask.h = sprite_image.get_size().y;
+ this->mask.w = this->texture.get_size().x;
+ this->mask.h = this->texture.get_size().y;
this->aspect_ratio = static_cast<double>(this->mask.w) / this->mask.h;
}
diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h
index a0e90a0..ea8104c 100644
--- a/src/crepe/api/Sprite.h
+++ b/src/crepe/api/Sprite.h
@@ -1,11 +1,10 @@
#pragma once
-#include <cstdint>
-
#include "../Component.h"
#include "Color.h"
#include "Texture.h"
+#include "types.h"
namespace crepe {
@@ -20,60 +19,81 @@ class AnimatorSystem;
* flip settings, and is managed in layers with defined sorting orders.
*/
class Sprite : public Component {
-
public:
+ //! settings to flip the image
struct FlipSettings {
+ //! horizantal flip
bool flip_x = false;
+ //! vertical flip
bool flip_y = false;
};
+ //! Sprite data that does not have to be set in the constructor
+ struct Data {
+ /**
+ * \color tint of the sprite
+ *
+ * the default value is white because of the color multiplier.
+ * this means that the orginal image will be shown. if color is BLACK for example
+ * then it turns the image black because of the Color channels being 0.
+ */
+ Color color = Color::WHITE;
+
+ //! Flip settings for the sprite
+ FlipSettings flip;
+
+ //! Layer sorting level of the sprite
+ const int sorting_in_layer = 0;
+
+ //! Order within the sorting layer
+ const int order_in_layer = 0;
+
+ /**
+ * \size width and height of the sprite in game units
+ *
+ * - if height is filled in and not width it will multiply width by aspect_ratio.
+ * - if width is filled in and not height it will multiply height by aspect_ratio.
+ * - if neither is filled it will not show sprite because size will be zero
+ * - if both are filled will it use the width and height without making sure the aspect_ratio
+ * is correct
+ */
+ vec2 size;
+
+ //! independent sprite angle. rotating clockwise direction in degrees
+ float angle_offset = 0;
+
+ //! independent sprite scale multiplier
+ float scale_offset = 1;
+
+ //! independent sprite offset position
+ vec2 position_offset;
+ };
+
public:
- // TODO: Loek comment in github #27 will be looked another time
- // about shared_ptr Texture
/**
* \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.
- * \param order_layer decides the sorting in layer of the sprite.
- * \param sort_layer decides the order in layer of the sprite.
- * \param height the height of the image in game units
- */
- Sprite(game_object_id_t id, Texture & image, const Color & color,
- const FlipSettings & flip, int sort_layer, int order_layer, int height);
-
- /**
- * \brief Destroys the Sprite instance.
+ * \param texture asset of the image
+ * \param ctx all the sprite data
*/
+ Sprite(game_object_id_t id, Texture & texture, const Data & data);
~Sprite();
//! Texture used for the sprite
- const Texture sprite_image;
+ const Texture texture;
- //! Color tint of the sprite
- Color color;
-
- //! Flip settings for the sprite
- FlipSettings flip;
-
- //! Layer sorting level of the sprite
- const int sorting_in_layer;
- //! Order within the sorting layer
- const int order_in_layer;
-
- //! height in world units
- const int height;
+ Data data;
+private:
/**
- * \aspect_ratio ratio of the img so that scaling will not become weird
- *
- * cannot be const because if Animator component is addded then ratio becomes scuffed and
- * does it need to be calculated again in the Animator
- */
- double aspect_ratio;
+ * \aspect_ratio ratio of the img
+ *
+ * - This will multiply one of \c size variable if it is 0.
+ * - Will be adjusted if \c Animator component is added to an GameObject
+ * that is why this value cannot be const.
+ */
+ float aspect_ratio;
-private:
//! Reads the mask of sprite
friend class SDLContext;
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index 6243a93..3ef0fb5 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -15,10 +15,10 @@ class Transform : public Component {
public:
//! Translation (shift)
vec2 position = {0, 0};
- //! Rotation, in degrees
- double rotation = 0;
+ //! Rotation, in degrees clockwise
+ float rotation = 0;
//! Multiplication factor
- double scale = 0;
+ float scale = 0;
protected:
/**
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index ad9f1f0..4cc2206 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -11,19 +11,17 @@
#include <cstddef>
#include <cstdint>
#include <functional>
-#include <iostream>
#include <memory>
#include <stdexcept>
#include "../api/Camera.h"
+#include "../api/Color.h"
#include "../api/Config.h"
#include "../api/Sprite.h"
#include "../api/Texture.h"
-#include "../manager/EventManager.h"
#include "../util/Log.h"
#include "SDLContext.h"
-#include "api/Color.h"
#include "types.h"
using namespace crepe;
@@ -215,11 +213,13 @@ MouseButton SDLContext::sdl_to_mousebutton(Uint8 sdl_button) {
return MOUSE_BUTTON_LOOKUP_TABLE[sdl_button];
}
-void SDLContext::clear_screen() {
+void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); }
+void SDLContext::present_screen() {
SDL_SetRenderDrawColor(this->game_renderer.get(), 0, 0, 0, 255);
- SDL_RenderClear(this->game_renderer.get());
+ SDL_RenderFillRectF(this->game_renderer.get(), &black_bars[0]);
+ SDL_RenderFillRectF(this->game_renderer.get(), &black_bars[1]);
+ SDL_RenderPresent(this->game_renderer.get());
}
-void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); }
SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const {
return SDL_Rect{
@@ -229,40 +229,62 @@ SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const {
.h = sprite.mask.h,
};
}
-SDL_Rect SDLContext::get_dst_rect(const Sprite & sprite, const vec2 & pos, const Camera & cam,
- const vec2 & cam_pos, const double & img_scale) const {
- int width = sprite.height * sprite.aspect_ratio;
- int height = sprite.height;
+SDL_FRect SDLContext::get_dst_rect(const DestinationRectangleData & ctx) const {
- width *= img_scale * cam.zoom;
- height *= img_scale * cam.zoom;
+ const Sprite::Data & data = ctx.sprite.data;
- return SDL_Rect{
- .x = static_cast<int>((pos.x - cam_pos.x + (cam.viewport_size.x / 2) - width / 2)),
- .y = static_cast<int>((pos.y - cam_pos.y + (cam.viewport_size.y / 2) - height / 2)),
- .w = width,
- .h = height,
+ vec2 size;
+ if (data.size.x == 0 && data.size.y != 0) {
+ size.x = data.size.y * ctx.sprite.aspect_ratio;
+ }
+ if (data.size.y == 0 && data.size.x != 0) {
+ size.y = data.size.x / ctx.sprite.aspect_ratio;
+ }
+
+ const CameraValues & cam = ctx.cam;
+
+ size *= cam.render_scale * ctx.img_scale * data.scale_offset;
+
+ vec2 screen_pos
+ = (ctx.pos + data.position_offset - cam.cam_pos + (cam.zoomed_viewport) / 2)
+ * cam.render_scale
+ - size / 2 + cam.bar_size;
+
+ return SDL_FRect{
+ .x = screen_pos.x,
+ .y = screen_pos.y,
+ .w = size.x,
+ .h = size.y,
};
}
void SDLContext::draw(const RenderContext & ctx) {
+ const Sprite::Data & data = ctx.sprite.data;
SDL_RendererFlip render_flip
- = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * ctx.sprite.flip.flip_x)
- | (SDL_FLIP_VERTICAL * ctx.sprite.flip.flip_y));
+ = (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * data.flip.flip_x)
+ | (SDL_FLIP_VERTICAL * data.flip.flip_y));
SDL_Rect srcrect = this->get_src_rect(ctx.sprite);
- SDL_Rect dstrect
- = this->get_dst_rect(ctx.sprite, ctx.pos, ctx.cam, ctx.cam_pos, ctx.scale);
-
- this->set_color_texture(ctx.sprite.sprite_image, ctx.sprite.color);
- SDL_RenderCopyEx(this->game_renderer.get(), ctx.sprite.sprite_image.texture.get(),
- &srcrect, &dstrect, ctx.angle, NULL, render_flip);
+ SDL_FRect dstrect = this->get_dst_rect(SDLContext::DestinationRectangleData{
+ .sprite = ctx.sprite,
+ .cam = ctx.cam,
+ .pos = ctx.pos,
+ .img_scale = ctx.scale,
+ });
+
+ double angle = ctx.angle + data.angle_offset;
+
+ this->set_color_texture(ctx.sprite.texture, ctx.sprite.data.color);
+ SDL_RenderCopyExF(this->game_renderer.get(), ctx.sprite.texture.texture.get(), &srcrect,
+ &dstrect, angle, NULL, render_flip);
}
-void SDLContext::set_camera(const Camera & cam) {
+SDLContext::CameraValues SDLContext::set_camera(const Camera & cam) {
+ const Camera::Data & cam_data = cam.data;
+ CameraValues ret_cam;
// resize window
int w, h;
SDL_GetWindowSize(this->game_window.get(), &w, &h);
@@ -270,42 +292,52 @@ void SDLContext::set_camera(const Camera & cam) {
SDL_SetWindowSize(this->game_window.get(), cam.screen.x, cam.screen.y);
}
- double screen_aspect = cam.screen.x / cam.screen.y;
- double viewport_aspect = cam.viewport_size.x / cam.viewport_size.y;
+ vec2 & zoomed_viewport = ret_cam.zoomed_viewport;
+ vec2 & bar_size = ret_cam.bar_size;
+ vec2 & render_scale = ret_cam.render_scale;
+
+ zoomed_viewport = cam.viewport_size * cam_data.zoom;
+ float screen_aspect = static_cast<float>(cam.screen.x) / cam.screen.y;
+ float viewport_aspect = zoomed_viewport.x / zoomed_viewport.y;
- SDL_Rect view;
// calculate black bars
if (screen_aspect > viewport_aspect) {
- // letterboxing
- view.h = cam.screen.y / cam.zoom;
- view.w = cam.screen.y * viewport_aspect;
- view.x = (cam.screen.x - view.w) / 2;
- view.y = 0;
- } else {
// pillarboxing
- view.h = cam.screen.x / viewport_aspect;
- view.w = cam.screen.x / cam.zoom;
- view.x = 0;
- view.y = (cam.screen.y - view.h) / 2;
+ float scale = cam.screen.y / zoomed_viewport.y;
+ float adj_width = zoomed_viewport.x * scale;
+ float bar_width = (cam.screen.x - adj_width) / 2;
+ this->black_bars[0] = {0, 0, bar_width, (float) cam.screen.y};
+ this->black_bars[1] = {(cam.screen.x - bar_width), 0, bar_width, (float) cam.screen.y};
+
+ bar_size = {bar_width, 0};
+ render_scale.x = render_scale.y = scale;
+ } else {
+ // letterboxing
+ float scale = cam.screen.x / (cam.viewport_size.x * cam_data.zoom);
+ float adj_height = cam.viewport_size.y * scale;
+ float bar_height = (cam.screen.y - adj_height) / 2;
+ this->black_bars[0] = {0, 0, (float) cam.screen.x, bar_height};
+ this->black_bars[1]
+ = {0, (cam.screen.y - bar_height), (float) cam.screen.x, bar_height};
+
+ bar_size = {0, bar_height};
+ render_scale.x = render_scale.y = scale;
}
- // set drawing area
- SDL_RenderSetViewport(this->game_renderer.get(), &view);
-
- SDL_RenderSetLogicalSize(this->game_renderer.get(), static_cast<int>(cam.viewport_size.x),
- static_cast<int>(cam.viewport_size.y));
- // set bg color
- SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, cam.bg_color.g,
- cam.bg_color.b, cam.bg_color.a);
+ SDL_SetRenderDrawColor(this->game_renderer.get(), cam_data.bg_color.r, cam_data.bg_color.g,
+ cam_data.bg_color.b, cam_data.bg_color.a);
SDL_Rect bg = {
.x = 0,
.y = 0,
- .w = static_cast<int>(cam.viewport_size.x),
- .h = static_cast<int>(cam.viewport_size.y),
+ .w = cam.screen.x,
+ .h = cam.screen.y,
};
+
// fill bg color
SDL_RenderFillRect(this->game_renderer.get(), &bg);
+
+ return ret_cam;
}
uint64_t SDLContext::get_ticks() const { return SDL_GetTicks64(); }
diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h
index a2b34c1..81a8a34 100644
--- a/src/crepe/facade/SDLContext.h
+++ b/src/crepe/facade/SDLContext.h
@@ -9,11 +9,9 @@
#include <functional>
#include <memory>
#include <string>
-#include <utility>
#include "api/Camera.h"
#include "api/Color.h"
-#include "api/Event.h"
#include "api/KeyCodes.h"
#include "api/Sprite.h"
#include "api/Texture.h"
@@ -33,10 +31,38 @@ class InputSystem;
*/
class SDLContext {
public:
+ //! data that the camera component cannot hold
+ struct CameraValues {
+
+ //! zoomed in viewport in game_units
+ vec2 zoomed_viewport;
+
+ /**
+ * \render_scale scaling factor
+ *
+ * depending on the black bars type will the scaling be different.
+ * - lettorboxing --> scaling on the y-as
+ * - pillarboxing --> scaling on the x-as
+ */
+ vec2 render_scale;
+
+ /**
+ * \bar_size size of calculated black bars
+ *
+ * depending on the black bars type will the size be different
+ * - lettorboxing --> {0, bar_height}
+ * - pillarboxing --> {bar_width , 0}
+ */
+ vec2 bar_size;
+
+ //! Calculated camera position
+ vec2 cam_pos;
+ };
+
+ //! rendering data needed to render on screen
struct RenderContext {
const Sprite & sprite;
- const Camera & cam;
- const vec2 & cam_pos;
+ const CameraValues & cam;
const vec2 & pos;
const double & angle;
const double & scale;
@@ -114,8 +140,6 @@ private:
MouseButton sdl_to_mousebutton(Uint8 sdl_button);
private:
- //! Will only use get_ticks
- friend class AnimatorSystem;
//! Will only use delay
friend class LoopTimer;
/**
@@ -170,7 +194,7 @@ private:
/**
* \brief Draws a sprite to the screen using the specified transform and camera.
- * \param RenderCtx Reference to rendering data to draw
+ * \param RenderContext Reference to rendering data to draw
*/
void draw(const RenderContext & ctx);
@@ -184,9 +208,16 @@ private:
* \brief sets the background of the camera (will be adjusted in future PR)
* \param camera Reference to the Camera object.
*/
- void set_camera(const Camera & camera);
+ CameraValues set_camera(const Camera & camera);
private:
+ //! the data needed to construct a sdl dst rectangle
+ struct DestinationRectangleData {
+ const Sprite & sprite;
+ const CameraValues & cam;
+ const vec2 & pos;
+ const double & img_scale;
+ };
/**
* \brief calculates the sqaure size of the image
*
@@ -205,8 +236,7 @@ private:
* \param img_scale the image multiplier for increasing img size
* \return sdl rectangle to draw a dst image to draw on the screen
*/
- SDL_Rect get_dst_rect(const Sprite & sprite, const vec2 & pos, const Camera & cam,
- const vec2 & cam_pos, const double & img_scale) const;
+ SDL_FRect get_dst_rect(const DestinationRectangleData & data) const;
/**
* \brief Set an additional color value multiplied into render copy operations.
*
@@ -221,6 +251,9 @@ private:
//! renderer for the crepe engine
std::unique_ptr<SDL_Renderer, std::function<void(SDL_Renderer *)>> game_renderer;
+
+ //! black bars rectangle to draw
+ SDL_FRect black_bars[2] = {};
};
} // namespace crepe
diff --git a/src/crepe/manager/Mediator.h b/src/crepe/manager/Mediator.h
index 71bd1c9..8094d80 100644
--- a/src/crepe/manager/Mediator.h
+++ b/src/crepe/manager/Mediator.h
@@ -3,8 +3,10 @@
#include "../util/OptionalRef.h"
// TODO: remove these singletons:
+#include "../facade/SDLContext.h"
#include "EventManager.h"
#include "SaveManager.h"
+#include "api/LoopTimer.h"
namespace crepe {
@@ -28,6 +30,8 @@ struct Mediator {
OptionalRef<SceneManager> scene_manager;
OptionalRef<SaveManager> save_manager = SaveManager::get_instance();
OptionalRef<EventManager> event_manager = EventManager::get_instance();
+ OptionalRef<SDLContext> sdl_context = SDLContext::get_instance();
+ OptionalRef<LoopTimer> timer = LoopTimer::get_instance();
};
} // namespace crepe
diff --git a/src/crepe/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp
index 8bb6465..549c35d 100644
--- a/src/crepe/system/AnimatorSystem.cpp
+++ b/src/crepe/system/AnimatorSystem.cpp
@@ -1,8 +1,8 @@
-#include <cstdint>
+
#include "../api/Animator.h"
-#include "../facade/SDLContext.h"
#include "../manager/ComponentManager.h"
+#include "api/LoopTimer.h"
#include "AnimatorSystem.h"
@@ -10,15 +10,30 @@ using namespace crepe;
void AnimatorSystem::update() {
ComponentManager & mgr = this->mediator.component_manager;
-
+ LoopTimer & timer = this->mediator.timer;
RefVector<Animator> animations = mgr.get_components_by_type<Animator>();
- uint64_t tick = SDLContext::get_instance().get_ticks();
+ double elapsed_time = timer.get_current_time();
+
for (Animator & a : animations) {
if (!a.active) continue;
- // (10 frames per second)
- a.curr_row = (tick / 100) % a.row;
- a.spritesheet.mask.x = (a.curr_row * a.spritesheet.mask.w) + a.curr_col;
- a.spritesheet.mask = a.spritesheet.mask;
+
+ Animator::Data & ctx = a.data;
+ float frame_duration = 1.0f / ctx.fps;
+
+ int last_frame = ctx.row;
+
+ int cycle_end = (ctx.cycle_end == -1) ? a.max_rows : ctx.cycle_end;
+ int total_frames = cycle_end - ctx.cycle_start;
+
+ int curr_frame = static_cast<int>(elapsed_time / frame_duration) % total_frames;
+
+ ctx.row = ctx.cycle_start + curr_frame;
+ a.spritesheet.mask.x = ctx.row * a.spritesheet.mask.w;
+ a.spritesheet.mask.y = (ctx.col * a.spritesheet.mask.h);
+
+ if (!ctx.looping && curr_frame == ctx.cycle_start && last_frame == total_frames - 1) {
+ a.active = false;
+ }
}
}
diff --git a/src/crepe/system/AnimatorSystem.h b/src/crepe/system/AnimatorSystem.h
index f8179a9..7d3f565 100644
--- a/src/crepe/system/AnimatorSystem.h
+++ b/src/crepe/system/AnimatorSystem.h
@@ -2,9 +2,6 @@
#include "System.h"
-//TODO:
-// control if flip works with animation system
-
namespace crepe {
/**
diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp
index 7cc8d30..aaa8bdf 100644
--- a/src/crepe/system/InputSystem.cpp
+++ b/src/crepe/system/InputSystem.cpp
@@ -24,10 +24,10 @@ void InputSystem::update() {
RefVector<Transform> transform_vec
= mgr.get_components_by_id<Transform>(current_cam.game_object_id);
Transform & cam_transform = transform_vec.front().get();
- int camera_origin_x
- = cam_transform.position.x + current_cam.offset.x - (current_cam.viewport_size.x / 2);
- int camera_origin_y
- = cam_transform.position.y + current_cam.offset.y - (current_cam.viewport_size.y / 2);
+ int camera_origin_x = cam_transform.position.x + current_cam.data.postion_offset.x
+ - (current_cam.viewport_size.x / 2);
+ int camera_origin_y = cam_transform.position.y + current_cam.data.postion_offset.y
+ - (current_cam.viewport_size.y / 2);
for (const SDLContext::EventData & event : event_list) {
int world_mouse_x = event.mouse_position.x + camera_origin_x;
diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp
index 92dba43..241e833 100644
--- a/src/crepe/system/RenderSystem.cpp
+++ b/src/crepe/system/RenderSystem.cpp
@@ -17,13 +17,19 @@
using namespace crepe;
using namespace std;
-void RenderSystem::clear_screen() { this->context.clear_screen(); }
+void RenderSystem::clear_screen() {
+ SDLContext & ctx = this->mediator.sdl_context;
+ ctx.clear_screen();
+}
-void RenderSystem::present_screen() { this->context.present_screen(); }
+void RenderSystem::present_screen() {
+ SDLContext & ctx = this->mediator.sdl_context;
+ ctx.present_screen();
+}
-const Camera & RenderSystem::update_camera() {
+SDLContext::CameraValues RenderSystem::update_camera() {
ComponentManager & mgr = this->mediator.component_manager;
-
+ SDLContext & ctx = this->mediator.sdl_context;
RefVector<Camera> cameras = mgr.get_components_by_type<Camera>();
if (cameras.size() == 0) throw std::runtime_error("No cameras in current scene");
@@ -32,16 +38,17 @@ const Camera & RenderSystem::update_camera() {
if (!cam.active) continue;
const Transform & transform
= mgr.get_components_by_id<Transform>(cam.game_object_id).front().get();
- this->context.set_camera(cam);
- this->cam_pos = transform.position + cam.offset;
- return cam;
+ SDLContext::CameraValues cam_val = ctx.set_camera(cam);
+ cam_val.cam_pos = transform.position + cam.data.postion_offset;
+ return cam_val;
}
throw std::runtime_error("No active cameras in current scene");
}
bool sorting_comparison(const Sprite & a, const Sprite & b) {
- if (a.sorting_in_layer < b.sorting_in_layer) return true;
- if (a.sorting_in_layer == b.sorting_in_layer) return a.order_in_layer < b.order_in_layer;
+ if (a.data.sorting_in_layer < b.data.sorting_in_layer) return true;
+ if (a.data.sorting_in_layer == b.data.sorting_in_layer)
+ return a.data.order_in_layer < b.data.order_in_layer;
return false;
}
@@ -59,10 +66,11 @@ void RenderSystem::update() {
this->present_screen();
}
-bool RenderSystem::render_particle(const Sprite & sprite, const Camera & cam,
+bool RenderSystem::render_particle(const Sprite & sprite, const SDLContext::CameraValues & cam,
const double & scale) {
ComponentManager & mgr = this->mediator.component_manager;
+ SDLContext & ctx = this->mediator.sdl_context;
vector<reference_wrapper<ParticleEmitter>> emitters
= mgr.get_components_by_id<ParticleEmitter>(sprite.game_object_id);
@@ -77,10 +85,9 @@ bool RenderSystem::render_particle(const Sprite & sprite, const Camera & cam,
for (const Particle & p : em.data.particles) {
if (!p.active) continue;
- this->context.draw(SDLContext::RenderContext{
+ ctx.draw(SDLContext::RenderContext{
.sprite = sprite,
.cam = cam,
- .cam_pos = this->cam_pos,
.pos = p.position,
.angle = p.angle,
.scale = scale,
@@ -89,12 +96,12 @@ bool RenderSystem::render_particle(const Sprite & sprite, const Camera & cam,
}
return rendering_particles;
}
-void RenderSystem::render_normal(const Sprite & sprite, const Camera & cam,
+void RenderSystem::render_normal(const Sprite & sprite, const SDLContext::CameraValues & cam,
const Transform & tm) {
- this->context.draw(SDLContext::RenderContext{
+ SDLContext & ctx = this->mediator.sdl_context;
+ ctx.draw(SDLContext::RenderContext{
.sprite = sprite,
.cam = cam,
- .cam_pos = this->cam_pos,
.pos = tm.position,
.angle = tm.rotation,
.scale = tm.scale,
@@ -103,7 +110,7 @@ void RenderSystem::render_normal(const Sprite & sprite, const Camera & cam,
void RenderSystem::render() {
ComponentManager & mgr = this->mediator.component_manager;
- const Camera & cam = this->update_camera();
+ const SDLContext::CameraValues & cam = this->update_camera();
RefVector<Sprite> sprites = mgr.get_components_by_type<Sprite>();
RefVector<Sprite> sorted_sprites = this->sort(sprites);
diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h
index 096d058..de76229 100644
--- a/src/crepe/system/RenderSystem.h
+++ b/src/crepe/system/RenderSystem.h
@@ -37,7 +37,7 @@ private:
void present_screen();
//! Updates the active camera used for rendering.
- const Camera & update_camera();
+ SDLContext::CameraValues update_camera();
//! Renders the whole screen
void render();
@@ -52,7 +52,8 @@ private:
* constructor is now protected i cannot make tmp inside
* \return true if particles have been rendered
*/
- bool render_particle(const Sprite & sprite, const Camera & cam, const double & scale);
+ bool render_particle(const Sprite & sprite, const SDLContext::CameraValues & cam,
+ const double & scale);
/**
* \brief renders a sprite with a Transform component on the screen
@@ -60,7 +61,8 @@ private:
* \param sprite the sprite component that holds all the data
* \param tm the Transform component that holds the position,rotation and scale
*/
- void render_normal(const Sprite & sprite, const Camera & cam, const Transform & tm);
+ void render_normal(const Sprite & sprite, const SDLContext::CameraValues & cam,
+ const Transform & tm);
/**
* \brief sort a vector sprite objects with
@@ -75,13 +77,6 @@ private:
* \todo Implement a text component and a button component.
* \todo Consider adding text input functionality.
*/
-
-private:
- // FIXME: retrieve sdlcontext via mediator after #PR57
- SDLContext & context = SDLContext::get_instance();
-
- //! camera postion in the current scene
- vec2 cam_pos;
};
} // namespace crepe