From f4484b24f1304dd06ce1c527863ad164d824961a Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 29 Jul 2024 17:49:12 +0200 Subject: [PATCH] afegida (altra volta) la classe Surface --- source/common/surface.cpp | 204 ++++++++++++++++++++++++++++++++++++++ source/common/surface.h | 63 ++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 source/common/surface.cpp create mode 100644 source/common/surface.h diff --git a/source/common/surface.cpp b/source/common/surface.cpp new file mode 100644 index 0000000..07498b1 --- /dev/null +++ b/source/common/surface.cpp @@ -0,0 +1,204 @@ +#include "surface.h" +#include "gif.c" + +struct jSurface_s +{ + Uint8 *data; + Uint16 w, h; +}; + +// Constructor +Surface::Surface(const char *filename, jSurface dest) +{ + surface = loadSurface(filename); + destSurface = dest; + texture = nullptr; + + loadPalette(filename); + transparentColor = 0; +} + +// Constructor +Surface::Surface(int width, int height, SDL_Texture *tex) +{ + surface = newSurface(width, height); + destSurface = nullptr; + texture = tex; + + clearPalette(0); + transparentColor = 0; +} + +// Destructor +Surface::~Surface() +{ + deleteSurface(surface); + deleteSurface(destSurface); +} + +// Crea una surface +jSurface Surface::newSurface(int w, int h) +{ + jSurface surf = (jSurface)malloc(sizeof(jSurface_s)); + surf->w = w; + surf->h = h; + surf->data = (Uint8 *)malloc(w * h); + return surf; +} + +// Borra una surface +void Surface::deleteSurface(jSurface surf) +{ + if (surf == nullptr) + { + return; + } + + if (surf->data != nullptr) + { + free(surf->data); + } + + free(surf); +} + +// Establece una surface de destino donde hacer el blit +void Surface::setDest(jSurface surf) +{ + destSurface = surf; +} + +// Establece una textura donde hacer el flip +void Surface::setTexture(SDL_Texture *tex) +{ + texture = tex; +} + +// Crea una surface a partir de un fichero .gif +jSurface Surface::loadSurface(const char *filename) +{ + FILE *f = fopen(filename, "rb"); + if (!f) + { + return nullptr; + } + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + Uint8 *buffer = (Uint8 *)malloc(size); + fread(buffer, size, 1, f); + fclose(f); + + Uint16 w, h; + Uint8 *pixels = LoadGif(buffer, &w, &h); + if (pixels == nullptr) + { + return nullptr; + } + jSurface surf = (jSurface)malloc(sizeof(jSurface_s)); + surf->w = w; + surf->h = h; + surf->data = pixels; + free(buffer); + return surf; +} + +// Carga una palette desde un fichero .gif +void Surface::loadPalette(const char *filename) +{ + FILE *f = fopen(filename, "rb"); + if (!f) + { + return; + } + + fseek(f, 0, SEEK_END); + long size = ftell(f); + fseek(f, 0, SEEK_SET); + Uint8 *buffer = (Uint8 *)malloc(size); + fread(buffer, size, 1, f); + fclose(f); + + Uint32 *pal = LoadPalette(buffer); + if (pal == nullptr) + { + return; + } + free(buffer); + for (int i = 0; i < 256; ++i) + { + palette[i] = pal[i]; + } +} + +// Cambia un color de la palette +void Surface::setPaletteColor(int index, Uint32 color) +{ + palette[index] = color; +} + +// Limpia la surface +void Surface::cls(Uint8 color) +{ + for (int i = 0; i < surface->w * surface->h; ++i) + { + surface->data[i] = color; + } +} + +// Volca la surface a una textura +void Surface::flip(SDL_Texture *texture) +{ + Uint32 *pixels; + int pitch; + SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch); + for (int i = 0; i < surface->w * surface->h; ++i) + { + pixels[i] = palette[surface->data[i]]; + } + SDL_UnlockTexture(texture); +} + +// Escribe pixels en destSurface +void Surface::putPixel(int x, int y, Uint8 color) +{ + // if (x < 0 || y < 0 || x >= jDestSurf->w || y >= jDestSurf->h || color == transparentColor) + if (x < 0 || y < 0 || x >= destSurface->w || y >= destSurface->h) + { + return; + } + destSurface->data[x + y * destSurface->w] = color; +} + +// Lee pixels en surface +Uint8 Surface::getPixel(int x, int y) +{ + return surface->data[x + y * surface->w]; +} + +// Copia pixels desde surface a destSurface +void Surface::blit(int dx, int dy, int sx, int sy, int w, int h) +{ + if (surface == nullptr) + { + return; + } + + for (int iy = 0; iy < h; ++iy) + { + for (int ix = 0; ix < w; ++ix) + { + putPixel(dx + ix, dy + iy, getPixel(sx + ix, sy + iy)); + } + } +} + +// Limpia la paleta +void Surface::clearPalette(Uint32 color) +{ + for (int i = 0; i < 256; ++i) + { + palette[i] = color; + } +} \ No newline at end of file diff --git a/source/common/surface.h b/source/common/surface.h new file mode 100644 index 0000000..91f3da8 --- /dev/null +++ b/source/common/surface.h @@ -0,0 +1,63 @@ +#pragma once + +#include + +typedef struct jSurface_s *jSurface; + +class Surface +{ +private: + // Variables + jSurface surface; + jSurface destSurface; + SDL_Texture *texture; + Uint32 palette[256]; + int transparentColor; + + // Escribe pixels en destSurface + void putPixel(int x, int y, Uint8 color); + + // Lee pixels en surface + Uint8 getPixel(int x, int y); + + // Limpia la paleta + void clearPalette(Uint32 color); + +public: + // Constructor + Surface(const char *filename, jSurface dest); + Surface(int width, int height, SDL_Texture *tex); + + // Destructor + ~Surface(); + + // Crea una surface + jSurface newSurface(int w, int h); + + // Borra una surface + void deleteSurface(jSurface surf); + + // Establece una surface de destino donde hacer el blit + void setDest(jSurface surf); + + // Establece una textura donde hacer el flip + void setTexture(SDL_Texture *tex); + + // Crea una surface a partir de un fichero .gif + jSurface loadSurface(const char *filename); + + // Carga una paleta desde un fichero .gif + void loadPalette(const char *filename); + + // Copia pixels desde surface a destSurface + void blit(int dx, int dy, int sx, int sy, int w, int h); + + // Cambia un color de la paleta + void setPaletteColor(int index, Uint32 color); + + // Limpia la surface + void cls(Uint8 color); + + // Volca la surface a una textura + void flip(SDL_Texture *texture); +}; \ No newline at end of file