afegit gif.cpp i jail_shader.cpp desde coffee_crisis_arcade_edition

This commit is contained in:
2025-03-16 15:44:38 +01:00
parent a14f6fcf6f
commit 40dcbabfe8
61 changed files with 1185 additions and 1231 deletions

View File

@@ -1,21 +1,18 @@
#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 "screen.h"
#include "gif.h" // for LoadGif, LoadPalette
#include <iostream>
#include <fstream>
#include <sstream>
#include <array>
#include <cstdint>
#include <stdexcept>
#include <SDL2/SDL_error.h> // Para SDL_GetError
#include <bits/std_abs.h> // Para abs
#include <stdlib.h> // Para abs
#include <algorithm> // Para min, max, copy_n, fill
#include <cstdint> // Para uint32_t
#include <cstring> // Para memcpy, size_t
#include <fstream> // Para basic_ifstream, basic_ostream, basic_ist...
#include <iostream> // Para cerr
#include <memory> // Para shared_ptr, __shared_ptr_access, default...
#include <sstream> // Para basic_istringstream
#include <stdexcept> // Para runtime_error
#include <vector> // Para vector
#include "gif.h" // Para Gif
#include "screen.h" // Para Screen
// Carga una paleta desde un archivo .gif
Palette loadPalette(const std::string &file_path)
@@ -27,7 +24,7 @@ Palette loadPalette(const std::string &file_path)
throw std::runtime_error("Error opening file: " + file_path);
}
// Leer el contenido del archivo en un buffer
// Obtener el tamaño del archivo y leerlo en un buffer
std::streamsize size = file.tellg();
file.seekg(0, std::ios::beg);
@@ -38,15 +35,16 @@ Palette loadPalette(const std::string &file_path)
}
// Cargar la paleta usando los datos del buffer
std::unique_ptr<Uint32[]> pal(LoadPalette(buffer.data()));
if (pal == nullptr)
GIF::Gif gif;
std::vector<uint32_t> pal = gif.loadPalette(buffer.data());
if (pal.empty())
{
throw std::runtime_error("Error loading palette from file: " + file_path);
throw std::runtime_error("No palette found in GIF file: " + file_path);
}
// Crear la paleta y copiar los datos
Palette palette;
std::copy(pal.get(), pal.get() + palette.size(), palette.begin());
// Crear la paleta y copiar los datos desde 'pal'
Palette palette = {}; // Inicializa la paleta con ceros
std::copy_n(pal.begin(), std::min(pal.size(), palette.size()), palette.begin());
// Mensaje de depuración
printWithDots("Palette : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
@@ -118,32 +116,42 @@ Surface::Surface(const std::string &file_path)
// Carga una superficie desde un archivo
SurfaceData Surface::loadSurface(const std::string &file_path)
{
// 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.is_open())
{
std::cerr << "Error opening file: " << file_path << std::endl;
throw std::runtime_error("Error opening file");
}
// 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((char *)buffer.data(), size))
if (!file.read(reinterpret_cast<char *>(buffer.data()), size))
{
std::cerr << "Error reading file: " << file_path << std::endl;
throw std::runtime_error("Error reading file");
}
Uint16 w, h;
Uint8 *pixels = LoadGif(buffer.data(), &w, &h);
if (pixels == nullptr)
// 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())
{
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);
// Crear y devolver directamente el objeto SurfaceData
printWithDots("Surface : ", file_path.substr(file_path.find_last_of("\\/") + 1), "[ LOADED ]");
return SurfaceData(w, h, pixels);
@@ -171,7 +179,8 @@ void Surface::setColor(int index, Uint32 color)
void Surface::clear(Uint8 color)
{
const size_t total_pixels = surface_data_->width * surface_data_->height;
std::fill(surface_data_->data, surface_data_->data + total_pixels, color);
Uint8* data_ptr = surface_data_->data.get(); // Explicitly get a typed pointer
std::fill(data_ptr, data_ptr + total_pixels, color);
}
// Pone un pixel en la SurfaceData
@@ -183,14 +192,14 @@ void Surface::putPixel(int x, int y, Uint8 color)
}
const int index = x + y * surface_data_->width;
surface_data_->data[index] = color;
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[x + y * surface_data_->width]; }
Uint8 Surface::getPixel(int x, int y) { return surface_data_->data.get()[x + y * surface_data_->width]; }
// Dibuja un rectangulo relleno
void Surface::fillRect(SDL_Rect *rect, Uint8 color)
void Surface::fillRect(const SDL_Rect *rect, Uint8 color)
{
// Limitar los valores del rectángulo al tamaño de la superficie
int x_start = std::max(0, rect->x);
@@ -204,13 +213,13 @@ void Surface::fillRect(SDL_Rect *rect, Uint8 color)
for (int x = x_start; x < x_end; ++x)
{
const int index = x + y * surface_data_->width;
surface_data_->data[index] = color;
surface_data_->data.get()[index] = color;
}
}
}
// Dibuja el borde de un rectangulo
void Surface::drawRectBorder(SDL_Rect *rect, Uint8 color)
void Surface::drawRectBorder(const SDL_Rect *rect, Uint8 color)
{
// Limitar los valores del rectángulo al tamaño de la superficie
int x_start = std::max(0, rect->x);
@@ -223,11 +232,11 @@ void Surface::drawRectBorder(SDL_Rect *rect, Uint8 color)
{
// Borde superior
const int top_index = x + y_start * surface_data_->width;
surface_data_->data[top_index] = color;
surface_data_->data.get()[top_index] = color;
// Borde inferior
const int bottom_index = x + (y_end - 1) * surface_data_->width;
surface_data_->data[bottom_index] = color;
surface_data_->data.get()[bottom_index] = color;
}
// Dibujar bordes verticales
@@ -235,11 +244,11 @@ void Surface::drawRectBorder(SDL_Rect *rect, Uint8 color)
{
// Borde izquierdo
const int left_index = x_start + y * surface_data_->width;
surface_data_->data[left_index] = color;
surface_data_->data.get()[left_index] = color;
// Borde derecho
const int right_index = (x_end - 1) + y * surface_data_->width;
surface_data_->data[right_index] = color;
surface_data_->data.get()[right_index] = color;
}
}
@@ -261,7 +270,7 @@ void Surface::drawLine(int x1, int y1, int x2, int y2, Uint8 color)
// 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[x1 + y1 * surface_data_->width] = color;
surface_data_->data.get()[x1 + y1 * surface_data_->width] = color;
}
// Si alcanzamos el punto final, salimos
@@ -298,18 +307,19 @@ void Surface::render(int dx, int dy, int sx, int sy, int w, int h)
{
for (int ix = 0; ix < w; ++ix)
{
int src_x = sx + ix;
int src_y = sy + iy;
int dest_x = dx + ix;
int dest_y = dy + iy;
// Verificar que las coordenadas de destino están dentro de los límites
if (dest_x >= 0 && dest_x < surface_data->width && dest_y >= 0 && dest_y < surface_data->height)
if (int dest_x = dx + ix; dest_x >= 0 && dest_x < surface_data->width)
{
Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
if (int dest_y = dy + iy; dest_y >= 0 && dest_y < surface_data->height)
{
surface_data->data[dest_x + dest_y * surface_data->width] = sub_palette_[color];
int src_x = sx + ix;
int src_y = sy + iy;
Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_data->data.get()[dest_x + dest_y * surface_data->width] = sub_palette_[color];
}
}
}
}
@@ -353,7 +363,7 @@ void Surface::render(int x, int y, SDL_Rect *srcRect, SDL_RendererFlip flip)
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[src_x + src_y * surface_data_->width];
Uint8 color = surface_data_->data.get()[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];
@@ -406,14 +416,17 @@ void Surface::render(SDL_Rect *srcRect, SDL_Rect *dstRect, SDL_RendererFlip flip
int src_y = (flip == SDL_FLIP_VERTICAL) ? (sy + final_height - 1 - iy) : (sy + iy);
// Coordenadas de destino
int dest_x = dx + ix;
int dest_y = dy + iy;
// Copiar el píxel si no es transparente
Uint8 color = surface_data_->data[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
if (int dest_x = dx + ix; dest_x >= 0 && dest_x < surface_data->width)
{
surface_data->data[dest_x + dest_y * surface_data->width] = sub_palette_[color];
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()[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_data->data[dest_x + dest_y * surface_data->width] = sub_palette_[color];
}
}
}
}
}
@@ -454,7 +467,7 @@ 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[src_x + src_y * surface_data_->width];
Uint8 color = surface_data_->data.get()[src_x + src_y * surface_data_->width];
if (color != transparent_color_)
{
surface_data->data[dest_x + dest_y * surface_data->width] =
@@ -472,7 +485,7 @@ void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
throw std::runtime_error("Renderer or texture is null.");
}
if (surface_data_->width <= 0 || surface_data_->height <= 0 || !surface_data_->data)
if (surface_data_->width <= 0 || surface_data_->height <= 0 || !surface_data_->data.get())
{
throw std::runtime_error("Invalid surface dimensions or data.");
}
@@ -481,7 +494,7 @@ void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
int pitch = 0;
// Bloquea la textura para modificar los píxeles directamente
if (SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch) != 0)
if (SDL_LockTexture(texture, nullptr, reinterpret_cast<void **>(&pixels), &pitch) != 0)
{
throw std::runtime_error("Failed to lock texture: " + std::string(SDL_GetError()));
}
@@ -497,7 +510,7 @@ void Surface::copyToTexture(SDL_Renderer *renderer, SDL_Texture *texture)
int texture_index = y * row_stride + x;
int surface_index = y * surface_data_->width + x;
pixels[texture_index] = palette_[surface_data_->data[surface_index]];
pixels[texture_index] = palette_[surface_data_->data.get()[surface_index]];
}
}