#pragma once #include #include // Para array #include // Para default_delete, shared_ptr, __shared_pt... #include // Para iota #include // Para string #include // Para move #include "utils/utils.hpp" // Para PaletteColor // Alias using Palette = std::array; using SubPalette = std::array; // Carga una paleta desde un archivo .gif Palette loadPalette(const std::string& file_path); // Carga una paleta desde un archivo .pal Palette readPalFile(const std::string& file_path); struct SurfaceData { std::shared_ptr data; // Usa std::shared_ptr para gestión automática float width; // Ancho de la imagen float height; // Alto de la imagen // Constructor por defecto SurfaceData() : data(nullptr), width(0), height(0) {} // Constructor que inicializa dimensiones y asigna memoria SurfaceData(float w, float h) : data(std::shared_ptr(new Uint8[static_cast(w * h)](), std::default_delete())), width(w), height(h) {} // Constructor para inicializar directamente con datos SurfaceData(float w, float h, std::shared_ptr pixels) : data(std::move(pixels)), width(w), height(h) {} // Constructor de movimiento SurfaceData(SurfaceData&& other) noexcept = default; // Operador de movimiento SurfaceData& operator=(SurfaceData&& other) noexcept = default; // Evita copias accidentales SurfaceData(const SurfaceData&) = delete; SurfaceData& operator=(const SurfaceData&) = delete; }; class Surface { private: std::shared_ptr surface_data_; // Datos a dibujar Palette palette_; // Paleta para volcar la SurfaceData a una Textura SubPalette sub_palette_; // Paleta para reindexar colores int transparent_color_; // Indice de la paleta que se omite en la copia de datos public: // Constructor Surface(int w, int h); explicit Surface(const std::string& file_path); // Destructor ~Surface() = default; // Carga una SurfaceData desde un archivo static SurfaceData loadSurface(const std::string& file_path); // Carga una paleta desde un archivo void loadPalette(const std::string& file_path); void loadPalette(Palette palette); // Copia una región de la SurfaceData de origen a la SurfaceData de destino void render(float dx, float dy, float sx, float sy, float w, float h); void render(int x, int y, SDL_FRect* clip = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); void render(SDL_FRect* src_rect = nullptr, SDL_FRect* dst_rect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro void renderWithColorReplace(int x, int y, Uint8 source_color = 0, Uint8 target_color = 0, SDL_FRect* src_rect = nullptr, SDL_FlipMode flip = SDL_FLIP_NONE); // Establece un color en la paleta void setColor(int index, Uint32 color); // Rellena la SurfaceData con un color void clear(Uint8 color); // Vuelca la SurfaceData a una textura void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture); void copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* src_rect, SDL_FRect* dest_rect); // Realiza un efecto de fundido en las paletas bool fadePalette(); bool fadeSubPalette(Uint32 delay = 0); // Pone un pixel en la SurfaceData void putPixel(int x, int y, Uint8 color); // Obtiene el color de un pixel de la surface_data Uint8 getPixel(int x, int y); // Dibuja un rectangulo relleno void fillRect(const SDL_FRect* rect, Uint8 color); // Dibuja el borde de un rectangulo void drawRectBorder(const SDL_FRect* rect, Uint8 color); // Dibuja una linea void drawLine(float x1, float y1, float x2, float y2, Uint8 color); // Metodos para gestionar surface_data_ std::shared_ptr getSurfaceData() const { return surface_data_; } void setSurfaceData(std::shared_ptr new_data) { surface_data_ = new_data; } // Obtien ancho y alto float getWidth() const { return surface_data_->width; } float getHeight() const { return surface_data_->height; } // Color transparente Uint8 getTransparentColor() const { return transparent_color_; } void setTransparentColor(Uint8 color = 255) { transparent_color_ = color; } // Paleta void setPalette(const std::array& palette) { palette_ = palette; } // Inicializa la sub paleta static void initializeSubPalette(SubPalette& palette) { std::iota(palette.begin(), palette.end(), 0); } };