He posat punteros dobles i tampoc va res

This commit is contained in:
2025-03-05 12:31:54 +01:00
parent 33038e8509
commit d41b0cb31c
11 changed files with 151 additions and 144 deletions

View File

@@ -10,43 +10,30 @@
#include "asset.h" // for Asset
#include "gif.h" // for LoadGif, LoadPalette
Surface::Surface(std::shared_ptr<SurfaceData> surface_data_dest, int w, int h)
// Constructor
Surface::Surface(std::shared_ptr<std::shared_ptr<SurfaceData>> surface_dest, int w, int h)
: surface_data_dest_(surface_dest),
surface_data_(std::make_shared<SurfaceData>(w, h)),
original_surface_data_(surface_data_),
transparent_color_(0)
{
// Inicializar surface_data_ con un nuevo SurfaceData
surface_data_ = std::make_shared<SurfaceData>(w, h);
// Guardar la copia original de surface_data_
original_surface_data_ = surface_data_;
// Si se proporciona un surface_data_dest, enlazamos surface_data_dest_
if (surface_data_dest)
if (!surface_data_dest_)
{
surface_data_dest_ = surface_data_dest;
}
else
{
// Si no se pasa otro puntero, surface_data_dest_ apunta al propio surface_data_
surface_data_dest_ = surface_data_;
surface_data_dest_ = std::make_shared<std::shared_ptr<SurfaceData>>(surface_data_);
}
}
Surface::Surface(std::shared_ptr<SurfaceData> surface_data_dest, const std::string &file_path)
Surface::Surface(std::shared_ptr<std::shared_ptr<SurfaceData>> surface_dest, const std::string &file_path)
: surface_data_dest_(surface_dest),
transparent_color_(0)
{
// Cargar surface_data_ desde el archivo
surface_data_ = std::make_shared<SurfaceData>(loadSurface(file_path));
// Guardar la copia original de surface_data_
SurfaceData loadedData = loadSurface(file_path);
surface_data_ = std::make_shared<SurfaceData>(std::move(loadedData));
original_surface_data_ = surface_data_;
// Si se proporciona un surface_data_dest, enlazamos surface_data_dest_
if (surface_data_dest)
if (!surface_data_dest_)
{
surface_data_dest_ = surface_data_dest;
}
else
{
// Si no se pasa otro puntero, surface_data_dest_ apunta al propio surface_data_
surface_data_dest_ = surface_data_;
surface_data_dest_ = std::make_shared<std::shared_ptr<SurfaceData>>(surface_data_);
}
}
@@ -212,16 +199,17 @@ void Surface::drawLine(std::shared_ptr<SurfaceData> surface_data, int x1, int y1
// 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)
{
if (!surface_data_ || !surface_data_dest_)
{
if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) {
throw std::runtime_error("Surface source or destination is null.");
}
auto &dest = **surface_data_dest_;
// Limitar la región para evitar accesos fuera de rango
w = std::min(w, surface_data_->width - sx);
h = std::min(h, surface_data_->height - sy);
w = std::min(w, surface_data_dest_->width - dx);
h = std::min(h, surface_data_dest_->height - dy);
w = std::min(w, dest.width - dx);
h = std::min(h, dest.height - dy);
for (int iy = 0; iy < h; ++iy)
{
@@ -230,7 +218,7 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
Uint8 color = surface_data_->data[(sx + ix) + (sy + iy) * surface_data_->width];
if (color != transparent_color_)
{
surface_data_dest_->data[(dx + ix) + (dy + iy) * surface_data_dest_->width] = color;
dest.data[(dx + ix) + (dy + iy) * dest.width] = color;
}
}
}
@@ -239,11 +227,12 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
// Copia una región de la superficie de origen a la de destino
void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip)
{
if (!surface_data_ || !surface_data_dest_)
{
if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) {
throw std::runtime_error("Surface source or destination is null.");
}
auto &dest = **surface_data_dest_;
// Determina la región de origen (clip) a renderizar
int sx = (srcRect) ? srcRect->x : 0;
int sy = (srcRect) ? srcRect->y : 0;
@@ -253,8 +242,8 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip)
// Limitar la región para evitar accesos fuera de rango
w = std::min(w, surface_data_->width - sx);
h = std::min(h, surface_data_->height - sy);
w = std::min(w, surface_data_dest_->width - x);
h = std::min(h, surface_data_dest_->height - y);
w = std::min(w, dest.width - x);
h = std::min(h, dest.height - y);
// Renderiza píxel por píxel aplicando el flip si es necesario
for (int iy = 0; iy < h; ++iy)
@@ -273,7 +262,7 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip)
Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] = color;
dest.data[dest_x + dest_y * dest.width] = color;
}
}
}
@@ -282,11 +271,12 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip)
// Copia una región de la superficie de origen a la de destino
void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip)
{
if (!surface_data_ || !surface_data_dest_)
{
if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) {
throw std::runtime_error("Surface source or destination is null.");
}
auto &dest = **surface_data_dest_;
// Si srcRect es nullptr, tomar toda la superficie fuente
int sx = (srcRect) ? srcRect->x : 0;
int sy = (srcRect) ? srcRect->y : 0;
@@ -309,8 +299,8 @@ void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip
// Limitar la región para evitar accesos fuera de rango en src y dst
sw = std::min(sw, surface_data_->width - sx);
sh = std::min(sh, surface_data_->height - sy);
dw = std::min(dw, surface_data_dest_->width - dx);
dh = std::min(dh, surface_data_dest_->height - dy);
dw = std::min(dw, dest.width - dx);
dh = std::min(dh, dest.height - dy);
int final_width = std::min(sw, dw);
int final_height = std::min(sh, dh);
@@ -332,7 +322,7 @@ void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip
Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] = color;
dest.data[dest_x + dest_y * dest.width] = color;
}
}
}
@@ -341,11 +331,12 @@ void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip 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_Rect *srcRect, SDL_RendererFlip flip)
{
if (!surface_data_ || !surface_data_dest_)
{
if (!surface_data_ || !surface_data_dest_ || !*surface_data_dest_) {
throw std::runtime_error("Surface source or destination is null.");
}
auto &dest = **surface_data_dest_;
// Determina la región de origen (clip) a renderizar
int sx = (srcRect) ? srcRect->x : 0;
int sy = (srcRect) ? srcRect->y : 0;
@@ -370,7 +361,7 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar
int dest_y = y + iy;
// Verifica que las coordenadas de destino estén dentro de los límites
if (dest_x < 0 || dest_y < 0 || dest_x >= surface_data_dest_->width || dest_y >= surface_data_dest_->height)
if (dest_x < 0 || dest_y < 0 || dest_x >= dest.width || dest_y >= dest.height)
{
continue; // Saltar píxeles fuera del rango del destino
}
@@ -379,7 +370,7 @@ void Surface::renderWithColorReplace(int x, int y, Uint8 source_color, Uint8 tar
Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] =
dest.data[dest_x + dest_y * dest.width] =
(color == source_color) ? target_color : color;
}
}
@@ -455,27 +446,25 @@ bool Surface::fadePalette()
return palette_[15] == palette_[0];
}
// Método para redirigir surface_data_ al surface_data_ de otro objeto
void Surface::redirectSurfaceDataTo(const std::shared_ptr<SurfaceData>& newSurfaceData)
// Permite que una Surface apunte al SurfaceData de otra Surface
void Surface::redirectSurfaceDataTo(const std::shared_ptr<SurfaceData> &newSurfaceData)
{
// Guardar el surface_data_ original para poder restaurarlo
original_surface_data_ = surface_data_;
// Redirigir surface_data_ al nuevo surface_data_
surface_data_ = newSurfaceData;
if (surface_data_dest_)
{
*surface_data_dest_ = newSurfaceData;
}
}
void Surface::redirectSurfaceDataTo(const std::shared_ptr<Surface> &otherSurface)
{
// Guardar el surface_data_ original para poder restaurarlo
original_surface_data_ = surface_data_;
// Redirigir surface_data_ al nuevo surface_data_
surface_data_ = otherSurface->getSurfaceData();
redirectSurfaceDataTo(otherSurface->getSurfaceData());
}
// Método para restaurar surface_data_ al valor original
// Método para restaurar
void Surface::restoreOriginalSurfaceData()
{
surface_data_ = original_surface_data_;
}
if (surface_data_dest_)
{
*surface_data_dest_ = original_surface_data_;
}
}