He fet un "manolete" i he pasat a c++ i smartpointers la cárrega de surfaces desde gif. Sembla que no ha petat res
Precárrega i asignació de paletes a les textures Ara si algú toca una paleta, que siga conscient que la textura es compartida durant tot el joc
This commit is contained in:
@@ -7,22 +7,22 @@
|
||||
#include <stdio.h> // for fseek, fclose, fopen, fread, ftell, NULL
|
||||
#include <stdlib.h> // for malloc, free, exit
|
||||
#include <iostream> // for basic_ostream, operator<<, cout, endl
|
||||
#include "gif.c" // for LoadGif, LoadPalette
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "gif.c" // for LoadGif, LoadPalette
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h" // for stbi_failure_reason, stbi_image_free
|
||||
|
||||
// Constructor
|
||||
Texture::Texture(SDL_Renderer *renderer, const std::string &path)
|
||||
: renderer_(renderer), path_(path)
|
||||
: texture_(nullptr),
|
||||
renderer_(renderer),
|
||||
surface_(nullptr),
|
||||
width_(0),
|
||||
height_(0),
|
||||
path_(path),
|
||||
current_palette_(0)
|
||||
{
|
||||
// Inicializa
|
||||
surface_ = nullptr;
|
||||
texture_ = nullptr;
|
||||
width_ = 0;
|
||||
height_ = 0;
|
||||
paletteIndex_ = 0;
|
||||
palettes_.clear();
|
||||
|
||||
// Carga el fichero en la textura
|
||||
if (!path_.empty())
|
||||
{
|
||||
@@ -39,7 +39,7 @@ Texture::Texture(SDL_Renderer *renderer, const std::string &path)
|
||||
else if (extension == "gif")
|
||||
{
|
||||
surface_ = loadSurface(path_);
|
||||
addPalette(path_);
|
||||
addPaletteFromFile(path_);
|
||||
setPaletteColor(0, 0, 0x00000000);
|
||||
createBlank(width_, height_, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING);
|
||||
SDL_SetTextureBlendMode(texture_, SDL_BLENDMODE_BLEND);
|
||||
@@ -51,7 +51,9 @@ Texture::Texture(SDL_Renderer *renderer, const std::string &path)
|
||||
// Destructor
|
||||
Texture::~Texture()
|
||||
{
|
||||
unload();
|
||||
unloadTexture();
|
||||
unloadSurface();
|
||||
palettes_.clear();
|
||||
}
|
||||
|
||||
// Carga una imagen desde un fichero
|
||||
@@ -87,7 +89,7 @@ bool Texture::loadFromFile(const std::string &file_path)
|
||||
}
|
||||
|
||||
// Limpia
|
||||
unload();
|
||||
unloadTexture();
|
||||
|
||||
// La textura final
|
||||
SDL_Texture *newTexture = nullptr;
|
||||
@@ -142,7 +144,7 @@ bool Texture::createBlank(int width, int height, SDL_PixelFormatEnum format, SDL
|
||||
}
|
||||
|
||||
// Libera la memoria de la textura
|
||||
void Texture::unload()
|
||||
void Texture::unloadTexture()
|
||||
{
|
||||
// Libera la textura
|
||||
if (texture_)
|
||||
@@ -152,13 +154,6 @@ void Texture::unload()
|
||||
width_ = 0;
|
||||
height_ = 0;
|
||||
}
|
||||
|
||||
// Libera la surface
|
||||
if (surface_)
|
||||
{
|
||||
deleteSurface(surface_);
|
||||
surface_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Establece el color para la modulacion
|
||||
@@ -229,61 +224,56 @@ SDL_Texture *Texture::getSDLTexture()
|
||||
return texture_;
|
||||
}
|
||||
|
||||
// Crea una nueva surface
|
||||
/*Surface Texture::newSurface(int w, int h)
|
||||
// Desencadenar la superficie actual
|
||||
void Texture::unloadSurface()
|
||||
{
|
||||
Surface surf = static_cast<Surface>(malloc(sizeof(surface_s)));
|
||||
surf->w = w;
|
||||
surf->h = h;
|
||||
surf->data = static_cast<Uint8 *>(malloc(w * h));
|
||||
return surf;
|
||||
}*/
|
||||
|
||||
// Elimina una surface
|
||||
void Texture::deleteSurface(Surface surface)
|
||||
{
|
||||
if (surface == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (surface->data != nullptr)
|
||||
{
|
||||
free(surface->data);
|
||||
}
|
||||
|
||||
free(surface);
|
||||
surface_.reset(); // Resetea el shared_ptr
|
||||
width_ = 0;
|
||||
height_ = 0;
|
||||
}
|
||||
|
||||
// Crea una surface desde un fichero .gif
|
||||
Surface Texture::loadSurface(const std::string &file_name)
|
||||
std::shared_ptr<Surface> Texture::loadSurface(const std::string &file_path)
|
||||
{
|
||||
FILE *f = fopen(file_name.c_str(), "rb");
|
||||
if (!f)
|
||||
// Desencadenar la superficie actual
|
||||
unloadSurface();
|
||||
|
||||
// Abrir el archivo usando std::ifstream para manejo automático del recurso
|
||||
std::ifstream file(file_path, std::ios::binary | std::ios::ate);
|
||||
if (!file)
|
||||
{
|
||||
return nullptr;
|
||||
std::cerr << "Error: Fichero no encontrado " << file_path << std::endl;
|
||||
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
Uint8 *buffer = static_cast<Uint8 *>(malloc(size));
|
||||
fread(buffer, size, 1, f);
|
||||
fclose(f);
|
||||
// Obtener el tamaño del archivo
|
||||
std::streamsize size = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
|
||||
// Leer el contenido del archivo en un buffer
|
||||
std::vector<Uint8> buffer(size);
|
||||
if (!file.read(reinterpret_cast<char *>(buffer.data()), size))
|
||||
{
|
||||
std::cerr << "Error al leer el fichero " << file_path << std::endl;
|
||||
throw std::runtime_error("Error al leer el fichero: " + file_path);
|
||||
}
|
||||
|
||||
// Cerrar el archivo (automáticamente manejado por std::ifstream)
|
||||
file.close();
|
||||
|
||||
// Llamar a la función LoadGif
|
||||
Uint16 w, h;
|
||||
Uint8 *pixels = LoadGif(buffer, &w, &h);
|
||||
if (pixels == nullptr)
|
||||
Uint8 *rawPixels = LoadGif(buffer.data(), &w, &h);
|
||||
if (!rawPixels)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Surface surface = static_cast<Surface>(malloc(sizeof(surface_s)));
|
||||
surface->w = w;
|
||||
surface->h = h;
|
||||
surface->data = pixels;
|
||||
free(buffer);
|
||||
// Crear un std::shared_ptr con std::make_shared para pixels
|
||||
auto pixels = std::shared_ptr<Uint8[]>(rawPixels, std::default_delete<Uint8[]>());
|
||||
auto surface = std::make_shared<Surface>(w, h, pixels);
|
||||
|
||||
// Actualizar la anchura y altura
|
||||
width_ = w;
|
||||
height_ = h;
|
||||
|
||||
@@ -306,7 +296,7 @@ void Texture::flipSurface()
|
||||
SDL_LockTexture(texture_, nullptr, reinterpret_cast<void **>(&pixels), &pitch);
|
||||
for (int i = 0; i < width_ * height_; ++i)
|
||||
{
|
||||
pixels[i] = palettes_[paletteIndex_][surface_->data[i]];
|
||||
pixels[i] = palettes_[current_palette_][surface_->data[i]];
|
||||
}
|
||||
SDL_UnlockTexture(texture_);
|
||||
}
|
||||
@@ -318,14 +308,20 @@ void Texture::setPaletteColor(int palette, int index, Uint32 color)
|
||||
}
|
||||
|
||||
// Carga una paleta desde un fichero
|
||||
std::vector<Uint32> Texture::loadPal(const std::string &file_name)
|
||||
std::vector<Uint32> Texture::loadPaletteFromFile(const std::string &file_path)
|
||||
{
|
||||
std::vector<Uint32> palette;
|
||||
|
||||
FILE *f = fopen(file_name.c_str(), "rb");
|
||||
FILE *f = fopen(file_path.c_str(), "rb");
|
||||
if (!f)
|
||||
{
|
||||
return palette;
|
||||
std::cerr << "Error: Fichero no encontrado " << file_path << std::endl;
|
||||
throw std::runtime_error("Fichero no encontrado: " + file_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
const std::string file_name = file_path.substr(file_path.find_last_of("\\/") + 1);
|
||||
printWithDots("Image : ", file_name, "[ LOADED ]");
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
@@ -352,9 +348,9 @@ std::vector<Uint32> Texture::loadPal(const std::string &file_name)
|
||||
}
|
||||
|
||||
// Añade una paleta a la lista
|
||||
void Texture::addPalette(const std::string &path)
|
||||
void Texture::addPaletteFromFile(const std::string &path)
|
||||
{
|
||||
palettes_.push_back(loadPal(path));
|
||||
palettes_.emplace_back(loadPaletteFromFile(path));
|
||||
setPaletteColor((int)palettes_.size() - 1, 0, 0x00000000);
|
||||
}
|
||||
|
||||
@@ -363,7 +359,7 @@ void Texture::setPalette(int palette)
|
||||
{
|
||||
if (palette < (int)palettes_.size())
|
||||
{
|
||||
paletteIndex_ = palette;
|
||||
current_palette_ = palette;
|
||||
flipSurface();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user