#pragma once #include #include #include #include "utils/defaults.hpp" class Screen { public: // Configuració typada de Screen. L'omple el Director des d'Options, // de manera que Screen no coneix YAML ni la capa Options directament. struct Config { int zoom{Defaults::Window::ZOOM}; bool fullscreen{Defaults::Window::FULLSCREEN}; bool vsync{Defaults::Video::VSYNC}; Defaults::ScalingMode scaling_mode{Defaults::Video::SCALING_MODE}; Defaults::TextureFilter texture_filter{Defaults::Video::TEXTURE_FILTER}; }; // Meyers singleton: la destrucció ocorre durant la termianció estàtica // (LIFO respecte a Resource::Cache). El SDL_Quit s'ha de registrar via // std::atexit ABANS de la primera crida a get(); així Screen::~Screen // (que crida SDL_Destroy*/SDL_QuitSubSystem) s'executa amb SDL encara viu. static auto get() -> Screen&; Screen(const Screen&) = delete; Screen(Screen&&) = delete; auto operator=(const Screen&) -> Screen& = delete; auto operator=(Screen&&) -> Screen& = delete; // Crea (o recrea) finestra, renderer i textura a partir de la config. // Imprescindible cridar-lo abans de qualsevol clear()/present(). void configure(const Config& config); void clear(std::uint8_t r = 0, std::uint8_t g = 0, std::uint8_t b = 0); void present(); [[nodiscard]] auto getRenderer() const -> SDL_Renderer* { return renderer_; } [[nodiscard]] auto getCanvasArgb() -> std::uint32_t* { return canvas_.data(); } [[nodiscard]] auto getCanvasWidth() const -> int { return canvas_width_; } [[nodiscard]] auto getCanvasHeight() const -> int { return canvas_height_; } private: Screen(); ~Screen(); void destroySdl(); void createSdl(); Config config_{}; SDL_Window* window_{nullptr}; SDL_Renderer* renderer_{nullptr}; SDL_Texture* game_texture_{nullptr}; int canvas_width_{0}; int canvas_height_{0}; std::vector canvas_; };