From 5ff04daf203e844cb762af3bd7f8664a550fc8fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20Valor=20Mart=C3=ADnez?= Date: Fri, 28 Feb 2025 22:58:01 +0100 Subject: [PATCH] gonna fer un commit per si reventa algo: estic a meitat implementar surfaces --- data/test.gif | Bin 0 -> 630 bytes source/director.cpp | 3 + source/game.cpp | 4 + source/game.h | 2 + source/{gif.c => gif.cpp} | 87 +------------- source/gif.h | 65 +++++++++++ source/paleta.cpp | 2 +- source/screen.cpp | 59 ++++++---- source/screen.h | 23 ++-- source/surface.cpp | 230 ++++++++++++++++++++++++++++++++++++++ source/surface.h | 108 ++++++++++++++++++ source/texture.h | 6 +- source/title.cpp | 41 +++---- source/title.h | 38 +++---- 14 files changed, 511 insertions(+), 157 deletions(-) create mode 100644 data/test.gif rename source/{gif.c => gif.cpp} (87%) create mode 100644 source/gif.h create mode 100644 source/surface.cpp create mode 100644 source/surface.h diff --git a/data/test.gif b/data/test.gif new file mode 100644 index 0000000000000000000000000000000000000000..4fd9371af38b4dd2218a7078a5c6bb6ab41c49b2 GIT binary patch literal 630 zcmV-+0*U=cNk%v~VL$*t0HOc@00000007Vz7U>>i&D=Tv>pL+Uk^lezA^8Le3IG5A zEC2ui06+jh000C3IJ#rjk4fdKeQxT_S!b1jky=4Okfz?t^OcX_05@pkt)MHDArMg<=Vr9GEBe<3(e^=}ByPdg% zPv$i>gc($qH48>rI1)xF)c*eu}V z3gF@5-08`|=;Q0`^4I1Z@5A%?-SzhE=lTG>xf8blUBH0+lzB6F5MV-lzZf>u_mF|a zgPW|;BbaUfqAF$}r=j8&$(TowC{r@4^|7SIhALyq)F=QV!kIWjBC|O!r_YqWUON0q zRHIOeCXp09?Yz2D*RtiC6)st=7X>C3DHtr_0Ak%1)+%q+V#ba0M&67#a=dV# z(=m0-xwPlYAMIu~eR^|fk1bcTHtQNS%&(+pTh;6rHoeTe5x?E-+4sI>cvU{0YXQHfJDyWC&;S4c literal 0 HcmV?d00001 diff --git a/source/director.cpp b/source/director.cpp index 47a1d5a..e69d573 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -395,6 +395,9 @@ bool Director::setFileList() // Datos Asset::get()->add(prefix + "/data/input/gamecontrollerdb.txt", AssetType::DATA); + + // Test + Asset::get()->add(prefix + "/data/test.gif", AssetType::DATA); // Ficheros de sistema Asset::get()->add(system_folder_ + "/config.txt", AssetType::DATA, false, true); diff --git a/source/game.cpp b/source/game.cpp index ecd89c1..c571aa3 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -24,6 +24,7 @@ #include "notifier.h" #include "global_inputs.h" #include "global_events.h" +#include "surface.h" // Constructor Game::Game() @@ -36,6 +37,7 @@ Game::Game() cheevos_(Cheevos::get()) { // Inicia algunas variables + std::make_shared(Screen::get()->getGameSurface(), "test.gif"); board_ = std::make_shared(); board_->ini_clock = SDL_GetTicks(); #ifdef DEBUG @@ -258,8 +260,10 @@ void Game::update() // Pinta los objetos en pantalla void Game::render() { + // Prepara para dibujar el frame screen_->start(); + test_surface_->render(0, 0, 10, 10, 64, 64); // Dibuja los elementos del juego en orden room_->renderMap(); diff --git a/source/game.h b/source/game.h index 1d113cb..24c42a7 100644 --- a/source/game.h +++ b/source/game.h @@ -8,6 +8,7 @@ #include "player.h" // Para playerSpawn_t #include "scoreboard.h" // Para board_t #include "room.h" +#include "surface.h" class Asset; class Cheevos; class Debug; @@ -42,6 +43,7 @@ private: std::shared_ptr scoreboard_; // Objeto encargado de gestionar el marcador std::shared_ptr stats_; // Objeto encargado de gestionar las estadísticas SDL_Texture *room_name_texture_; // Textura para escribir el nombre de la habitación + std::shared_ptr test_surface_; // Variables JA_Music_t *music_; // Musica que suena durante el juego diff --git a/source/gif.c b/source/gif.cpp similarity index 87% rename from source/gif.c rename to source/gif.cpp index f029375..f0f6fbb 100644 --- a/source/gif.c +++ b/source/gif.cpp @@ -1,94 +1,9 @@ +#include "gif.h" #include #include #include #include -#define EXTENSION_INTRODUCER 0x21 -#define IMAGE_DESCRIPTOR 0x2C -#define TRAILER 0x3B - -#define GRAPHIC_CONTROL 0xF9 -#define APPLICATION_EXTENSION 0xFF -#define COMMENT_EXTENSION 0xFE -#define PLAINTEXT_EXTENSION 0x01 - -#define READ(dst, size) memcpy(dst, buffer, size); buffer += size - -typedef struct -{ - unsigned short width; - unsigned short height; - unsigned char fields; - unsigned char background_color_index; - unsigned char pixel_aspect_ratio; -} -screen_descriptor_t; - -typedef struct -{ - unsigned char r; - unsigned char g; - unsigned char b; -} -rgb; - -typedef struct -{ - unsigned short image_left_position; - unsigned short image_top_position; - unsigned short image_width; - unsigned short image_height; - unsigned char fields; -} -image_descriptor_t; - -typedef struct -{ - unsigned char byte; - int prev; - int len; -} -dictionary_entry_t; - -typedef struct -{ - unsigned char extension_code; - unsigned char block_size; -} -extension_t; - -typedef struct -{ - unsigned char fields; - unsigned short delay_time; - unsigned char transparent_color_index; -} -graphic_control_extension_t; - -typedef struct -{ - unsigned char application_id[ 8 ]; - unsigned char version[ 3 ]; -} -application_extension_t; - -typedef struct -{ - unsigned short left; - unsigned short top; - unsigned short width; - unsigned short height; - unsigned char cell_width; - unsigned char cell_height; - unsigned char foreground_color; - unsigned char background_color; -} -plaintext_extension_t; - -//static unsigned short width = 0; -//static unsigned short height = 0; -//static unsigned char* uncompressed_data = NULL; - void uncompress( int code_length, const unsigned char *input, int input_length, diff --git a/source/gif.h b/source/gif.h new file mode 100644 index 0000000..ba6f670 --- /dev/null +++ b/source/gif.h @@ -0,0 +1,65 @@ +#pragma once + +#include + +#define EXTENSION_INTRODUCER 0x21 +#define IMAGE_DESCRIPTOR 0x2C +#define TRAILER 0x3B +#define GRAPHIC_CONTROL 0xF9 +#define APPLICATION_EXTENSION 0xFF +#define COMMENT_EXTENSION 0xFE +#define PLAINTEXT_EXTENSION 0x01 + +#define READ(dst, size) memcpy(dst, buffer, size); buffer += size + +typedef struct { + unsigned short width; + unsigned short height; + unsigned char fields; + unsigned char background_color_index; + unsigned char pixel_aspect_ratio; +} screen_descriptor_t; + +typedef struct { + unsigned char r, g, b; +} rgb; + +typedef struct { + unsigned short image_left_position; + unsigned short image_top_position; + unsigned short image_width; + unsigned short image_height; + unsigned char fields; +} image_descriptor_t; + +typedef struct { + unsigned char byte; + int prev; + int len; +} dictionary_entry_t; + +typedef struct { + unsigned char extension_code; + unsigned char block_size; +} extension_t; + +typedef struct { + unsigned char fields; + unsigned short delay_time; + unsigned char transparent_color_index; +} graphic_control_extension_t; + +typedef struct { + unsigned char application_id[8]; + unsigned char version[3]; +} application_extension_t; + +typedef struct { + unsigned short left, top, width, height; + unsigned char cell_width, cell_height; + unsigned char foreground_color, background_color; +} plaintext_extension_t; + +void uncompress(int code_length, const unsigned char *input, int input_length, unsigned char *out); +uint32_t* LoadPalette(unsigned char *buffer); +unsigned char* LoadGif(unsigned char *buffer, unsigned short* w, unsigned short* h); \ No newline at end of file diff --git a/source/paleta.cpp b/source/paleta.cpp index e36fc13..e545916 100644 --- a/source/paleta.cpp +++ b/source/paleta.cpp @@ -4,7 +4,7 @@ #include // Para SEEK_END, SEEK_SET #include // Para NULL, fseek, fclose, fopen, fread, ftell #include // Para malloc, free -#include "gif.c" // Para LoadGif, LoadPalette +#include "gif.h" // Para LoadGif, LoadPalette struct jSurface_s { diff --git a/source/screen.cpp b/source/screen.cpp index 368af34..dc973f0 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -13,6 +13,7 @@ #include "notifier.h" // Para Notify #include "options.h" #include "mouse.h" +#include "surface.h" // [SINGLETON] Screen *Screen::screen_ = nullptr; @@ -50,27 +51,41 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) // Establece el modo de escalado SDL_RenderSetIntegerScale(renderer_, options.video.integer_scale ? SDL_TRUE : SDL_FALSE); - // Crea la textura donde se dibujan los graficos del juego - game_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height); - if (game_canvas_ == nullptr) + // Crea la textura donde se vuelcan las surfaces + surface_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, options.game.width, options.game.height); + if (surface_texture_ == nullptr) { if (options.console) { - std::cout << "gameCanvas could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + std::cout << "surface_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + } + } + + // Crea la textura donde se dibujan los graficos del juego + game_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width, options.game.height); + if (game_texture_ == nullptr) + { + if (options.console) + { + std::cout << "game_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } } // Crea la textura donde se dibuja el borde que rodea el area de juego - border_canvas_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2); - if (border_canvas_ == nullptr) + border_texture_ = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, options.game.width + options.video.border.width * 2, options.game.height + options.video.border.height * 2); + if (border_texture_ == nullptr) { if (options.console) { - std::cout << "borderCanvas could not be created!\nSDL Error: " << SDL_GetError() << std::endl; + std::cout << "border_texture_ could not be created!\nSDL Error: " << SDL_GetError() << std::endl; } } setBorderColor(border_color_); + // Crea la surface donde se pinta el juego + surface_ = std::make_shared(nullptr, options.game.width, options.game.height); + surface_->loadPalette(Asset::get()->get("test.gif")); + // Establece el modo de video setVideoMode(options.video.mode); @@ -82,8 +97,9 @@ Screen::Screen(SDL_Window *window, SDL_Renderer *renderer) // Destructor Screen::~Screen() { - SDL_DestroyTexture(game_canvas_); - SDL_DestroyTexture(border_canvas_); + SDL_DestroyTexture(surface_texture_); + SDL_DestroyTexture(game_texture_); + SDL_DestroyTexture(border_texture_); } // Limpia la pantalla @@ -96,13 +112,14 @@ void Screen::clean(Color color) // Prepara para empezar a dibujar en la textura de juego void Screen::start() { - SDL_SetRenderTarget(renderer_, game_canvas_); + surface_->clear(surface_->getSurface(), surface_->getTransparentColor()); + SDL_SetRenderTarget(renderer_, game_texture_); } // Prepara para empezar a dibujar en la textura del borde void Screen::startDrawOnBorder() { - SDL_SetRenderTarget(renderer_, border_canvas_); + SDL_SetRenderTarget(renderer_, border_texture_); } // Vuelca el contenido del renderizador en pantalla @@ -111,6 +128,8 @@ void Screen::render() // Renderiza sobre gameCanvas los overlays renderNotifications(); + surface_->copyToTexture(renderer_, game_texture_); + // Si está el borde activo, vuelca gameCanvas sobre borderCanvas if (options.video.border.enabled) { @@ -174,11 +193,11 @@ void Screen::setVideoMode(int videoMode) if (options.video.border.enabled) { - shader::init(window_, border_canvas_, source.c_str()); + shader::init(window_, border_texture_, source.c_str()); } else { - shader::init(window_, game_canvas_, source.c_str()); + shader::init(window_, game_texture_, source.c_str()); } } } @@ -233,7 +252,7 @@ void Screen::setBorderColor(Color color) { border_color_ = color; auto temp = SDL_GetRenderTarget(renderer_); - SDL_SetRenderTarget(renderer_, border_canvas_); + SDL_SetRenderTarget(renderer_, border_texture_); SDL_SetRenderDrawColor(renderer_, border_color_.r, border_color_.g, border_color_.b, 0xFF); SDL_RenderClear(renderer_); SDL_SetRenderTarget(renderer_, temp); @@ -279,8 +298,8 @@ void Screen::renderNotifications() void Screen::gameCanvasToBorderCanvas() { auto temp = SDL_GetRenderTarget(renderer_); - SDL_SetRenderTarget(renderer_, border_canvas_); - SDL_RenderCopy(renderer_, game_canvas_, nullptr, &game_canvas_rect_); + SDL_SetRenderTarget(renderer_, border_texture_); + SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_); SDL_SetRenderTarget(renderer_, temp); } @@ -300,11 +319,11 @@ void Screen::renderPresent() { if (options.video.border.enabled) { - SDL_RenderCopy(renderer_, border_canvas_, nullptr, nullptr); + SDL_RenderCopy(renderer_, border_texture_, nullptr, nullptr); } else { - SDL_RenderCopy(renderer_, game_canvas_, nullptr, &game_canvas_rect_); + SDL_RenderCopy(renderer_, game_texture_, nullptr, &game_texture_rect_); } SDL_RenderPresent(renderer_); } @@ -364,7 +383,7 @@ void Screen::adjustWindowSize() // Ajusta game_canvas_rect_ void Screen::adjustGameCanvasRect() { - game_canvas_rect_ = { + game_texture_rect_ = { options.video.border.enabled ? options.video.border.width : 0, options.video.border.enabled ? options.video.border.height : 0, options.game.width, @@ -388,7 +407,7 @@ int Screen::getMaxZoom() // Calcula el máximo factor de zoom que se puede aplicar a la pantalla const int max_zoom = std::min(DM.w / window_width_, (DM.h - WINDOWS_DECORATIONS_) / window_height_); - + // Normaliza los valores de zoom options.window.zoom = std::min(options.window.zoom, max_zoom); diff --git a/source/screen.h b/source/screen.h index 1c5060b..4383d72 100644 --- a/source/screen.h +++ b/source/screen.h @@ -6,7 +6,9 @@ #include // for Uint32 #include // for SDL_Window #include // for vector +#include // for shared_ptr #include "utils.h" // for Color +#include "surface.h" // Tipos de filtro enum class ScreenFilter : Uint32 @@ -25,16 +27,18 @@ private: static Screen *screen_; // Objetos y punteros - SDL_Window *window_; // Ventana de la aplicación - SDL_Renderer *renderer_; // El renderizador de la ventana - SDL_Texture *game_canvas_; // Textura donde se dibuja el juego - SDL_Texture *border_canvas_; // Textura donde se dibuja el borde del juego + SDL_Window *window_; // Ventana de la aplicación + SDL_Renderer *renderer_; // El renderizador de la ventana + SDL_Texture *surface_texture_; // Textura donde se dibuja el juego + SDL_Texture *game_texture_; // Textura donde se dibuja el juego + SDL_Texture *border_texture_; // Textura donde se dibuja el borde del juego + std::shared_ptr surface_; // Objeto para trabajar con surfaces // Variables - int window_width_; // Ancho de la pantalla o ventana - int window_height_; // Alto de la pantalla o ventana - SDL_Rect game_canvas_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana - Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla + int window_width_; // Ancho de la pantalla o ventana + int window_height_; // Alto de la pantalla o ventana + SDL_Rect game_texture_rect_; // Coordenadas donde se va a dibujar la textura del juego sobre la pantalla o ventana + Color border_color_; // Color del borde añadido a la textura de juego para rellenar la pantalla // Dibuja las notificaciones void renderNotifications(); @@ -131,4 +135,7 @@ public: // Getters SDL_Renderer *getRenderer() { return renderer_; } + std::shared_ptr getGameSurface() { return surface_->getSurface(); } + SDL_Texture *getGameTexture() { return game_texture_; }; + SDL_Texture *getBorderTexture() { return border_texture_; } }; \ No newline at end of file diff --git a/source/surface.cpp b/source/surface.cpp new file mode 100644 index 0000000..8fff6c9 --- /dev/null +++ b/source/surface.cpp @@ -0,0 +1,230 @@ +#include "surface.h" +#include // Para SDL_PIXELFORMAT_ARGB8888 +#include // Para SDL_Rect +#include // Para std::ifstream +#include // Para std::cerr +#include // Para std::vector +#include // For exceptions +#include "gif.h" // Para LoadGif, LoadPalette +#include // Para std::shared_ptr +#include // Para std::copy +#include "asset.h" + +Surface::Surface(std::shared_ptr surface_dest, int w, int h) + : surface_dest_(surface_dest), + surface_(std::make_shared(w, h)), + transparent_color_(0) {} + +Surface::Surface(std::shared_ptr surface_dest, std::string file_path) + : surface_dest_(surface_dest), + surface_(std::make_shared(loadSurface(Asset::get()->get(file_path)))), + transparent_color_(0) {} + +Surface::~Surface() {} + +// Carga una superficie desde un archivo +SurfaceData Surface::loadSurface(const std::string &file_path) +{ + std::ifstream file(file_path, std::ios::binary | std::ios::ate); + + if (!file.is_open()) + { + std::cerr << "Error opening file: " << file_path << std::endl; + throw std::runtime_error("Error opening file"); + } + + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector buffer(size); + if (!file.read((char *)buffer.data(), size)) + { + std::cerr << "Error reading file: " << file_path << std::endl; + throw std::runtime_error("Error reading file"); + } + + Uint16 w, h; + Uint8 *pixels = LoadGif(buffer.data(), &w, &h); + if (pixels == nullptr) + { + std::cerr << "Error loading GIF from file: " << file_path << std::endl; + throw std::runtime_error("Error loading GIF"); + } + + // Crear y devolver directamente el objeto SurfaceData + return SurfaceData(w, h, pixels); +} + +// Carga una paleta desde un archivo +void Surface::loadPalette(const std::string &file_path) +{ + // Abrir el archivo en modo binario + std::ifstream file(file_path, std::ios::binary | std::ios::ate); + if (!file.is_open()) + { + throw std::runtime_error("Error opening file: " + file_path); + } + + // Leer el contenido del archivo en un buffer + std::streamsize size = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector buffer(size); + if (!file.read(reinterpret_cast(buffer.data()), size)) + { + throw std::runtime_error("Error reading file: " + file_path); + } + + // Cargar la paleta usando los datos del buffer + std::unique_ptr pal(LoadPalette(buffer.data())); + if (pal == nullptr) + { + throw std::runtime_error("Error loading palette from file: " + file_path); + } + + // Copiar los datos de la paleta al std::array + std::copy(pal.get(), pal.get() + palette_.size(), palette_.begin()); +} + +// Establece un color en la paleta +void Surface::setColor(int index, Uint32 color) +{ + palette_.at(index) = color; +} + +// Limpia la superficie de destino con un color +void Surface::clear(std::shared_ptr surface, Uint8 color) +{ + const size_t total_pixels = surface->width * surface->height; + std::fill(surface->data, surface->data + total_pixels, color); +} + +// Pone un pixel en la superficie de destino +void Surface::putPixel(int x, int y, Uint8 color) +{ + if (color == transparent_color_) + { + return; // Color transparente, no dibujar + } + + if (x < 0 || y < 0 || x >= surface_dest_->width || y >= surface_dest_->height) + { + return; // Coordenadas fuera de rango + } + + const int index = x + y * surface_dest_->width; + surface_dest_->data[index] = color; +} + +// Obtiene el color de un pixel de la superficie de origen +Uint8 Surface::getPixel(int x, int y) +{ + return surface_->data[x + y * surface_->width]; +} + +// Copia una región de la superficie de origen a la de destino +void Surface::render(int dx, int dy, int sx, int sy, int w, int h) +{ + // Limitar la región para evitar accesos fuera de rango + w = std::min(w, surface_->width - sx); + h = std::min(h, surface_->height - sy); + w = std::min(w, surface_dest_->width - dx); + h = std::min(h, surface_dest_->height - dy); + + for (int iy = 0; iy < h; ++iy) + { + for (int ix = 0; ix < w; ++ix) + { + Uint8 color = surface_->data[(sx + ix) + (sy + iy) * surface_->width]; + if (color != transparent_color_) // Opcional: Ignorar píxeles transparentes + { + surface_dest_->data[(dx + ix) + (dy + iy) * surface_dest_->width] = color; + } + } + } +} + +/* +// Vuelca la superficie a una textura +void Surface::flip(SDL_Renderer *renderer, SDL_Texture *texture) +{ + Uint32 *pixels; + int pitch; + SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch); + for (int i = 0; i < surface_.width * surface_.height; ++i) + { + pixels[i] = palette_[surface_.data[i]]; + } + SDL_UnlockTexture(texture); + SDL_RenderCopy(renderer, texture, nullptr, nullptr); + } + */ + +// Vuelca la superficie a una textura +void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + if (!renderer || !texture) + { + throw std::runtime_error("Renderer or texture is null."); + } + + if (surface_->width <= 0 || surface_->height <= 0 || !surface_->data) + { + throw std::runtime_error("Invalid surface dimensions or data."); + } + + Uint32 *pixels = nullptr; + int pitch = 0; + + // Bloquea la textura para modificar los píxeles directamente + if (SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch) != 0) + { + throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError())); + } + + // Convertir `pitch` de bytes a Uint32 (asegurando alineación correcta en hardware) + int row_stride = pitch / sizeof(Uint32); + + for (int y = 0; y < surface_->height; ++y) + { + for (int x = 0; x < surface_->width; ++x) + { + // Calcular la posición correcta en la textura teniendo en cuenta el stride + int texture_index = y * row_stride + x; + int surface_index = y * surface_->width + x; + + pixels[texture_index] = palette_[surface_->data[surface_index]]; + } + } + + SDL_UnlockTexture(texture); // Desbloquea la textura + + // Renderiza la textura en la pantalla completa + if (SDL_RenderCopy(renderer, texture, nullptr, nullptr) != 0) + { + throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError())); + } +} + +// Realiza un efecto de fundido en la paleta +bool Surface::fadePalette() +{ + // Verificar que el tamaño mínimo de palette_ sea adecuado + static constexpr int palette_size = 19; + if (sizeof(palette_) / sizeof(palette_[0]) < palette_size) + { + throw std::runtime_error("Palette size is insufficient for fadePalette operation."); + } + + // Desplazar colores (pares e impares) + for (int i = 18; i > 1; --i) + { + palette_[i] = palette_[i - 2]; + } + + // Ajustar el primer color + palette_[1] = palette_[0]; + + // Devolver si el índice 15 coincide con el índice 0 + return palette_[15] == palette_[0]; +} diff --git a/source/surface.h b/source/surface.h new file mode 100644 index 0000000..3b2cbf0 --- /dev/null +++ b/source/surface.h @@ -0,0 +1,108 @@ +#pragma once + +#include // Para SDL_Renderer +#include // Para Uint8, Uint32 +#include +#include +#include + +struct SurfaceData +{ + Uint8 *data; + Uint16 width; + Uint16 height; + + // Constructor por defecto + SurfaceData() : data(nullptr), width(0), height(0) {} + + // Constructor que inicializa dimensiones y asigna memoria + SurfaceData(Uint16 w, Uint16 h) + : data(new Uint8[w * h]()), width(w), height(h) {} + + // Constructor para inicializar directamente con datos + SurfaceData(Uint16 w, Uint16 h, Uint8 *pixels) + : data(pixels), width(w), height(h) {} + + // Destructor para liberar memoria + ~SurfaceData() { delete[] data; } + + // Evita copias accidentales (opcional para mayor seguridad) + SurfaceData(const SurfaceData &) = delete; + SurfaceData &operator=(const SurfaceData &) = delete; + + // Permite movimiento para evitar copias costosas + SurfaceData(SurfaceData &&other) noexcept + : data(other.data), width(other.width), height(other.height) + { + other.data = nullptr; + other.width = 0; + other.height = 0; + } + + SurfaceData &operator=(SurfaceData &&other) noexcept + { + if (this != &other) + { + delete[] data; + + data = other.data; + width = other.width; + height = other.height; + + other.data = nullptr; + other.width = 0; + other.height = 0; + } + return *this; + } +}; + +class Surface +{ +private: + std::shared_ptr surface_dest_; + std::shared_ptr surface_; + std::array palette_; + int transparent_color_; + + // Pone un pixel en la superficie de destino + void putPixel(int x, int y, Uint8 color); + + // Obtiene el color de un pixel de la superficie de origen + Uint8 getPixel(int x, int y); + +public: + // Constructor + Surface(std::shared_ptr surface_dest, int w, int h); + Surface(std::shared_ptr surface_dest, std::string file_path); + + // Destructor + ~Surface(); + + // Carga una superficie desde un archivo + SurfaceData loadSurface(const std::string &file_path); + + // Carga una paleta desde un archivo + void loadPalette(const std::string &file_path); + + // Copia una región de la superficie de origen a la de destino + void render(int dx, int dy, int sx, int sy, int w, int h); + + // Establece un color en la paleta + void setColor(int index, Uint32 color); + + // Limpia la superficie de destino con un color + void clear(std::shared_ptr surface, Uint8 color); + + // Vuelca la superficie a una textura + void copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture); + + // Realiza un efecto de fundido en la paleta + bool fadePalette(); + + // Getters + std::shared_ptr getSurface() const { return surface_; } + // std::shared_ptr getSurfaceDest() const { return surface_dest_; } + // std::array getPalette() const { return palette_; } + int getTransparentColor() const { return transparent_color_; } +}; diff --git a/source/texture.h b/source/texture.h index 95ad5cb..98f3709 100644 --- a/source/texture.h +++ b/source/texture.h @@ -11,7 +11,7 @@ struct Color; // Definiciones de tipos -struct Surface +/*struct Surface { std::shared_ptr data; Uint16 w, h; @@ -19,7 +19,7 @@ struct Surface // Constructor Surface(Uint16 width, Uint16 height, std::shared_ptr pixels) : data(pixels), w(width), h(height) {} -}; +};*/ class Texture { @@ -27,7 +27,7 @@ private: // Objetos y punteros SDL_Renderer *renderer_; // Renderizador donde dibujar la textura SDL_Texture *texture_ = nullptr; // La textura - std::shared_ptr surface_ = nullptr; // Surface para usar imagenes en formato gif con paleta + //std::shared_ptr surface_ = nullptr; // Surface para usar imagenes en formato gif con paleta // Variables std::string path_; // Ruta de la imagen de la textura diff --git a/source/title.cpp b/source/title.cpp index 6c5f028..3b49671 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -1,24 +1,25 @@ #include "title.h" -#include // for SDL_BLENDMODE_BLEND -#include // for SDL_GetError -#include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN -#include // for SDL_PIXELFORMAT_RGBA8888 -#include // for SDL_SCANCODE_1, SDL_SCANCODE_2 -#include // for SDL_GetTicks -#include // for basic_ostream, operator<<, cout, endl -#include "asset.h" // for Asset -#include "cheevos.h" // for Achievement, Cheevos -#include "defines.h" // for PLAY_AREA_CENTER_X, GAMECANVAS_WIDTH -#include "global_events.h" // for check -#include "global_inputs.h" // for check -#include "input.h" // for Input, inputs_e, REPEAT_FALSE, REPEA... -#include "options.h" // for Options, options, OptionsVideo, Sect... -#include "resource.h" // for Resource -#include "screen.h" // for Screen -#include "sprite.h" // for Sprite -#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR -#include "texture.h" // for Texture -#include "utils.h" // for Color, stringToColor, Palette +#include // for SDL_BLENDMODE_BLEND +#include // for SDL_GetError +#include // for SDL_PollEvent, SDL_Event, SDL_KEYDOWN +#include // for SDL_PIXELFORMAT_RGBA8888 +#include // for SDL_SCANCODE_1, SDL_SCANCODE_2 +#include // for SDL_GetTicks +#include // for basic_ostream, operator<<, cout, endl +#include "asset.h" // for Asset +#include "cheevos.h" // for Achievement, Cheevos +#include "defines.h" // for PLAY_AREA_CENTER_X, GAMECANVAS_WIDTH +#include "global_events.h" // for check +#include "global_inputs.h" // for check +#include "input.h" // for Input, inputs_e, REPEAT_FALSE, REPEA... +#include "options.h" // for Options, options, OptionsVideo, Sect... +#include "resource.h" // for Resource +#include "screen.h" // for Screen +#include "sprite.h" // for Sprite +#include "text.h" // for Text, TEXT_CENTER, TEXT_COLOR +#include "texture.h" // for Texture +#include "utils.h" // for Color, stringToColor, Palette +#include "paleta.h" // Constructor Title::Title() diff --git a/source/title.h b/source/title.h index 267b39f..3d3e533 100644 --- a/source/title.h +++ b/source/title.h @@ -1,18 +1,18 @@ #pragma once -#include // for SDL_Rect -#include // for SDL_Renderer, SDL_Texture -#include // for Uint32 -#include // for shared_ptr -#include // for string -#include // for vector -#include "paleta.h" // for jSurface -class Input; // lines 13-13 -class Resource; // lines 14-14 -class Screen; // lines 15-15 -class Sprite; // lines 16-16 -class Text; // lines 17-17 -class Texture; // lines 18-18 +#include // for SDL_Rect +#include // for SDL_Renderer, SDL_Texture +#include // for Uint32 +#include // for shared_ptr +#include // for string +#include // for vector +#include "paleta.h" // for jSurface +class Input; // lines 13-13 +class Resource; // lines 14-14 +class Screen; // lines 15-15 +class Sprite; // lines 16-16 +class Text; // lines 17-17 +class Texture; // lines 18-18 class Title { @@ -32,13 +32,13 @@ private: }; // Objetos y punteros - Screen *screen_; // Objeto encargado de dibujar en pantalla - SDL_Renderer *renderer_; // El renderizador de la ventana - Resource *resource_; // Objeto con los recursos - Input *input_; // Objeto pata gestionar la entrada + Screen *screen_; // Objeto encargado de dibujar en pantalla + SDL_Renderer *renderer_; // El renderizador de la ventana + Resource *resource_; // Objeto con los recursos + Input *input_; // Objeto pata gestionar la entrada std::shared_ptr texture_; // Textura con los graficos std::shared_ptr sprite_; // Sprite para manejar la textura - SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla + SDL_Texture *bg_texture_; // Textura para dibujar el fondo de la pantalla std::shared_ptr text_; // Objeto para escribir texto en pantalla std::shared_ptr info_text_; // Objeto para escribir texto en pantalla std::shared_ptr cheevos_texture_; // Textura con la lista de logros @@ -53,7 +53,7 @@ private: bool show_cheevos_ = false; // Indica si se muestra por pantalla el listado de logros SDL_Rect cheevos_texture_view_; // Zona visible de la textura con el listado de logros states_e state_; // Estado en el que se encuentra el bucle principal - jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga + jSurface loading_screen_; // Surface con los gráficos de la pantalla de carga // Actualiza las variables void update();