diff --git a/source/common/surface.cpp b/source/common/surface.cpp deleted file mode 100644 index 9d0f43d..0000000 --- a/source/common/surface.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "jUnit.h" -#include "gif.c" -#include - -struct jSurface_s -{ - Uint8 *data; - Uint16 w, h; -}; - -static SDL_Window *jWin = NULL; -static SDL_Renderer *jRen = NULL; -static SDL_Texture *jTex = NULL; -static jSurface jScreen; -static jSurface jDestSurf; -static jSurface jSourceSurf = NULL; -static Uint32 paleta[256]; -static int jWidth = 320; -static int jHeight = 240; -static int jZoom = 2; -static int transparentColor = 0; - -jSurface jNewSurface(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; -} - -void jDeleteSurface(jSurface surf) -{ - if (surf == NULL) - return; - if (surf->data != NULL) - free(surf->data); - free(surf); -} - -void jSetDest(jSurface surf) -{ - if (surf == NULL) - jDestSurf = jScreen; - else - jDestSurf = surf; -} - -void jSetSource(jSurface surf) -{ - jSourceSurf = surf; -} - -void jBlit(int dx, int dy, int sx, int sy, int w, int h) -{ - if (jSourceSurf == NULL) - return; - - for (int iy = 0; iy < h; ++iy) - { - for (int ix = 0; ix < w; ++ix) - jPutPixel(dx + ix, dy + iy, jGetPixel(sx + ix, sy + iy)); - } -} - -jSurface jLoadSurface(const char *filename) -{ - FILE *f = fopen(filename, "rb"); - if (!f) - return NULL; - - 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 == NULL) - { - return NULL; - } - jSurface surf = (jSurface)malloc(sizeof(jSurface_s)); - surf->w = w; - surf->h = h; - surf->data = pixels; - free(buffer); - return surf; -} - -void jLoadPal(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 == NULL) - { - return; - } - free(buffer); - for (int i = 0; i < 256; ++i) - { - paleta[i] = pal[i]; - } -} - -void jInit(const char *titol, int w, int h, int z) -{ - SDL_Init(SDL_INIT_EVERYTHING); - jWidth = w; - jHeight = h; - jZoom = z; - jWin = SDL_CreateWindow(titol, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, w * z, h * z, SDL_WINDOW_SHOWN); - jRen = SDL_CreateRenderer(jWin, -1, 0); - SDL_RenderSetLogicalSize(jRen, w, h); - jTex = SDL_CreateTexture(jRen, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, w, h); - jScreen = jNewSurface(w, h); - jDestSurf = jScreen; -} - -void jSetPal(int index, Uint32 color) -{ - paleta[index] = color; -} - -void jCls(Uint8 color) -{ - for (int i = 0; i < jDestSurf->w * jDestSurf->h; ++i) - jDestSurf->data[i] = color; -} - -void jFlip() -{ - Uint32 *pixels; - int pitch; - SDL_LockTexture(jTex, NULL, (void **)&pixels, &pitch); - for (int i = 0; i < jWidth * jHeight; ++i) - pixels[i] = paleta[jScreen->data[i]]; - SDL_UnlockTexture(jTex); - SDL_RenderCopy(jRen, jTex, NULL, NULL); - SDL_RenderPresent(jRen); -} - -void jPutPixel(int x, int y, Uint8 color) -{ - if (x < 0 || y < 0 || x >= jDestSurf->w || y >= jDestSurf->h || color == transparentColor) - return; - jDestSurf->data[x + y * jDestSurf->w] = color; -} - -Uint8 jGetPixel(int x, int y) -{ - return jSourceSurf->data[x + y * jSourceSurf->w]; -} \ No newline at end of file diff --git a/source/common/surface.h b/source/common/surface.h deleted file mode 100644 index 2f63387..0000000 --- a/source/common/surface.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once -#include - -typedef struct jSurface_s *jSurface; - -void init(); -void update(); - -jSurface jNewSurface(int w, int h); -void jDeleteSurface(jSurface surf); -void jSetDest(jSurface surf); -void jSetSource(jSurface surf); - -jSurface jLoadSurface(const char* filename); - -void jPutPixel(int x, int y, Uint8 color); -Uint8 jGetPixel(int x, int y); - -void jBlit(int dx, int dy, int sx, int sy, int w, int h); - -void jInit(const char *titol, int w, int h, int z); - -void jSetPal(int index, Uint32 color); -void jLoadPal(const char *filename); - -void jCls(Uint8 color); - -void jFlip(); diff --git a/source/common/texture.cpp b/source/common/texture.cpp index dce9ed2..e9860d6 100644 --- a/source/common/texture.cpp +++ b/source/common/texture.cpp @@ -2,6 +2,7 @@ #include "texture.h" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" +#include "gif.c" #include // Constructor @@ -12,14 +13,36 @@ Texture::Texture(SDL_Renderer *renderer, std::string path, bool verbose) this->path = path; // Inicializa + surface = nullptr; texture = nullptr; width = 0; height = 0; + for (int i = 0; i < 256; ++i) + { + paleta[i] = 0; + } // Carga el fichero en la textura if (path != "") { - loadFromFile(path, renderer, verbose); + // Obtiene la extensión + const std::string extension = path.substr(path.find_last_of(".") + 1); + + // .png + if (extension == "png") + { + loadFromFile(path, renderer, verbose); + } + + // .gif + else if (extension == "gif") + { + surface = loadSurface(path.c_str()); + loadPal(path.c_str()); + setPal(0, 0x00000000); + createBlank(renderer, width, height); + flipSurface(); + } } } @@ -109,10 +132,10 @@ bool Texture::loadFromFile(std::string path, SDL_Renderer *renderer, bool verbos } // Crea una textura en blanco -bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess access) +bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_PixelFormatEnum format, SDL_TextureAccess access) { // Crea una textura sin inicializar - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, access, width, height); + texture = SDL_CreateTexture(renderer, format, access, width, height); if (texture == nullptr) { std::cout << "Unable to create blank texture! SDL Error: " << SDL_GetError() << std::endl; @@ -129,7 +152,7 @@ bool Texture::createBlank(SDL_Renderer *renderer, int width, int height, SDL_Tex // Libera la memoria de la textura void Texture::unload() { - // Libera la textura si existe + // Libera la textura if (texture != nullptr) { SDL_DestroyTexture(texture); @@ -137,6 +160,13 @@ void Texture::unload() width = 0; height = 0; } + + // Libera la surface + if (surface != nullptr) + { + deleteSurface(surface); + surface = nullptr; + } } // Establece el color para la modulacion @@ -205,4 +235,114 @@ bool Texture::reLoad() SDL_Texture *Texture::getSDLTexture() { return texture; +} + +// Crea una nueva surface +Surface Texture::newSurface(int w, int h) +{ + Surface surf = (Surface)malloc(sizeof(surface_s)); + surf->w = w; + surf->h = h; + surf->data = (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); +} + +// Crea una surface desde un fichero .gif +Surface Texture::loadSurface(const char *filename) +{ + FILE *f = fopen(filename, "rb"); + if (!f) + { + return NULL; + } + + 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 == NULL) + { + return NULL; + } + + Surface surface = (Surface)malloc(sizeof(surface_s)); + surface->w = w; + surface->h = h; + surface->data = pixels; + free(buffer); + + this->width = w; + this->height = h; + + return surface; +} + +// Vuelca la surface en la textura +void Texture::flipSurface() +{ + Uint32 *pixels; + int pitch; + SDL_LockTexture(texture, nullptr, (void **)&pixels, &pitch); + for (int i = 0; i < width * height; ++i) + { + pixels[i] = paleta[surface->data[i]]; + } + SDL_UnlockTexture(texture); +} + +// Establece un color de la paleta +void Texture::setPal(int index, Uint32 color) +{ + paleta[index] = color; +} + +// Carga una paleta desde un fichero +void Texture::loadPal(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 == NULL) + { + return; + } + + free(buffer); + + for (int i = 0; i < 256; ++i) + { + paleta[i] = (pal[i] << 8) + 255; + } } \ No newline at end of file diff --git a/source/common/texture.h b/source/common/texture.h index d83d7e2..a7fe7ea 100644 --- a/source/common/texture.h +++ b/source/common/texture.h @@ -7,17 +7,46 @@ #ifndef TEXTURE_H #define TEXTURE_H +// Definiciones de tipos +struct surface_s +{ + Uint8 *data; + Uint16 w, h; +}; + +typedef struct surface_s *Surface; + class Texture { private: // Objetos y punteros SDL_Texture *texture; // La textura SDL_Renderer *renderer; // Renderizador donde dibujar la textura + Surface surface; // Surface para usar imagenes en formato gif con paleta // Variables - int width; // Ancho de la imagen - int height; // Alto de la imagen - std::string path; // Ruta de la imagen de la textura + int width; // Ancho de la imagen + int height; // Alto de la imagen + std::string path; // Ruta de la imagen de la textura + Uint32 paleta[256]; // Paleta para la surface + + // Crea una nueva surface + Surface newSurface(int w, int h); + + // Elimina una surface + void deleteSurface(Surface surface); + + // Crea una surface desde un fichero .gif + Surface loadSurface(const char *filename); + + // Vuelca la surface en la textura + void flipSurface(); + + // Establece un color de la paleta + void setPal(int index, Uint32 color); + + // Carga una paleta desde un fichero + void loadPal(const char *filename); public: // Constructor @@ -30,7 +59,7 @@ public: bool loadFromFile(std::string path, SDL_Renderer *renderer, bool verbose = false); // Crea una textura en blanco - bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING); + bool createBlank(SDL_Renderer *renderer, int width, int height, SDL_PixelFormatEnum format = SDL_PIXELFORMAT_RGBA8888, SDL_TextureAccess = SDL_TEXTUREACCESS_STREAMING); // Libera la memoria de la textura void unload(); diff --git a/source/game.cpp b/source/game.cpp index 48efa82..bfaf6c0 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -453,19 +453,19 @@ void Game::loadMedia() itemTextures.push_back(item6); // Texturas - Player1 - Texture *player1 = new Texture(renderer, asset->get("player1.png")); + Texture *player1 = new Texture(renderer, asset->get("player1.gif")); player1Textures.push_back(player1); - Texture *player1Power = new Texture(renderer, asset->get("player1_power.png")); + Texture *player1Power = new Texture(renderer, asset->get("player1_power.gif")); player1Textures.push_back(player1Power); playerTextures.push_back(player1Textures); // Texturas - Player2 - Texture *player2 = new Texture(renderer, asset->get("player2.png")); + Texture *player2 = new Texture(renderer, asset->get("player2.gif")); player2Textures.push_back(player2); - Texture *player2Power = new Texture(renderer, asset->get("player2_power.png")); + Texture *player2Power = new Texture(renderer, asset->get("player2_power.gif")); player2Textures.push_back(player2Power); playerTextures.push_back(player2Textures);