#pragma once #include #include #include #include #include #include #include #include #include "../api/Sprite.h" #include "../api/Transform.h" #include "api/Camera.h" #include "api/Config.h" #include "types.h" 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 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: /** * \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; 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; //! Will only use delay 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(); /** * \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; /** * \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> 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; /** * \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 cam_pos position of the current camera in the scene * \param cam_scale multiplier for the world to screen */ void draw(const Sprite & sprite, const Transform & transform, const vec2 & cam_pos, const vec2 & cam_scale); /** * \brief Draws a particle to the screen using the specified parameters * * \param sprite Referenceto the sprite to draw * \param pos particle position in world units * \param angle particle angle in degrees * \param cam_pos camera position in world units * \param img_scale scalar multiplier to increase image size * \param cam_scale camera scalar for world to screen */ void draw_particle(const Sprite & sprite, const vec2 & pos, const double & angle, const vec2 & cam_pos, const double & img_scale, const vec2 & cam_scale); //! Clears the screen, preparing for a new frame. void clear_screen(); //! Presents the rendered frame to the screen. void present_screen(); /** * \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, vec2 & scale); private: /** * \brief calculates the sqaure size of the image * * \param sprite Reference to the sprite to calculate the rectangle * \return sdl rectangle to draw a src image */ SDL_Rect get_src_rect(const Sprite & sprite) const; /** * \brief calculates the sqaure size of the image for destination * * \param sprite Reference to the sprite to calculate rectangle * \param pos the pos in world units * \param cam_pos the camera position in world units * \param img_scale the image multiplier for increasing img size * \param scale the multiplier for world to screen * \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 vec2 & cam_pos, const double & img_scale, const vec2 & scale) const; private: //! sdl Window std::unique_ptr> game_window; //! renderer for the crepe engine std::unique_ptr> game_renderer; //! viewport for the camera window vec2 window = Config::get_instance().win_set.def_size; }; } // namespace crepe