bfff, a casa a meitat enfangà.. be..

Estic acabant de convertir Title
This commit is contained in:
2025-03-03 14:26:07 +01:00
parent 8f1d1df5d6
commit c9e75ad5c8
9 changed files with 190 additions and 81 deletions

View File

@@ -1,23 +1,25 @@
#include "surface.h"
#include <SDL2/SDL_error.h> // for SDL_GetError
#include <stddef.h> // for size_t
#include <algorithm> // for min, copy, fill
#include <fstream> // for basic_ostream, basic_ifstream, basic_ios
#include <iostream> // for cerr, cout
#include <memory> // for shared_ptr, __shared_ptr_access, unique_ptr
#include <stdexcept> // for runtime_error
#include <vector> // for vector
#include "asset.h" // for Asset
#include "gif.h" // for LoadGif, LoadPalette
#include <SDL2/SDL_error.h> // for SDL_GetError
#include <stddef.h> // for size_t
#include <algorithm> // for min, copy, fill
#include <fstream> // for basic_ostream, basic_ifstream, basic_ios
#include <iostream> // for cerr, cout
#include <memory> // for shared_ptr, __shared_ptr_access, unique_ptr
#include <stdexcept> // for runtime_error
#include <vector> // for vector
#include "asset.h" // for Asset
#include "gif.h" // for LoadGif, LoadPalette
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, int w, int h)
: surface_dest_(surface_dest),
surface_(std::make_shared<SurfaceData>(w, h)),
: surface_data_dest_(surface_dest),
surface_data_(std::make_shared<SurfaceData>(w, h)),
original_surface_data_(surface_data_),
transparent_color_(0) {}
Surface::Surface(std::shared_ptr<SurfaceData> surface_dest, const std::string &file_path)
: surface_dest_(surface_dest),
surface_(std::make_shared<SurfaceData>(loadSurface(Asset::get()->get(file_path)))),
: surface_data_dest_(surface_dest),
surface_data_(std::make_shared<SurfaceData>(loadSurface(Asset::get()->get(file_path)))),
original_surface_data_(surface_data_),
transparent_color_(0) {}
Surface::~Surface() {}
@@ -101,8 +103,8 @@ void Surface::setColor(int index, Uint32 color)
// Rellena la superficie con un color
void Surface::clear(Uint8 color)
{
const size_t total_pixels = surface_->width * surface_->height;
std::fill(surface_->data, surface_->data + total_pixels, color);
const size_t total_pixels = surface_data_->width * surface_data_->height;
std::fill(surface_data_->data, surface_data_->data + total_pixels, color);
}
// Pone un pixel en la superficie de destino
@@ -113,43 +115,43 @@ void Surface::putPixel(int x, int y, Uint8 color)
return; // Color transparente, no dibujar
}
if (x < 0 || y < 0 || x >= surface_dest_->width || y >= surface_dest_->height)
if (x < 0 || y < 0 || x >= surface_data_dest_->width || y >= surface_data_dest_->height)
{
return; // Coordenadas fuera de rango
}
const int index = x + y * surface_dest_->width;
surface_dest_->data[index] = color;
const int index = x + y * surface_data_dest_->width;
surface_data_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];
return surface_data_->data[x + y * surface_data_->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)
{
if (!surface_ || !surface_dest_)
if (!surface_data_ || !surface_data_dest_)
{
throw std::runtime_error("Surface source or destination is null.");
}
// 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);
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);
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
Uint8 color = surface_data_->data[(sx + ix) + (sy + iy) * surface_data_->width];
if (color != transparent_color_)
{
surface_dest_->data[(dx + ix) + (dy + iy) * surface_dest_->width] = color;
surface_data_dest_->data[(dx + ix) + (dy + iy) * surface_data_dest_->width] = color;
}
}
}
@@ -158,7 +160,7 @@ 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 *clip, SDL_RendererFlip flip)
{
if (!surface_ || !surface_dest_)
if (!surface_data_ || !surface_data_dest_)
{
throw std::runtime_error("Surface source or destination is null.");
}
@@ -166,14 +168,14 @@ void Surface::render(int x, int y, SDL_Rect *clip, SDL_RendererFlip flip)
// Determina la región de origen (clip) a renderizar
int sx = (clip) ? clip->x : 0;
int sy = (clip) ? clip->y : 0;
int w = (clip) ? clip->w : surface_->width;
int h = (clip) ? clip->h : surface_->height;
int w = (clip) ? clip->w : surface_data_->width;
int h = (clip) ? clip->h : surface_data_->height;
// 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 - x);
h = std::min(h, surface_dest_->height - y);
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);
// Renderiza píxel por píxel aplicando el flip si es necesario
for (int iy = 0; iy < h; ++iy)
@@ -189,15 +191,58 @@ void Surface::render(int x, int y, SDL_Rect *clip, SDL_RendererFlip flip)
int dest_y = y + iy;
// Copia el píxel si no es transparente
Uint8 color = surface_->data[src_x + src_y * surface_->width];
if (color != transparent_color_) // Opcional: Ignorar píxeles transparentes
Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_dest_->data[dest_x + dest_y * surface_dest_->width] = color;
surface_data_dest_->data[dest_x + dest_y * surface_data_dest_->width] = color;
}
}
}
}
// 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 = 0, Uint8 target_color = 0, SDL_Rect *clip = nullptr, SDL_RendererFlip flip = SDL_FLIP_NONE)
{
if (!surface_data_ || !surface_data_dest_)
{
throw std::runtime_error("Surface source or destination is null.");
}
// Determina la región de origen (clip) a renderizar
int sx = (clip) ? clip->x : 0;
int sy = (clip) ? clip->y : 0;
int w = (clip) ? clip->w : surface_data_->width;
int h = (clip) ? clip->h : surface_data_->height;
// 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);
// Renderiza píxel por píxel aplicando el flip si es necesario
for (int iy = 0; iy < h; ++iy)
{
for (int ix = 0; ix < w; ++ix)
{
// 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;
// Copia el píxel si no es transparente
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 == source_color) ? target_color : color;
}
}
}
}
// Vuelca la superficie a una textura
void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
@@ -207,7 +252,7 @@ void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
throw std::runtime_error("Renderer or texture is null.");
}
if (surface_->width <= 0 || surface_->height <= 0 || !surface_->data)
if (surface_data_->width <= 0 || surface_data_->height <= 0 || !surface_data_->data)
{
throw std::runtime_error("Invalid surface dimensions or data.");
}
@@ -224,15 +269,15 @@ void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
// 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 y = 0; y < surface_data_->height; ++y)
{
for (int x = 0; x < surface_->width; ++x)
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_->width + x;
int surface_index = y * surface_data_->width + x;
pixels[texture_index] = palette_[surface_->data[surface_index]];
pixels[texture_index] = palette_[surface_data_->data[surface_index]];
}
}