aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-09 13:21:34 +0100
committerWBoerenkamps <wrj.boerenkamps@student.avans.nl>2024-11-09 13:21:34 +0100
commitacfa153789d9b55f3453a1d32f249da04ad6b5c1 (patch)
tree10eff6219f329800da3a1f17310ceef2a52d2585
parentd3f39a67d62473661f7a76237ebf6df66e26d506 (diff)
changed comment
-rw-r--r--src/crepe/api/LoopTimer.h2
-rw-r--r--src/crepe/facade/SDLContext.cpp203
-rw-r--r--src/crepe/facade/SDLContext.h127
3 files changed, 239 insertions, 93 deletions
diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h
index 584a408..8d95921 100644
--- a/src/crepe/api/LoopTimer.h
+++ b/src/crepe/api/LoopTimer.h
@@ -78,4 +78,4 @@ double elapsed_fixed_time = 0; ///< Total elapsed time for fixed updates
uint64_t last_frame_time = 0; ///< Time of the last frame
};
-} // namespace crepe::api
+} // namespace crepe
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index 8da93e9..17ced0c 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -1,16 +1,22 @@
#include <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>
#include <cmath>
#include <cstddef>
+#include <functional>
#include <iostream>
+#include <memory>
+#include <string>
+#include <utility>
#include "../api/Sprite.h"
#include "../api/Texture.h"
#include "../api/Transform.h"
#include "../util/log.h"
+#include "Exception.h"
#include "SDLContext.h"
@@ -21,34 +27,6 @@ SDLContext & SDLContext::get_instance() {
return instance;
}
-void SDLContext::handle_events(bool & running) {
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- if (event.type == SDL_QUIT) {
- running = false;
- }
- }
-}
-
-SDLContext::~SDLContext() {
- dbg_trace();
-
- if (this->game_renderer != nullptr)
- SDL_DestroyRenderer(this->game_renderer);
-
- if (this->game_window != nullptr) {
- SDL_DestroyWindow(this->game_window);
- }
-
- // TODO: how are we going to ensure that these are called from the same
- // thread that SDL_Init() was called on? This has caused problems for me
- // before.
- IMG_Quit();
- SDL_Quit();
-}
-
-void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer); }
-
SDLContext::SDLContext() {
dbg_trace();
// FIXME: read window defaults from config manager
@@ -59,26 +37,32 @@ SDLContext::SDLContext() {
<< std::endl;
return;
}
-
- this->game_window = SDL_CreateWindow(
+ SDL_Window * tmp_window = SDL_CreateWindow(
"Crepe Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
- 1920, 1080, SDL_WINDOW_SHOWN);
- if (!this->game_window) {
+ this->viewport.w, this->viewport.h, 0);
+ if (!tmp_window) {
// FIXME: throw exception
std::cerr << "Window could not be created! SDL_Error: "
<< SDL_GetError() << std::endl;
+ return;
}
+ this->game_window
+ = {tmp_window, [](SDL_Window * window) { SDL_DestroyWindow(window); }};
- this->game_renderer
- = SDL_CreateRenderer(this->game_window, -1, SDL_RENDERER_ACCELERATED);
- if (!this->game_renderer) {
+ SDL_Renderer * tmp_renderer = SDL_CreateRenderer(
+ this->game_window.get(), -1, SDL_RENDERER_ACCELERATED);
+ if (!tmp_renderer) {
// FIXME: throw exception
std::cerr << "Renderer could not be created! SDL_Error: "
<< SDL_GetError() << std::endl;
- SDL_DestroyWindow(this->game_window);
+ SDL_DestroyWindow(this->game_window.get());
return;
}
+ this->game_renderer = {tmp_renderer, [](SDL_Renderer * renderer) {
+ SDL_DestroyRenderer(renderer);
+ }};
+
int img_flags = IMG_INIT_PNG;
if (!(IMG_Init(img_flags) & img_flags)) {
// FIXME: throw exception
@@ -87,71 +71,126 @@ SDLContext::SDLContext() {
}
}
-void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer); }
+SDLContext::~SDLContext() {
+ dbg_trace();
+
+ this->game_renderer.reset();
+ this->game_window.reset();
+
+ // TODO: how are we going to ensure that these are called from the same
+ // thread that SDL_Init() was called on? This has caused problems for me
+ // before.
+ IMG_Quit();
+ SDL_Quit();
+}
+
+void SDLContext::handle_events(bool & running) {
+ //TODO: wouter i need events
+ /*
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ switch (event.type) {
+ case SDL_QUIT:
+ running = false;
+ break;
+ case SDL_KEYDOWN:
+ triggerEvent(KeyPressedEvent(getCustomKey(event.key.keysym.sym)));
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ int x, y;
+ SDL_GetMouseState(&x, &y);
+ triggerEvent(MousePressedEvent(x, y));
+ break;
+ }
+ */
+}
+
+void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); }
+void SDLContext::present_screen() {
+ SDL_RenderPresent(this->game_renderer.get());
+}
-void SDLContext::draw(const Sprite & sprite, const Transform & transform) {
+void SDLContext::draw(const Sprite & sprite, const Transform & transform,
+ const Camera & cam) {
- static SDL_RendererFlip render_flip
+ SDL_RendererFlip render_flip
= (SDL_RendererFlip) ((SDL_FLIP_HORIZONTAL * sprite.flip.flip_x)
| (SDL_FLIP_VERTICAL * sprite.flip.flip_y));
- int w, h;
- SDL_QueryTexture(sprite.sprite_image->texture, NULL, NULL, &w, &h);
- // needs maybe camera for position
+ double adjusted_x = (transform.position.x - cam.x) * cam.zoom;
+ double adjusted_y = (transform.position.y - cam.y) * cam.zoom;
+ double adjusted_w = sprite.sprite_rect.w * transform.scale * cam.zoom;
+ double adjusted_h = sprite.sprite_rect.h * transform.scale * cam.zoom;
+
+ SDL_Rect srcrect = {
+ .x = sprite.sprite_rect.x,
+ .y = sprite.sprite_rect.y,
+ .w = sprite.sprite_rect.w,
+ .h = sprite.sprite_rect.h,
+ };
+
SDL_Rect dstrect = {
- .x = static_cast<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_RenderCopyEx(this->game_renderer.get(),
+ sprite.sprite_image->texture.get(), &srcrect,
+
+ &dstrect, transform.rotation, NULL, render_flip);
}
-/*
-SDL_Texture * SDLContext::setTextureFromPath(const char * path, SDL_Rect & clip,
- const int row, const int col) {
- dbg_trace();
+void SDLContext::camera(const Camera & cam) {
+ this->viewport.w = static_cast<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);
- SDL_Surface * tmp = IMG_Load(path);
- if (!tmp) {
- std::cerr << "Error surface " << IMG_GetError << std::endl;
- }
+ SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r,
+ cam.bg_color.g, cam.bg_color.b, cam.bg_color.a);
+}
- clip.
- w = tmp->w / col;
- clip.h = tmp->h / row;
+uint64_t SDLContext::get_ticks() const { return SDL_GetTicks64(); }
- SDL_Texture * CreatedTexture
- = SDL_CreateTextureFromSurface(this->game_renderer, tmp);
+std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>>
+SDLContext::texture_from_path(const std::string & path) {
- if (!CreatedTexture) {
- std::cerr << "Error could not create texture " << IMG_GetError
- << std::endl;
+ SDL_Surface * tmp = IMG_Load(path.c_str());
+ if (tmp == nullptr) {
+ throw Exception("surface cannot be load from %s", path.c_str());
}
- SDL_FreeSurface(tmp);
- return CreatedTexture;
-}
-*/
+ std::unique_ptr<SDL_Surface, std::function<void(SDL_Surface *)>>
+ img_surface;
+ img_surface
+ = {tmp, [](SDL_Surface * surface) { SDL_FreeSurface(surface); }};
-SDL_Texture * SDLContext::texture_from_path(const char * path) {
- dbg_trace();
+ SDL_Texture * tmp_texture = SDL_CreateTextureFromSurface(
+ this->game_renderer.get(), img_surface.get());
- SDL_Surface * tmp = IMG_Load(path);
- if (!tmp) {
- std::cerr << "Error surface " << IMG_GetError << std::endl;
+ if (tmp_texture == nullptr) {
+ throw Exception("Texture cannot be load from %s", path.c_str());
}
- SDL_Texture * created_texture
- = SDL_CreateTextureFromSurface(this->game_renderer, tmp);
- if (!created_texture) {
- std::cerr << "Error could not create texture " << IMG_GetError
- << std::endl;
- }
- SDL_FreeSurface(tmp);
+ std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>>
+ img_texture;
+ img_texture = {tmp_texture,
+ [](SDL_Texture * texture) { SDL_DestroyTexture(texture); }};
- return created_texture;
+ return img_texture;
+}
+int SDLContext::get_width(const Texture & ctx) const {
+ int w;
+ SDL_QueryTexture(ctx.texture.get(), NULL, NULL, &w, NULL);
+ return w;
+}
+int SDLContext::get_height(const Texture & ctx) const {
+ int h;
+ SDL_QueryTexture(ctx.texture.get(), NULL, NULL, NULL, &h);
+ return h;
+}
+void SDLContext::delay(int ms) const{
+ SDL_Delay(ms);
}
diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h
index f1ba8a6..6c57ef9 100644
--- a/src/crepe/facade/SDLContext.h
+++ b/src/crepe/facade/SDLContext.h
@@ -1,48 +1,155 @@
#pragma once
+#include <SDL2/SDL_keycode.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_video.h>
+#include <functional>
+#include <memory>
+#include <string>
#include "../api/Sprite.h"
#include "../api/Transform.h"
-#include "../system/RenderSystem.h"
+#include "api/Camera.h"
+
+// FIXME: this needs to be removed
+const int SCREEN_WIDTH = 640;
+const int SCREEN_HEIGHT = 480;
namespace crepe {
+// TODO: SDL_Keycode is defined in a header not distributed with crepe, which
+// means this typedef is unusable when crepe is packaged. Wouter will fix this
+// later.
+typedef SDL_Keycode CREPE_KEYCODES;
+
class Texture;
+class LoopManager;
+
+/**
+ * \class SDLContext
+ * \brief Facade for the SDL library
+ *
+ * SDLContext is a singleton that handles the SDL window and renderer, provides methods
+ * for event handling, and rendering to the screen. It is never used directly by the user
+ */
class SDLContext {
public:
- // singleton
+ /**
+ * \brief Gets the singleton instance of SDLContext.
+ * \return Reference to the SDLContext instance.
+ */
static SDLContext & get_instance();
+
SDLContext(const SDLContext &) = delete;
SDLContext(SDLContext &&) = delete;
SDLContext & operator=(const SDLContext &) = delete;
SDLContext & operator=(SDLContext &&) = delete;
- //TODO decide events wouter?
-
private:
+ //! will only use handle_events
+ friend class LoopManager;
+ /**
+ * \brief Handles SDL events such as window close and input.
+ * \param running Reference to a boolean flag that controls the main loop.
+ */
void handle_events(bool & running);
private:
+ //! Will only use get_ticks
+ friend class AnimatorSystem;
+ friend class LoopTimer;
+ /**
+ * \brief Gets the current SDL ticks since the program started.
+ * \return Current ticks in milliseconds as a constant uint64_t.
+ */
+ uint64_t get_ticks() const;
+ /**
+ * \brief Pauses the execution for a specified duration.
+ *
+ * This function uses SDL's delay function to halt the program execution
+ * for a given number of milliseconds, allowing for frame rate control
+ * or other timing-related functionality.
+ *
+ * \param ms Duration of the delay in milliseconds.
+ */
+ void delay(int ms) const;
+private:
+ /**
+ * \brief Constructs an SDLContext instance.
+ * Initializes SDL, creates a window and renderer.
+ */
SDLContext();
- virtual ~SDLContext();
+
+ /**
+ * \brief Destroys the SDLContext instance.
+ * Cleans up SDL resources, including the window and renderer.
+ */
+ ~SDLContext();
private:
+ //! Will use the funtions: texture_from_path, get_width,get_height.
friend class Texture;
- SDL_Texture * texture_from_path(const char *);
- //SDL_Texture* setTextureFromPath(const char*, SDL_Rect& clip, const int row, const int col);
+
+ //! Will use the funtions: texture_from_path, get_width,get_height.
+ friend class Animator;
+
+ /**
+ * \brief Loads a texture from a file path.
+ * \param path Path to the image file.
+ * \return Pointer to the created SDL_Texture.
+ */
+ std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>>
+ texture_from_path(const std::string & path);
+ /**
+ * \brief Gets the width of a texture.
+ * \param texture Reference to the Texture object.
+ * \return Width of the texture as an integer.
+ */
+ int get_width(const Texture &) const;
+
+ /**
+ * \brief Gets the height of a texture.
+ * \param texture Reference to the Texture object.
+ * \return Height of the texture as an integer.
+ */
+ int get_height(const Texture &) const;
private:
+ //! Will use draw,clear_screen, present_screen, camera.
friend class RenderSystem;
- void draw(const Sprite &, const Transform &);
+
+ /**
+ * \brief Draws a sprite to the screen using the specified transform and camera.
+ * \param sprite Reference to the Sprite to draw.
+ * \param transform Reference to the Transform for positioning.
+ * \param camera Reference to the Camera for view adjustments.
+ */
+ void draw(const Sprite & sprite, const Transform & transform,
+ const Camera & camera);
+
+ //! Clears the screen, preparing for a new frame.
void clear_screen();
+
+ //! Presents the rendered frame to the screen.
void present_screen();
+ /**
+ * \brief Sets the current camera for rendering.
+ * \param camera Reference to the Camera object.
+ */
+ void camera(const Camera & camera);
+
private:
- SDL_Window * game_window = nullptr;
- SDL_Renderer * game_renderer = nullptr;
+ //! sdl Window
+ std::unique_ptr<SDL_Window, std::function<void(SDL_Window *)>> game_window;
+
+ //! renderer for the crepe engine
+ std::unique_ptr<SDL_Renderer, std::function<void(SDL_Renderer *)>>
+ game_renderer;
+
+ //! viewport for the camera window
+ SDL_Rect viewport = {0, 0, 640, 480};
};
} // namespace crepe