This commit is contained in:
2025-10-27 11:53:12 +01:00
parent 231dcd4b3b
commit 5d8811026d
69 changed files with 899 additions and 888 deletions

View File

@@ -75,7 +75,9 @@ Palette readPalFile(const std::string& file_path) {
// Procesar las líneas restantes con valores RGB
std::istringstream ss(line);
int r, g, b;
int r;
int g;
int b;
if (ss >> r >> g >> b) {
// Construir el color ARGB (A = 255 por defecto)
Uint32 color = (255 << 24) | (r << 16) | (g << 8) | b;
@@ -99,8 +101,8 @@ Surface::Surface(int w, int h)
Surface::Surface(const std::string& file_path)
: transparent_color_(static_cast<Uint8>(PaletteColor::TRANSPARENT)) {
SurfaceData loadedData = loadSurface(file_path);
surface_data_ = std::make_shared<SurfaceData>(std::move(loadedData));
SurfaceData loaded_data = loadSurface(file_path);
surface_data_ = std::make_shared<SurfaceData>(std::move(loaded_data));
initializeSubPalette(sub_palette_);
}
@@ -127,18 +129,19 @@ SurfaceData Surface::loadSurface(const std::string& file_path) {
// Crear un objeto Gif y llamar a la función loadGif
GIF::Gif gif;
Uint16 w = 0, h = 0;
std::vector<Uint8> rawPixels = gif.loadGif(buffer.data(), w, h);
if (rawPixels.empty()) {
Uint16 w = 0;
Uint16 h = 0;
std::vector<Uint8> raw_pixels = gif.loadGif(buffer.data(), w, h);
if (raw_pixels.empty()) {
std::cerr << "Error loading GIF from file: " << file_path << std::endl;
throw std::runtime_error("Error loading GIF");
}
// Si el constructor de Surface espera un std::shared_ptr<Uint8[]>,
// reservamos un bloque dinámico y copiamos los datos del vector.
size_t pixelCount = rawPixels.size();
auto pixels = std::shared_ptr<Uint8[]>(new Uint8[pixelCount], std::default_delete<Uint8[]>());
std::memcpy(pixels.get(), rawPixels.data(), pixelCount);
size_t pixel_count = raw_pixels.size();
auto pixels = std::shared_ptr<Uint8[]>(new Uint8[pixel_count], std::default_delete<Uint8[]>());
std::memcpy(pixels.get(), raw_pixels.data(), pixel_count);
// Crear y devolver directamente el objeto SurfaceData
printWithDots("Surface : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
@@ -162,9 +165,9 @@ 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;
const size_t TOTAL_PIXELS = surface_data_->width * surface_data_->height;
Uint8* data_ptr = surface_data_->data.get();
std::fill(data_ptr, data_ptr + total_pixels, color);
std::fill(data_ptr, data_ptr + TOTAL_PIXELS, color);
}
// Pone un pixel en la SurfaceData
@@ -173,12 +176,12 @@ void Surface::putPixel(int x, int y, Uint8 color) {
return; // Coordenadas fuera de rango
}
const int index = x + y * surface_data_->width;
surface_data_->data.get()[index] = color;
const int INDEX = x + (y * surface_data_->width);
surface_data_->data.get()[INDEX] = color;
}
// Obtiene el color de un pixel de la surface_data
Uint8 Surface::getPixel(int x, int y) { return surface_data_->data.get()[x + y * static_cast<int>(surface_data_->width)]; }
Uint8 Surface::getPixel(int x, int y) { return surface_data_->data.get()[x + (y * static_cast<int>(surface_data_->width))]; }
// Dibuja un rectangulo relleno
void Surface::fillRect(const SDL_FRect* rect, Uint8 color) {
@@ -191,7 +194,7 @@ void Surface::fillRect(const SDL_FRect* rect, Uint8 color) {
// Recorrer cada píxel dentro del rectángulo directamente
for (int y = y_start; y < y_end; ++y) {
for (int x = x_start; x < x_end; ++x) {
const int INDEX = x + y * surface_data_->width;
const int INDEX = x + (y * surface_data_->width);
surface_data_->data.get()[INDEX] = color;
}
}
@@ -208,22 +211,22 @@ void Surface::drawRectBorder(const SDL_FRect* rect, Uint8 color) {
// Dibujar bordes horizontales
for (int x = x_start; x < x_end; ++x) {
// Borde superior
const int top_index = x + y_start * surface_data_->width;
surface_data_->data.get()[top_index] = color;
const int TOP_INDEX = x + (y_start * surface_data_->width);
surface_data_->data.get()[TOP_INDEX] = color;
// Borde inferior
const int bottom_index = x + (y_end - 1) * surface_data_->width;
surface_data_->data.get()[bottom_index] = color;
const int BOTTOM_INDEX = x + ((y_end - 1) * surface_data_->width);
surface_data_->data.get()[BOTTOM_INDEX] = color;
}
// Dibujar bordes verticales
for (int y = y_start; y < y_end; ++y) {
// Borde izquierdo
const int LEFT_INDEX = x_start + y * surface_data_->width;
const int LEFT_INDEX = x_start + (y * surface_data_->width);
surface_data_->data.get()[LEFT_INDEX] = color;
// Borde derecho
const int RIGHT_INDEX = (x_end - 1) + y * surface_data_->width;
const int RIGHT_INDEX = (x_end - 1) + (y * surface_data_->width);
surface_data_->data.get()[RIGHT_INDEX] = color;
}
}
@@ -243,12 +246,13 @@ void Surface::drawLine(float x1, float y1, float x2, float y2, Uint8 color) {
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<size_t>(x1 + y1 * surface_data_->width)] = color;
surface_data_->data.get()[static_cast<size_t>(x1 + (y1 * surface_data_->width))] = color;
}
// Si alcanzamos el punto final, salimos
if (x1 == x2 && y1 == y2)
if (x1 == x2 && y1 == y2) {
break;
}
int e2 = 2 * err;
if (e2 > -dy) {
@@ -281,9 +285,9 @@ void Surface::render(float dx, float dy, float sx, float sy, float w, float h) {
int src_x = sx + ix;
int src_y = sy + iy;
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + (src_y * surface_data_->width))];
if (color != transparent_color_) {
surface_data->data.get()[static_cast<size_t>(dest_x + dest_y * surface_data->width)] = sub_palette_[color];
surface_data->data.get()[static_cast<size_t>(dest_x + (dest_y * surface_data->width))] = sub_palette_[color];
}
}
}
@@ -291,14 +295,14 @@ void Surface::render(float dx, float dy, float sx, float sy, float w, float h) {
}
}
void Surface::render(int x, int y, SDL_FRect* srcRect, SDL_FlipMode flip) {
void Surface::render(int x, int y, SDL_FRect* src_rect, SDL_FlipMode flip) {
auto surface_data_dest = Screen::get()->getRendererSurface()->getSurfaceData();
// Determina la región de origen (clip) a renderizar
float sx = (srcRect) ? srcRect->x : 0;
float sy = (srcRect) ? srcRect->y : 0;
float w = (srcRect) ? srcRect->w : surface_data_->width;
float h = (srcRect) ? srcRect->h : surface_data_->height;
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;
// Limitar la región para evitar accesos fuera de rango en origen
w = std::min(w, surface_data_->width - sx);
@@ -324,9 +328,9 @@ void Surface::render(int x, int y, SDL_FRect* srcRect, SDL_FlipMode flip) {
// 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 = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + (src_y * surface_data_->width))];
if (color != transparent_color_) {
surface_data_dest->data[dest_x + dest_y * surface_data_dest->width] = sub_palette_[color];
surface_data_dest->data[dest_x + (dest_y * surface_data_dest->width)] = sub_palette_[color];
}
}
}
@@ -334,20 +338,20 @@ void Surface::render(int x, int y, SDL_FRect* srcRect, SDL_FlipMode flip) {
}
// Copia una región de la superficie de origen a la de destino
void Surface::render(SDL_FRect* srcRect, SDL_FRect* dstRect, SDL_FlipMode flip) {
void Surface::render(SDL_FRect* src_rect, SDL_FRect* dst_rect, SDL_FlipMode flip) {
auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData();
// Si srcRect es nullptr, tomar toda la superficie fuente
float sx = (srcRect) ? srcRect->x : 0;
float sy = (srcRect) ? srcRect->y : 0;
float sw = (srcRect) ? srcRect->w : surface_data_->width;
float sh = (srcRect) ? srcRect->h : surface_data_->height;
float sx = ((src_rect) != nullptr) ? src_rect->x : 0;
float sy = ((src_rect) != nullptr) ? src_rect->y : 0;
float sw = ((src_rect) != nullptr) ? src_rect->w : surface_data_->width;
float sh = ((src_rect) != nullptr) ? src_rect->h : surface_data_->height;
// Si dstRect es nullptr, asignar las mismas dimensiones que srcRect
float dx = (dstRect) ? dstRect->x : 0;
float dy = (dstRect) ? dstRect->y : 0;
float dw = (dstRect) ? dstRect->w : sw;
float dh = (dstRect) ? dstRect->h : sh;
float dx = ((dst_rect) != nullptr) ? dst_rect->x : 0;
float dy = ((dst_rect) != nullptr) ? dst_rect->y : 0;
float dw = ((dst_rect) != nullptr) ? dst_rect->w : sw;
float dh = ((dst_rect) != nullptr) ? dst_rect->h : sh;
// Asegurarse de que srcRect y dstRect tienen las mismas dimensiones
if (sw != dw || sh != dh) {
@@ -375,9 +379,9 @@ void Surface::render(SDL_FRect* srcRect, SDL_FRect* dstRect, SDL_FlipMode flip)
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) {
// Copiar el píxel si no es transparente
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + (src_y * surface_data_->width))];
if (color != transparent_color_) {
surface_data->data[dest_x + dest_y * surface_data->width] = sub_palette_[color];
surface_data->data[dest_x + (dest_y * surface_data->width)] = sub_palette_[color];
}
}
}
@@ -386,14 +390,14 @@ void Surface::render(SDL_FRect* srcRect, SDL_FRect* dstRect, SDL_FlipMode flip)
}
// Copia una región de la SurfaceData de origen a la SurfaceData de destino reemplazando un color por otro
void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_FRect* srcRect, SDL_FlipMode flip) {
void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 target_color, SDL_FRect* src_rect, SDL_FlipMode flip) {
auto surface_data = Screen::get()->getRendererSurface()->getSurfaceData();
// Determina la región de origen (clip) a renderizar
float sx = (srcRect) ? srcRect->x : 0;
float sy = (srcRect) ? srcRect->y : 0;
float w = (srcRect) ? srcRect->w : surface_data_->width;
float h = (srcRect) ? srcRect->h : surface_data_->height;
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;
// Limitar la región para evitar accesos fuera de rango
w = std::min(w, surface_data_->width - sx);
@@ -416,9 +420,9 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar
}
// Copia el píxel si no es transparente
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + src_y * surface_data_->width)];
Uint8 color = surface_data_->data.get()[static_cast<size_t>(src_x + (src_y * surface_data_->width))];
if (color != transparent_color_) {
surface_data->data[dest_x + dest_y * surface_data->width] =
surface_data->data[dest_x + (dest_y * surface_data->width)] =
(color == source_color) ? target_color : color;
}
}
@@ -427,11 +431,11 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar
// Vuelca la superficie a una textura
void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) {
if (!renderer || !texture || !surface_data_) {
if ((renderer == nullptr) || (texture == nullptr) || !surface_data_) {
throw std::runtime_error("Renderer or texture is null.");
}
if (surface_data_->width <= 0 || surface_data_->height <= 0 || !surface_data_->data.get()) {
if (surface_data_->width <= 0 || surface_data_->height <= 0 || (surface_data_->data.get() == nullptr)) {
throw std::runtime_error("Invalid surface dimensions or data.");
}
@@ -449,8 +453,8 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture) {
for (int y = 0; y < surface_data_->height; ++y) {
for (int x = 0; x < surface_data_->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_data_->width + x;
int texture_index = (y * row_stride) + x;
int surface_index = (y * surface_data_->width) + x;
pixels[texture_index] = palette_[surface_data_->data.get()[surface_index]];
}
@@ -465,28 +469,28 @@ 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* srcRect, SDL_FRect* destRect) {
if (!renderer || !texture || !surface_data_) {
void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FRect* src_rect, SDL_FRect* dest_rect) {
if ((renderer == nullptr) || (texture == nullptr) || !surface_data_) {
throw std::runtime_error("Renderer or texture is null.");
}
if (surface_data_->width <= 0 || surface_data_->height <= 0 || !surface_data_->data.get()) {
if (surface_data_->width <= 0 || surface_data_->height <= 0 || (surface_data_->data.get() == nullptr)) {
throw std::runtime_error("Invalid surface dimensions or data.");
}
Uint32* pixels = nullptr;
int pitch = 0;
SDL_Rect lockRect;
if (destRect) {
lockRect.x = static_cast<int>(destRect->x);
lockRect.y = static_cast<int>(destRect->y);
lockRect.w = static_cast<int>(destRect->w);
lockRect.h = static_cast<int>(destRect->h);
SDL_Rect lock_rect;
if (dest_rect != nullptr) {
lock_rect.x = static_cast<int>(dest_rect->x);
lock_rect.y = static_cast<int>(dest_rect->y);
lock_rect.w = static_cast<int>(dest_rect->w);
lock_rect.h = static_cast<int>(dest_rect->h);
}
// Usa lockRect solo si destRect no es nulo
if (!SDL_LockTexture(texture, destRect ? &lockRect : nullptr, reinterpret_cast<void**>(&pixels), &pitch)) {
if (!SDL_LockTexture(texture, (dest_rect != nullptr) ? &lock_rect : nullptr, reinterpret_cast<void**>(&pixels), &pitch)) {
throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError()));
}
@@ -494,8 +498,8 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR
for (int y = 0; y < surface_data_->height; ++y) {
for (int x = 0; x < surface_data_->width; ++x) {
int texture_index = y * row_stride + x;
int surface_index = y * surface_data_->width + x;
int texture_index = (y * row_stride) + x;
int surface_index = (y * surface_data_->width) + x;
pixels[texture_index] = palette_[surface_data_->data.get()[surface_index]];
}
@@ -504,7 +508,7 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR
SDL_UnlockTexture(texture);
// Renderiza la textura con los rectángulos especificados
if (!SDL_RenderTexture(renderer, texture, srcRect, destRect)) {
if (!SDL_RenderTexture(renderer, texture, src_rect, dest_rect)) {
throw std::runtime_error("Failed to copy texture to renderer: " + std::string(SDL_GetError()));
}
}
@@ -512,8 +516,8 @@ void Surface::copyToTexture(SDL_Renderer* renderer, SDL_Texture* texture, SDL_FR
// Realiza un efecto de fundido en la paleta principal
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) {
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.");
}
@@ -532,22 +536,22 @@ bool Surface::fadePalette() {
// Realiza un efecto de fundido en la paleta secundaria
bool Surface::fadeSubPalette(Uint32 delay) {
// Variable estática para almacenar el último tick
static Uint32 last_tick = 0;
static Uint32 last_tick_ = 0;
// Obtener el tiempo actual
Uint32 current_tick = SDL_GetTicks();
// Verificar si ha pasado el tiempo de retardo
if (current_tick - last_tick < delay) {
if (current_tick - last_tick_ < delay) {
return false; // No se realiza el fade
}
// Actualizar el último tick
last_tick = current_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) {
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.");
}