diff options
Diffstat (limited to 'src/crepe/facade')
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 144 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 126 |
2 files changed, 201 insertions, 69 deletions
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 |