diff --git a/source/core/rendering/sprite/animated_sprite.cpp b/source/core/rendering/sprite/animated_sprite.cpp index 1f7b800..4075b61 100644 --- a/source/core/rendering/sprite/animated_sprite.cpp +++ b/source/core/rendering/sprite/animated_sprite.cpp @@ -134,7 +134,7 @@ AnimatedSprite::AnimatedSprite(std::shared_ptr surface, SDL_FRect pos) : MovingSprite(std::move(surface), pos) { // animations_ queda buit (protegit per el guard de animate()) if (surface_) { - clip_ = {.x = 0, .y = 0, .w = surface_->getWidth(), .h = surface_->getHeight()}; + clip_ = {.x = 0, .y = 0, .w = static_cast(surface_->getWidth()), .h = static_cast(surface_->getHeight())}; } } diff --git a/source/core/rendering/sprite/sprite.cpp b/source/core/rendering/sprite/sprite.cpp index 32ed45b..bbb683a 100644 --- a/source/core/rendering/sprite/sprite.cpp +++ b/source/core/rendering/sprite/sprite.cpp @@ -19,7 +19,7 @@ Sprite::Sprite() = default; Sprite::Sprite(std::shared_ptr surface) : surface_(std::move(surface)), - pos_{0.0F, 0.0F, surface_->getWidth(), surface_->getHeight()}, + pos_{0.0F, 0.0F, static_cast(surface_->getWidth()), static_cast(surface_->getHeight())}, clip_(pos_) {} // Muestra el sprite por pantalla diff --git a/source/core/rendering/surface.cpp b/source/core/rendering/surface.cpp index f5a25bb..98badc0 100644 --- a/source/core/rendering/surface.cpp +++ b/source/core/rendering/surface.cpp @@ -129,7 +129,7 @@ auto Surface::loadSurface(const std::string& file_path) -> SurfaceData { // Crear y devolver directamente el objeto SurfaceData printWithDots("Surface : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]"); - return {static_cast(w), static_cast(h), pixels}; + return {static_cast(w), static_cast(h), pixels}; } // Carga una paleta desde un archivo @@ -148,14 +148,14 @@ void Surface::setColor(int index, Uint32 color) { } // Rellena la superficie con un color -void Surface::clear(Uint8 color) { - const size_t TOTAL_PIXELS = surface_data_->width * surface_data_->height; +void Surface::clear(Uint8 color) { // NOLINT(readability-convert-member-functions-to-static) + const size_t TOTAL_PIXELS = static_cast(surface_data_->width) * static_cast(surface_data_->height); Uint8* data_ptr = surface_data_->data.get(); std::fill(data_ptr, data_ptr + TOTAL_PIXELS, color); } // Pone un pixel en la SurfaceData -void Surface::putPixel(int x, int y, Uint8 color) { +void Surface::putPixel(int x, int y, Uint8 color) { // NOLINT(readability-convert-member-functions-to-static) if (x < 0 || y < 0 || x >= surface_data_->width || y >= surface_data_->height) { return; // Coordenadas fuera de rango } @@ -165,39 +165,39 @@ void Surface::putPixel(int x, int y, Uint8 color) { } // Obtiene el color de un pixel de la surface_data -auto Surface::getPixel(int x, int y) -> Uint8 { return surface_data_->data.get()[x + (y * static_cast(surface_data_->width))]; } +auto Surface::getPixel(int x, int y) -> Uint8 { return surface_data_->data.get()[x + (y * surface_data_->width)]; } // Dibuja un rectangulo relleno -void Surface::fillRect(const SDL_FRect* rect, Uint8 color) { +void Surface::fillRect(const SDL_FRect* rect, Uint8 color) { // NOLINT(readability-convert-member-functions-to-static) // Limitar los valores del rectángulo al tamaño de la superficie float x_start = std::max(0.0F, rect->x); float y_start = std::max(0.0F, rect->y); - float x_end = std::min(rect->x + rect->w, surface_data_->width); - float y_end = std::min(rect->y + rect->h, surface_data_->height); + float x_end = std::min(rect->x + rect->w, static_cast(surface_data_->width)); + float y_end = std::min(rect->y + rect->h, static_cast(surface_data_->height)); // Rellenar fila a fila con memset (memoria contigua por fila) Uint8* data_ptr = surface_data_->data.get(); - const auto SURF_WIDTH = static_cast(surface_data_->width); - const auto ROW_WIDTH = static_cast(static_cast(x_end) - static_cast(x_start)); + const int SURF_WIDTH = surface_data_->width; + const int ROW_WIDTH = static_cast(x_end) - static_cast(x_start); for (int y = static_cast(y_start); y < static_cast(y_end); ++y) { - std::memset(data_ptr + (static_cast(y) * SURF_WIDTH) + static_cast(x_start), color, ROW_WIDTH); + std::memset(data_ptr + (y * SURF_WIDTH) + static_cast(x_start), color, ROW_WIDTH); } } // Dibuja el borde de un rectangulo -void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { +void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { // NOLINT(readability-convert-member-functions-to-static) // Limitar los valores del rectángulo al tamaño de la superficie float x_start = std::max(0.0F, rect->x); float y_start = std::max(0.0F, rect->y); - float x_end = std::min(rect->x + rect->w, surface_data_->width); - float y_end = std::min(rect->y + rect->h, surface_data_->height); + float x_end = std::min(rect->x + rect->w, static_cast(surface_data_->width)); + float y_end = std::min(rect->y + rect->h, static_cast(surface_data_->height)); // Dibujar bordes horizontales con memset (líneas contiguas en memoria) Uint8* data_ptr = surface_data_->data.get(); - const auto SURF_WIDTH = static_cast(surface_data_->width); - const auto ROW_WIDTH = static_cast(static_cast(x_end) - static_cast(x_start)); - std::memset(data_ptr + (static_cast(y_start) * SURF_WIDTH) + static_cast(x_start), color, ROW_WIDTH); - std::memset(data_ptr + ((static_cast(y_end) - 1) * SURF_WIDTH) + static_cast(x_start), color, ROW_WIDTH); + const int SURF_WIDTH = surface_data_->width; + const int ROW_WIDTH = static_cast(x_end) - static_cast(x_start); + std::memset(data_ptr + (static_cast(y_start) * SURF_WIDTH) + static_cast(x_start), color, ROW_WIDTH); + std::memset(data_ptr + ((static_cast(y_end) - 1) * SURF_WIDTH) + static_cast(x_start), color, ROW_WIDTH); // Dibujar bordes verticales for (int y = y_start; y < y_end; ++y) { @@ -211,72 +211,38 @@ void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) { } } -// Dibuja una linea -void Surface::drawLine(float x1, float y1, float x2, float y2, Uint8 color) { - // Calcula las diferencias - float dx = std::abs(x2 - x1); - float dy = std::abs(y2 - y1); +// Dibuja una linea (Bresenham en enteros) +void Surface::drawLine(float x1, float y1, float x2, float y2, Uint8 color) { // NOLINT(readability-convert-member-functions-to-static) + int ix1 = static_cast(std::lround(x1)); + int iy1 = static_cast(std::lround(y1)); + const int IX2 = static_cast(std::lround(x2)); + const int IY2 = static_cast(std::lround(y2)); - // Determina la dirección del incremento - float sx = (x1 < x2) ? 1 : -1; - float sy = (y1 < y2) ? 1 : -1; + const int DX = std::abs(IX2 - ix1); + const int DY = std::abs(IY2 - iy1); + const int SX = (ix1 < IX2) ? 1 : -1; + const int SY = (iy1 < IY2) ? 1 : -1; - float err = dx - dy; + const int SURF_W = surface_data_->width; + const int SURF_H = surface_data_->height; + Uint8* data_ptr = surface_data_->data.get(); + int err = DX - DY; while (true) { - // Asegúrate de no dibujar fuera de los límites de la superficie - if (x1 >= 0 && x1 < surface_data_->width && y1 >= 0 && y1 < surface_data_->height) { - surface_data_->data.get()[static_cast(x1 + (y1 * surface_data_->width))] = color; + if (ix1 >= 0 && ix1 < SURF_W && iy1 >= 0 && iy1 < SURF_H) { + data_ptr[ix1 + (iy1 * SURF_W)] = color; } - - // Si alcanzamos el punto final, salimos - if (x1 == x2 && y1 == y2) { + if (ix1 == IX2 && iy1 == IY2) { break; } - int e2 = 2 * err; - if (e2 > -dy) { - err -= dy; - x1 += sx; + if (e2 > -DY) { + err -= DY; + ix1 += SX; } - if (e2 < dx) { - err += dx; - y1 += sy; - } - } -} - -void Surface::render(float dx, float dy, float sx, float sy, float w, float h) { // NOLINT(readability-make-member-function-const) - auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData(); - - // Aplicar render offset - dx += Screen::get()->getRenderOffsetX(); - dy += Screen::get()->getRenderOffsetY(); - - // Limitar la región para evitar accesos fuera de rango en origen - w = std::min(w, surface_data_->width - sx); - h = std::min(h, surface_data_->height - sy); - - // Limitar la región para evitar accesos fuera de rango en destino - w = std::min(w, surface_data->width - dx); - h = std::min(h, surface_data->height - dy); - - const Uint8* src_ptr = surface_data_->data.get(); - Uint8* dst_ptr = surface_data->data.get(); - for (int iy = 0; iy < h; ++iy) { - for (int ix = 0; ix < w; ++ix) { - // Verificar que las coordenadas de destino están dentro de los límites - if (int dest_x = dx + ix; dest_x >= 0 && dest_x < surface_data->width) { - if (int dest_y = dy + iy; dest_y >= 0 && dest_y < surface_data->height) { - int src_x = sx + ix; - int src_y = sy + iy; - - Uint8 color = src_ptr[static_cast(src_x + (src_y * surface_data_->width))]; - if (color != static_cast(transparent_color_)) { - dst_ptr[static_cast(dest_x + (dest_y * surface_data->width))] = sub_palette_[color]; - } - } - } + if (e2 < DX) { + err += DX; + iy1 += SY; } } } @@ -284,44 +250,34 @@ void Surface::render(float dx, float dy, float sx, float sy, float w, float h) { void Surface::render(int x, int y, SDL_FRect* src_rect, SDL_FlipMode flip) { // NOLINT(readability-make-member-function-const) auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData(); - // Aplicar render offset - x += Screen::get()->getRenderOffsetX(); - y += Screen::get()->getRenderOffsetY(); - // Determina la región de origen (clip) a renderizar float sx = (src_rect != nullptr) ? src_rect->x : 0; float sy = (src_rect != nullptr) ? src_rect->y : 0; - float w = (src_rect != nullptr) ? src_rect->w : surface_data_->width; - float h = (src_rect != nullptr) ? src_rect->h : surface_data_->height; + float w = (src_rect != nullptr) ? src_rect->w : static_cast(surface_data_->width); + float h = (src_rect != nullptr) ? src_rect->h : static_cast(surface_data_->height); - // Guardar dimensiones originales antes del clipping (necesarias para flip) - float orig_w = (src_rect != nullptr) ? src_rect->w : surface_data_->width; - float orig_h = (src_rect != nullptr) ? src_rect->h : surface_data_->height; - - // Limitar la región para evitar accesos fuera de rango en origen - w = std::min(w, surface_data_->width - sx); - h = std::min(h, surface_data_->height - sy); - - // Limitar la región para evitar accesos fuera de rango en destino - w = std::min(w, surface_data_dest->width - static_cast(x)); - h = std::min(h, surface_data_dest->height - static_cast(y)); + // Limitar la región para evitar accesos fuera de rango (origen y destino) + w = std::min(w, static_cast(surface_data_->width) - sx); + h = std::min(h, static_cast(surface_data_->height) - sy); + w = std::min(w, static_cast(surface_data_dest->width - x)); + h = std::min(h, static_cast(surface_data_dest->height - y)); // Renderiza píxel por píxel aplicando el flip si es necesario const Uint8* src_ptr = surface_data_->data.get(); Uint8* dst_ptr = surface_data_dest->data.get(); for (int iy = 0; iy < h; ++iy) { for (int ix = 0; ix < w; ++ix) { - // Coordenadas de origen (flip usa dimensiones originales, no clipped) - int src_x = (flip == SDL_FLIP_HORIZONTAL) ? static_cast(sx + orig_w - 1 - ix) : static_cast(sx + ix); - int src_y = (flip == SDL_FLIP_VERTICAL) ? static_cast(sy + orig_h - 1 - iy) : static_cast(sy + iy); + // Coordenadas de origen + int src_x = (flip == SDL_FLIP_HORIZONTAL) ? (sx + w - 1 - ix) : (sx + ix); + int src_y = (flip == SDL_FLIP_VERTICAL) ? (sy + h - 1 - iy) : (sy + iy); // Coordenadas de destino int dest_x = x + ix; int dest_y = y + iy; - // Verificar que las coordenadas están dentro de los límites - if (dest_x >= 0 && dest_x < surface_data_dest->width && dest_y >= 0 && dest_y < surface_data_dest->height && - src_x >= 0 && src_x < surface_data_->width && src_y >= 0 && src_y < surface_data_->height) { + // Verificar que las coordenadas de destino están dentro de los límites + if (dest_x >= 0 && dest_x < surface_data_dest->width && dest_y >= 0 && dest_y < surface_data_dest->height) { + // Copia el píxel si no es transparente Uint8 color = src_ptr[static_cast(src_x + (src_y * surface_data_->width))]; if (color != static_cast(transparent_color_)) { dst_ptr[static_cast(dest_x + (dest_y * surface_data_dest->width))] = sub_palette_[color]; @@ -332,7 +288,7 @@ void Surface::render(int x, int y, SDL_FRect* src_rect, SDL_FlipMode flip) { // } // Helper para calcular coordenadas con flip -void Surface::calculateFlippedCoords(int ix, int iy, float sx, float sy, float w, float h, SDL_FlipMode flip, int& src_x, int& src_y) { +void Surface::calculateFlippedCoords(int ix, int iy, int sx, int sy, int w, int h, SDL_FlipMode flip, int& src_x, int& src_y) { src_x = (flip == SDL_FLIP_HORIZONTAL) ? (sx + w - 1 - ix) : (sx + ix); src_y = (flip == SDL_FLIP_VERTICAL) ? (sy + h - 1 - iy) : (sy + iy); } @@ -362,10 +318,6 @@ void Surface::render(SDL_FRect* src_rect, SDL_FRect* dst_rect, SDL_FlipMode flip // Si dstRect es nullptr, asignar las mismas dimensiones que srcRect float dx = (dst_rect != nullptr) ? dst_rect->x : 0; float dy = (dst_rect != nullptr) ? dst_rect->y : 0; - - // Aplicar render offset - dx += Screen::get()->getRenderOffsetX(); - dy += Screen::get()->getRenderOffsetY(); float dw = (dst_rect != nullptr) ? dst_rect->w : sw; float dh = (dst_rect != nullptr) ? dst_rect->h : sh; @@ -406,10 +358,6 @@ void Surface::render(SDL_FRect* src_rect, SDL_FRect* dst_rect, SDL_FlipMode flip void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect, SDL_FlipMode flip) const { auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData(); - // Aplicar render offset - x += Screen::get()->getRenderOffsetX(); - y += Screen::get()->getRenderOffsetY(); - // Determina la región de origen (clip) a renderizar float sx = (src_rect != nullptr) ? src_rect->x : 0; float sy = (src_rect != nullptr) ? src_rect->y : 0; @@ -436,11 +384,11 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar continue; // Saltar píxeles fuera del rango del destino } - // Copia el píxel si no es transparente + // Copia el píxel si no es transparente; aplica sub_palette_ como el resto de render* Uint8 color = surface_data_->data.get()[static_cast(src_x + (src_y * surface_data_->width))]; if (color != static_cast(transparent_color_)) { surface_data->data[dest_x + (dest_y * surface_data->width)] = - (color == source_color) ? target_color : color; + (color == source_color) ? target_color : sub_palette_[color]; } } } @@ -467,21 +415,17 @@ static auto computeFadeDensity(int screen_y, int fade_h, int canvas_height) -> f } // Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig) -void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, const SDL_FRect* src_rect) const { - // Aplicar render offset - x += Screen::get()->getRenderOffsetX(); - y += Screen::get()->getRenderOffsetY(); - +void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, SDL_FRect* src_rect) const { const int SX = (src_rect != nullptr) ? static_cast(src_rect->x) : 0; const int SY = (src_rect != nullptr) ? static_cast(src_rect->y) : 0; - const int SW = (src_rect != nullptr) ? static_cast(src_rect->w) : static_cast(surface_data_->width); - const int SH = (src_rect != nullptr) ? static_cast(src_rect->h) : static_cast(surface_data_->height); + const int SW = (src_rect != nullptr) ? static_cast(src_rect->w) : surface_data_->width; + const int SH = (src_rect != nullptr) ? static_cast(src_rect->h) : surface_data_->height; auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData(); for (int row = 0; row < SH; row++) { const int SCREEN_Y = y + row; - if (SCREEN_Y < 0 || SCREEN_Y >= static_cast(surface_data_dest->height)) { + if (SCREEN_Y < 0 || SCREEN_Y >= surface_data_dest->height) { continue; } @@ -489,11 +433,11 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height for (int col = 0; col < SW; col++) { const int SCREEN_X = x + col; - if (SCREEN_X < 0 || SCREEN_X >= static_cast(surface_data_dest->width)) { + if (SCREEN_X < 0 || SCREEN_X >= surface_data_dest->width) { continue; } - const Uint8 COLOR = surface_data_->data[((SY + row) * static_cast(surface_data_->width)) + (SX + col)]; + const Uint8 COLOR = surface_data_->data[((SY + row) * surface_data_->width) + (SX + col)]; if (COLOR == static_cast(transparent_color_)) { continue; } @@ -502,27 +446,23 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height continue; // Pixel tapat per la zona de fade } - surface_data_dest->data[SCREEN_X + (SCREEN_Y * static_cast(surface_data_dest->width))] = sub_palette_[COLOR]; + surface_data_dest->data[SCREEN_X + (SCREEN_Y * surface_data_dest->width)] = sub_palette_[COLOR]; } } } // Idem però reemplaçant un color índex -void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, const SDL_FRect* src_rect) const { - // Aplicar render offset - x += Screen::get()->getRenderOffsetX(); - y += Screen::get()->getRenderOffsetY(); - +void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect) const { const int SX = (src_rect != nullptr) ? static_cast(src_rect->x) : 0; const int SY = (src_rect != nullptr) ? static_cast(src_rect->y) : 0; - const int SW = (src_rect != nullptr) ? static_cast(src_rect->w) : static_cast(surface_data_->width); - const int SH = (src_rect != nullptr) ? static_cast(src_rect->h) : static_cast(surface_data_->height); + const int SW = (src_rect != nullptr) ? static_cast(src_rect->w) : surface_data_->width; + const int SH = (src_rect != nullptr) ? static_cast(src_rect->h) : surface_data_->height; auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData(); for (int row = 0; row < SH; row++) { const int SCREEN_Y = y + row; - if (SCREEN_Y < 0 || SCREEN_Y >= static_cast(surface_data_dest->height)) { + if (SCREEN_Y < 0 || SCREEN_Y >= surface_data_dest->height) { continue; } @@ -530,11 +470,11 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height for (int col = 0; col < SW; col++) { const int SCREEN_X = x + col; - if (SCREEN_X < 0 || SCREEN_X >= static_cast(surface_data_dest->width)) { + if (SCREEN_X < 0 || SCREEN_X >= surface_data_dest->width) { continue; } - const Uint8 COLOR = surface_data_->data[((SY + row) * static_cast(surface_data_->width)) + (SX + col)]; + const Uint8 COLOR = surface_data_->data[((SY + row) * surface_data_->width) + (SX + col)]; if (COLOR == static_cast(transparent_color_)) { continue; } @@ -544,7 +484,7 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height } const Uint8 OUT_COLOR = (COLOR == source_color) ? target_color : sub_palette_[COLOR]; - surface_data_dest->data[SCREEN_X + (SCREEN_Y * static_cast(surface_data_dest->width))] = OUT_COLOR; + surface_data_dest->data[SCREEN_X + (SCREEN_Y * surface_data_dest->width)] = OUT_COLOR; } } } @@ -553,8 +493,8 @@ void Surface::renderWithVerticalFade(int x, int y, int fade_h, int canvas_height void Surface::toARGBBuffer(Uint32* buffer) const { if (!surface_data_ || !surface_data_->data || (buffer == nullptr)) { return; } - const int WIDTH = static_cast(surface_data_->width); - const int HEIGHT = static_cast(surface_data_->height); + const int WIDTH = surface_data_->width; + const int HEIGHT = surface_data_->height; const Uint8* src = surface_data_->data.get(); // Obtenemos el tamaño de la paleta para evitar accesos fuera de rango @@ -573,7 +513,7 @@ void Surface::toARGBBuffer(Uint32* buffer) const { } // Vuelca la superficie a una textura -void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { +void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { // NOLINT(readability-convert-member-functions-to-static) if ((renderer == nullptr) || (texture == nullptr) || !surface_data_) { throw std::runtime_error("Renderer or texture is null."); } @@ -599,8 +539,8 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { const int WIDTH = surface_data_->width; const int HEIGHT = surface_data_->height; for (int y = 0; y < HEIGHT; ++y) { - const Uint8* src_row = src + (static_cast(y) * static_cast(WIDTH)); - Uint32* dst_row = pixels + (static_cast(y) * static_cast(row_stride)); + const Uint8* src_row = src + (y * WIDTH); + Uint32* dst_row = pixels + (y * row_stride); for (int x = 0; x < WIDTH; ++x) { dst_row[x] = pal[src_row[x]]; } @@ -615,7 +555,7 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) { } // Vuelca la superficie a una textura -void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* src_rect, SDL_FRect* dest_rect) { +void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* src_rect, SDL_FRect* dest_rect) { // NOLINT(readability-convert-member-functions-to-static) if ((renderer == nullptr) || (texture == nullptr) || !surface_data_) { throw std::runtime_error("Renderer or texture is null."); } @@ -648,8 +588,8 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR const int WIDTH = surface_data_->width; const int HEIGHT = surface_data_->height; for (int y = 0; y < HEIGHT; ++y) { - const Uint8* src_row = src + (static_cast(y) * static_cast(WIDTH)); - Uint32* dst_row = pixels + (static_cast(y) * static_cast(row_stride)); + const Uint8* src_row = src + (y * WIDTH); + Uint32* dst_row = pixels + (y * row_stride); for (int x = 0; x < WIDTH; ++x) { dst_row[x] = pal[src_row[x]]; } @@ -664,12 +604,9 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR } // Realiza un efecto de fundido en la paleta principal -auto Surface::fadePalette() -> bool { - // Verificar que el tamaño mínimo de palette_ sea adecuado +auto Surface::fadePalette() -> bool { // NOLINT(readability-convert-member-functions-to-static) 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."); - } + static_assert(std::tuple_size_v >= PALETTE_SIZE, "Palette size is insufficient for fadePalette operation."); // Desplazar colores (pares e impares) for (int i = 18; i > 1; --i) { @@ -684,7 +621,7 @@ auto Surface::fadePalette() -> bool { } // Realiza un efecto de fundido en la paleta secundaria -auto Surface::fadeSubPalette(Uint32 delay) -> bool { +auto Surface::fadeSubPalette(Uint32 delay) -> bool { // NOLINT(readability-convert-member-functions-to-static) // Variable estática para almacenar el último tick static Uint32 last_tick_ = 0; @@ -699,11 +636,8 @@ auto Surface::fadeSubPalette(Uint32 delay) -> bool { // Actualizar el último tick last_tick_ = current_tick; - // Verificar que el tamaño mínimo de sub_palette_ sea adecuado static constexpr int SUB_PALETTE_SIZE = 19; - if (sizeof(sub_palette_) / sizeof(sub_palette_[0]) < SUB_PALETTE_SIZE) { - throw std::runtime_error("Palette size is insufficient for fadePalette operation."); - } + static_assert(std::tuple_size_v >= SUB_PALETTE_SIZE, "Sub-palette size is insufficient for fadeSubPalette operation."); // Desplazar colores (pares e impares) for (int i = 18; i > 1; --i) { @@ -718,4 +652,4 @@ auto Surface::fadeSubPalette(Uint32 delay) -> bool { } // Restaura la sub paleta a su estado original -void Surface::resetSubPalette() { initializeSubPalette(sub_palette_); } +void Surface::resetSubPalette() { initializeSubPalette(sub_palette_); } // NOLINT(readability-convert-member-functions-to-static) diff --git a/source/core/rendering/surface.hpp b/source/core/rendering/surface.hpp index 8ba00cd..572847d 100644 --- a/source/core/rendering/surface.hpp +++ b/source/core/rendering/surface.hpp @@ -22,8 +22,8 @@ auto readPalFile(const std::string& file_path) -> Palette; 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 + int width; // Ancho de la imagen + int height; // Alto de la imagen // Constructor por defecto SurfaceData() @@ -32,13 +32,13 @@ struct SurfaceData { 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())), + SurfaceData(int w, int h) + : data(std::shared_ptr(new Uint8[static_cast(w) * static_cast(h)](), std::default_delete())), width(w), height(h) {} // Constructor para inicializar directamente con datos - SurfaceData(float w, float h, std::shared_ptr pixels) + SurfaceData(int w, int h, std::shared_ptr pixels) : data(std::move(pixels)), width(w), height(h) {} @@ -56,6 +56,9 @@ struct SurfaceData { class Surface { private: + // shared_ptr porque render() accede al SurfaceData propio y al del renderer + // surface (ver getRendererSurface()) de forma efímera; con self-blit ambos + // pueden alias y el refcount evita free accidental durante el recorrido. 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 @@ -77,7 +80,6 @@ class Surface { void loadPalette(const 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* src_rect = 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); @@ -85,10 +87,10 @@ class Surface { 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) const; // Render amb dissolució als cantons superior/inferior (hash 2D, sense parpelleig) - void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, const SDL_FRect* src_rect = nullptr) const; + void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, SDL_FRect* src_rect = nullptr) const; // Idem però reemplaçant un color índex (per a sprites sobre fons del mateix color) - void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, const SDL_FRect* src_rect = nullptr) const; + void renderWithVerticalFade(int x, int y, int fade_h, int canvas_height, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect = nullptr) const; // Establece un color en la paleta void setColor(int index, Uint32 color); @@ -127,11 +129,10 @@ class Surface { // Metodos para gestionar surface_data_ [[nodiscard]] auto getSurfaceData() const -> std::shared_ptr { return surface_data_; } - void setSurfaceData(std::shared_ptr new_data) { surface_data_ = std::move(new_data); } // Obtien ancho y alto - [[nodiscard]] auto getWidth() const -> float { return surface_data_->width; } - [[nodiscard]] auto getHeight() const -> float { return surface_data_->height; } + [[nodiscard]] auto getWidth() const -> int { return surface_data_->width; } + [[nodiscard]] auto getHeight() const -> int { return surface_data_->height; } // Color transparente [[nodiscard]] auto getTransparentColor() const -> Uint8 { return transparent_color_; } @@ -139,7 +140,6 @@ class Surface { // Paleta void setPalette(const std::array& palette) { palette_ = palette; } - [[nodiscard]] auto getPalette() const -> const Palette& { return palette_; } [[nodiscard]] auto getPaletteColor(Uint8 index) const -> Uint32 { return palette_[index]; } // Inicializa la sub paleta @@ -147,7 +147,7 @@ class Surface { private: // Helper para calcular coordenadas con flip - static void calculateFlippedCoords(int ix, int iy, float sx, float sy, float w, float h, SDL_FlipMode flip, int& src_x, int& src_y); + static void calculateFlippedCoords(int ix, int iy, int sx, int sy, int w, int h, SDL_FlipMode flip, int& src_x, int& src_y); // Helper para copiar un pixel si no es transparente void copyPixelIfNotTransparent(Uint8* dest_data, int dest_x, int dest_y, int dest_width, int src_x, int src_y) const; diff --git a/source/game/editor/mini_map.cpp b/source/game/editor/mini_map.cpp index 8df4290..b7e44bb 100644 --- a/source/game/editor/mini_map.cpp +++ b/source/game/editor/mini_map.cpp @@ -384,7 +384,11 @@ void MiniMap::handleEvent(const SDL_Event& event, const std::string& current_roo Screen::get()->setRendererSurface(prev); } auto game_surface = Screen::get()->getRendererSurface(); - if (game_surface) { map_surface_->setPalette(game_surface->getPalette()); } + if (game_surface) { + Palette src_palette{}; + for (int i = 0; i < 256; ++i) { src_palette[i] = game_surface->getPaletteColor(static_cast(i)); } + map_surface_->setPalette(src_palette); + } std::string file = Screenshot::save(*map_surface_); if (!file.empty()) { std::cout << "MiniMap screenshot: " << file << "\n"; } // Recomponer para limpiar los números de la surface diff --git a/source/game/ui/notifier.cpp b/source/game/ui/notifier.cpp index 5ae47d9..b63cdea 100644 --- a/source/game/ui/notifier.cpp +++ b/source/game/ui/notifier.cpp @@ -256,7 +256,7 @@ void Notifier::show(std::vector texts, const Style& style, int icon else if (SHAPE == Shape::SQUARED) { n.surface->clear(style.bg_color); - SDL_FRect squared_rect = {.x = 0, .y = 0, .w = n.surface->getWidth(), .h = n.surface->getHeight()}; + SDL_FRect squared_rect = {.x = 0, .y = 0, .w = static_cast(n.surface->getWidth()), .h = static_cast(n.surface->getHeight())}; n.surface->drawRectBorder(&squared_rect, style.border_color); }