From 4149eb480be5e4aef66fed3376cd8b6dcd2153a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Arreola=20Rodr=C3=ADguez?= Date: Sun, 3 Jun 2018 17:38:38 -0500 Subject: [PATCH] =?UTF-8?q?Agrego=20generador=20de=20datos=20de=20colisi?= =?UTF-8?q?=C3=B3n.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- configure.ac | 1 + data/Makefile.am | 2 + data/collider/Makefile.am | 56 +++++ data/collider/generate-collider.c | 293 ++++++++++++++++++++++ data/collider/generate-penguins.c | 400 ++++++++++++++++++++++++++++++ data/collider/gfx_blit_func.c | 1 + data/collider/gfx_blit_func.h | 1 + data/collider/penguin_1.col | Bin 0 -> 3004 bytes data/collider/penguin_10.col | Bin 0 -> 3020 bytes data/collider/penguin_2.col | Bin 0 -> 3096 bytes data/collider/penguin_3.col | Bin 0 -> 2864 bytes data/collider/penguin_4.col | Bin 0 -> 3696 bytes data/collider/penguin_5.col | Bin 0 -> 4224 bytes data/collider/penguin_6.col | Bin 0 -> 4488 bytes data/collider/penguin_7.col | Bin 0 -> 3320 bytes data/collider/penguin_8.col | Bin 0 -> 2600 bytes data/collider/penguin_9.col | Bin 0 -> 2348 bytes data/collider/savepng.c | 155 ++++++++++++ data/collider/savepng.h | 46 ++++ 19 files changed, 955 insertions(+) create mode 100644 data/collider/Makefile.am create mode 100644 data/collider/generate-collider.c create mode 100644 data/collider/generate-penguins.c create mode 120000 data/collider/gfx_blit_func.c create mode 120000 data/collider/gfx_blit_func.h create mode 100755 data/collider/penguin_1.col create mode 100755 data/collider/penguin_10.col create mode 100755 data/collider/penguin_2.col create mode 100755 data/collider/penguin_3.col create mode 100755 data/collider/penguin_4.col create mode 100755 data/collider/penguin_5.col create mode 100755 data/collider/penguin_6.col create mode 100755 data/collider/penguin_7.col create mode 100755 data/collider/penguin_8.col create mode 100755 data/collider/penguin_9.col create mode 100644 data/collider/savepng.c create mode 100644 data/collider/savepng.h diff --git a/configure.ac b/configure.ac index 5431bf5..12c57ba 100644 --- a/configure.ac +++ b/configure.ac @@ -120,6 +120,7 @@ AC_CONFIG_FILES([ po/Makefile.in data/Makefile etc/Makefile etc/Info.plist + data/collider/Makefile ]) AC_OUTPUT diff --git a/data/Makefile.am b/data/Makefile.am index f238fc4..da9fc8f 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -77,3 +77,5 @@ EXTRA_DIST = \ desktop/128x128/coffee_bag.png \ desktop/256x256/coffee_bag.png \ coffee_bag.ico + +SUBDIRS = collider diff --git a/data/collider/Makefile.am b/data/collider/Makefile.am new file mode 100644 index 0000000..f36abb6 --- /dev/null +++ b/data/collider/Makefile.am @@ -0,0 +1,56 @@ +collidergamedatadir = $(pkgdatadir)/data/collider + +nobase_dist_collidergamedata_DATA = \ + penguin_1.col \ + penguin_2.col \ + penguin_3.col \ + penguin_4.col \ + penguin_5.col \ + penguin_6.col \ + penguin_7.col \ + penguin_8.col \ + penguin_9.col \ + penguin_10.col + +noinst_PROGRAMS = penguin-generator collider-generator +penguin_generator_SOURCES = generate-penguins.c \ + savepng.c savepng.h \ + gfx_blit_func.c gfx_blit_func.h + +penguin_generator_CPPFLAGS = -DDATA_DIR=\"$(top_srcdir)/data\" -DBUILD_DIR=\"$(builddir)\" $(AM_CPPFLAGS) +penguin_generator_CFLAGS = $(SDL_CFLAGS) $(SDL_image_CFLAGS) $(AM_CFLAGS) +if MACOSX +# En MAC OS X, hay que ligar/compilar contra los frameworks +penguin_generator_LDFLAGS = -Wl,-rpath,@loader_path/../Frameworks $(AM_LDFLAGS) +else +penguin_generator_LDADD = $(SDL_LIBS) $(SDL_image_LIBS) -lm -lpng +endif + +collider_generator_SOURCES = generate-collider.c +collider_generator_CFLAGS = $(SDL_CFLAGS) $(SDL_image_CFLAGS) $(AM_CFLAGS) +if MACOSX +# En MAC OS X, hay que ligar/compilar contra los frameworks +collider_generator_LDFLAGS = -Wl,-rpath,@loader_path/../Frameworks $(AM_LDFLAGS) +else +collider_generator_LDADD = $(SDL_LIBS) $(SDL_image_LIBS) +endif + +#SUFFIXES = .png .col + +COLLIDER_GENERATOR=$(builddir)/collider-generator +PENGUIN_GENERATOR=$(builddir)/penguin-generator +PENGUINS=1 2 3 4 5 6 7 8 9 10 +colliders: collider-generator penguin-generator + $(PENGUIN_GENERATOR) + $(COLLIDER_GENERATOR) penguin_1.png penguin_1.col + $(COLLIDER_GENERATOR) penguin_2.png penguin_2.col + $(COLLIDER_GENERATOR) penguin_3.png penguin_3.col + $(COLLIDER_GENERATOR) penguin_4.png penguin_4.col + $(COLLIDER_GENERATOR) penguin_5.png penguin_5.col + $(COLLIDER_GENERATOR) penguin_6.png penguin_6.col + $(COLLIDER_GENERATOR) penguin_7.png penguin_7.col + $(COLLIDER_GENERATOR) penguin_8.png penguin_8.col + $(COLLIDER_GENERATOR) penguin_9.png penguin_9.col + $(COLLIDER_GENERATOR) penguin_10.png penguin_10.col + + rm penguin_1.png penguin_2.png penguin_3.png penguin_4.png penguin_5.png penguin_6.png penguin_7.png penguin_8.png penguin_9.png penguin_10.png diff --git a/data/collider/generate-collider.c b/data/collider/generate-collider.c new file mode 100644 index 0000000..79993d4 --- /dev/null +++ b/data/collider/generate-collider.c @@ -0,0 +1,293 @@ +/* + * beans.c + * This file is part of Bean Counters Classic + * + * Copyright (C) 2018 - Félix Arreola Rodríguez + * + * Bean Counters Classic is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Bean Counters Classic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bean Counters Classic; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +typedef struct _Collider { + Uint32 offset_x, offset_y; + Uint32 size_w, size_h; + + Uint32 pitch; + + Uint32 *pixels; +} Collider; + +Uint32 collider_extract_block (Collider *c, int y, int x, int size); +static Uint32 collider_htonl (Uint32 byte); + +Collider *generate_optimized (Collider *c, int min_x, int min_y, int max_x, int max_y) { + Collider *c_o; + Uint32 temp; + int map_size; + int bit_pos; + int s, x, h; + + c_o = (Collider *) malloc (sizeof (Collider)); + + c_o->size_w = max_x - min_x; + c_o->size_h = max_y - min_y; + c_o->offset_x = min_x; + c_o->offset_y = min_y; + + if (c_o->size_w % 32 != 0) { + c_o->pitch = (c_o->size_w / 32) + 2; + } else { + c_o->pitch = (c_o->size_w / 32) + 1; + } + map_size = c_o->pitch * c_o->size_h; + + /* Reservar los bytes necesarios */ + c_o->pixels = (Uint32 *) malloc (sizeof (Uint32) * map_size); + + memset (c_o->pixels, 0, sizeof (Uint32) * map_size); + /* Ejecutar la optimización */ + for (h = min_y; h < max_y; h++) { + s = max_x - min_x; + x = min_x; + + while (s > 0) { + temp = collider_extract_block (c, h, x, s); + + bit_pos = ((h - min_y) * c_o->pitch) + ((x - min_x) / 32); + + c_o->pixels[bit_pos] = temp; + + x = x + 32; + s = s - 32; + } + } + + free (c->pixels); + free (c); + return c_o; +} + +Collider *generate_collider (SDL_Surface *imagen) { + Uint8 *p; + int bpp, pos; + int g, h, i; + Uint32 pixel; + Uint32 temp; + Uint8 alpha; + int min_x, min_y, max_x, max_y; + int map_size; + int bit_pos; + Uint32 bit_a_prender; + int s, x; + + Collider *c; + + c = (Collider *) malloc (sizeof (Collider)); + + c->size_w = imagen->w; + c->size_h = imagen->h; + c->offset_x = c->offset_y = 0; + + max_x = max_y = 0; + min_x = imagen->w; + min_y = imagen->h; + + if (c->size_w % 32 != 0) { + c->pitch = (c->size_w / 32) + 2; + } else { + c->pitch = (c->size_w / 32) + 1; + } + map_size = c->pitch * c->size_h; + + /* Reservar los bytes necesarios */ + c->pixels = (Uint32 *) malloc (sizeof (Uint32) * map_size); + + memset (c->pixels, 0, sizeof (Uint32) * map_size); + + bpp = imagen->format->BytesPerPixel; + for (h = 0; h < imagen->h; h++) { + for (g = 0; g < imagen->w; g++) { + pos = (h * imagen->pitch) / bpp + g; + + pixel = ((Uint32 *) imagen->pixels)[pos]; + + temp = pixel & imagen->format->Amask; + temp = temp >> imagen->format->Ashift; + temp = temp << imagen->format->Aloss; + + alpha = (Uint8) temp; + + bit_pos = (h * c->pitch) + (g / 32); + + if (alpha != 0) { + bit_a_prender = 2147483648u >> (g % 32); + + c->pixels[bit_pos] = c->pixels[bit_pos] | bit_a_prender; + + if (h < min_y) { + min_y = h; + } + + if (h > max_y) { + max_y = h; + } + + if (g < min_x) { + min_x = g; + } + + if (g > max_x) { + max_x = g; + } + } + } + } + max_x++; + max_y++; + + if (min_x != 0 || min_y != 0 || max_x != imagen->w || max_y != imagen->h) { + return generate_optimized (c, min_x, min_y, max_x, max_y); + } + + return c; +} + +Uint32 collider_extract_block (Collider *c, int y, int x, int size) { + int bit_pos; + int align; + Uint32 res; + + bit_pos = c->pitch * y + (x / 32); + align = 32 - (x % 32); + + if (align == 32) { + res = c->pixels[bit_pos]; + } else { + res = c->pixels[bit_pos] << (32 - align); + res = res | (c->pixels[bit_pos + 1] >> align); + } + + if (size < 32) { + /* Quitar los bits sobrantes */ + res = res ^ (res & ((1 << (32 - size)) - 1)); + } + + return res; +} + +static Uint32 collider_htonl (Uint32 byte) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + return byte; +#else + unsigned char *data = (unsigned char *) &byte; + + return (data[3]<<0) | (data[2]<<8) | (data[1]<<16) | (data[0]<<24); +#endif +} + +void save_collider (Collider *c, int fd) { + Uint32 w, g, h; + int res; + w = 1; /* Número de versión */ + res = write (fd, &w, sizeof (w)); + + w = 0; /* Sin uso, solo para alinear bytes */ + res = write (fd, &w, sizeof (w)); + + w = c->offset_x; + res = write (fd, &w, sizeof (w)); + + w = c->offset_y; + res = write (fd, &w, sizeof (w)); + + w = c->size_w; + write (fd, &w, sizeof (w)); + + w = c->size_h; + write (fd, &w, sizeof (w)); + + for (h = 0; h < c->size_h; h++) { + for (g = 0; g < c->pitch; g++) { + w = c->pixels[(h * c->pitch) + g]; + write (fd, &w, sizeof (w)); + } + } +} + +int main (int argc, char *argv[]) { + int g; + SDL_Surface *image; + Collider *c; + + /* Inicializar el Video SDL */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf (stderr, + "Error: Can't initialize the video subsystem\n" + "The error returned by SDL is:\n" + "%s\n", SDL_GetError()); + exit (1); + } + + if (argc < 3) { + fprintf (stderr, "Need two arguments, png-file output-file\n"); + + exit (1); + } + + image = IMG_Load (argv[1]); + + if (image == NULL) { + fprintf (stderr, + "Failed to load data file:\n" + "%s\n" + "The error returned by SDL is:\n" + "%s\n", argv[1], SDL_GetError()); + SDL_Quit (); + exit (1); + } + + c = generate_collider (image); + + int fd; + + fd = open (argv[2], O_CREAT | O_TRUNC | O_WRONLY, 0777); + + if (fd < 0) { + fprintf (stderr, "Couldn't open %s for file writing\n", argv[2]); + + exit (1); + } + + save_collider (c, fd); + + close (fd); + + return 0; +} + diff --git a/data/collider/generate-penguins.c b/data/collider/generate-penguins.c new file mode 100644 index 0000000..a70ff45 --- /dev/null +++ b/data/collider/generate-penguins.c @@ -0,0 +1,400 @@ +/* + * beans.c + * This file is part of Bean Counters Classic + * + * Copyright (C) 2018 - Félix Arreola Rodríguez + * + * Bean Counters Classic is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Bean Counters Classic is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Bean Counters Classic; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include + +#include +#include + +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gfx_blit_func.h" +#include "savepng.h" + +#define RANDOM(x) ((int) (x ## .0 * rand () / (RAND_MAX + 1.0))) + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN +#define RMASK 0xff000000 +#define GMASK 0x00ff0000 +#define BMASK 0x0000ff00 +#define AMASK 0x000000ff +#else +#define RMASK 0x000000ff +#define GMASK 0x0000ff00 +#define BMASK 0x00ff0000 +#define AMASK 0xff000000 +#endif + +/* Imágenes de los pingüinos */ +enum { + IMG_PENGUIN_1_BACK, + IMG_PENGUIN_1_COLOR, + IMG_PENGUIN_1_FRONT, + + IMG_PENGUIN_2_BACK, + IMG_PENGUIN_2_COLOR, + IMG_PENGUIN_2_FRONT, + + IMG_PENGUIN_3_BACK, + IMG_PENGUIN_3_COLOR, + IMG_PENGUIN_3_FRONT, + + IMG_PENGUIN_4_BACK, + IMG_PENGUIN_4_COLOR, + IMG_PENGUIN_4_FRONT, + + IMG_PENGUIN_5_BACK, + IMG_PENGUIN_5_COLOR, + IMG_PENGUIN_5_1_FRONT, + IMG_PENGUIN_5_2_FRONT, + IMG_PENGUIN_5_3_FRONT, + + IMG_PENGUIN_6_1_BACK, + IMG_PENGUIN_6_2_BACK, + IMG_PENGUIN_6_1_COLOR, + IMG_PENGUIN_6_2_COLOR, + + IMG_PENGUIN_6_1_FRONT, + IMG_PENGUIN_6_2_FRONT, + IMG_PENGUIN_6_3_FRONT, + IMG_PENGUIN_6_4_FRONT, + IMG_PENGUIN_6_5_FRONT, + IMG_PENGUIN_6_6_FRONT, + + IMG_PENGUIN_7_BACK, + IMG_PENGUIN_7_COLOR, + IMG_PENGUIN_7_FRONT, + + IMG_PENGUIN_8_BACK, + IMG_PENGUIN_8_COLOR, + IMG_PENGUIN_8_1_FRONT, + IMG_PENGUIN_8_2_FRONT, + IMG_PENGUIN_8_3_FRONT, + + NUM_PENGUIN_IMGS +}; + +const char *penguin_images_names[NUM_PENGUIN_IMGS] = { + "images/penguin_1_back.png", + "images/penguin_1_color.png", + "images/penguin_1_front.png", + + "images/penguin_2_back.png", + "images/penguin_2_color.png", + "images/penguin_2_front.png", + + "images/penguin_3_back.png", + "images/penguin_3_color.png", + "images/penguin_3_front.png", + + "images/penguin_4_back.png", + "images/penguin_4_color.png", + "images/penguin_4_front.png", + + "images/penguin_5_back.png", + "images/penguin_5_color.png", + "images/penguin_5_1_front.png", + "images/penguin_5_2_front.png", + "images/penguin_5_3_front.png", + + "images/penguin_6_1_back.png", + "images/penguin_6_2_back.png", + "images/penguin_6_1_color.png", + "images/penguin_6_2_color.png", + + "images/penguin_6_1_front.png", + "images/penguin_6_2_front.png", + "images/penguin_6_3_front.png", + "images/penguin_6_4_front.png", + "images/penguin_6_5_front.png", + "images/penguin_6_6_front.png", + + "images/penguin_7_back.png", + "images/penguin_7_color.png", + "images/penguin_7_front.png", + + "images/penguin_8_back.png", + "images/penguin_8_color.png", + "images/penguin_8_1_front.png", + "images/penguin_8_2_front.png", + "images/penguin_8_3_front.png" +}; + +enum { + PENGUIN_FRAME_1, + PENGUIN_FRAME_2, + PENGUIN_FRAME_3, + PENGUIN_FRAME_4, + PENGUIN_FRAME_5_1, + PENGUIN_FRAME_5_2, + PENGUIN_FRAME_5_3, + PENGUIN_FRAME_6_1, + PENGUIN_FRAME_6_2, + PENGUIN_FRAME_6_3, + PENGUIN_FRAME_6_4, + PENGUIN_FRAME_6_5, + PENGUIN_FRAME_6_6, + PENGUIN_FRAME_7, + PENGUIN_FRAME_8, + PENGUIN_FRAME_9, + PENGUIN_FRAME_10, + + NUM_PENGUIN_FRAMES +}; + +const SDL_Color penguin_colors[18] = { + {0, 51, 102}, + {51, 51, 51}, + {206, 0, 0}, + {255, 204, 0}, + {0, 153, 0}, + {153, 102, 0}, + {255, 49, 156}, + {99, 0, 156}, + {0, 156, 204}, + {255, 102, 0}, + {0, 102, 0}, + {255, 99, 99}, + {139, 227, 3}, + {28, 150, 163}, + {240, 240, 216}, + {174, 159, 200}, + {128, 33, 75}, + {46, 71, 170} +}; + +void setup_and_color_penguin (void); + +SDL_Surface * penguin_images[NUM_PENGUIN_FRAMES]; +int color_penguin = 0; + +int main (int argc, char *argv[]) { + int g; + /* Inicializar el Video SDL */ + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + fprintf (stderr, + "Error: Can't initialize the video subsystem\n" + "The error returned by SDL is:\n" + "%s\n", SDL_GetError()); + exit (1); + } + + /* Generador de números aleatorios */ + srand ((unsigned int) getpid ()); + + /* Colorear y organizar las imágenes de pingüinos */ + color_penguin = RANDOM (18); + + setup_and_color_penguin (); + + char buffer_file [8192]; + for (g = 0; g <= PENGUIN_FRAME_4; g++) { + sprintf (buffer_file, "%s/penguin_%i.png", BUILD_DIR, g + 1); + SDL_SavePNG (penguin_images[g], buffer_file); + } + + /* El pingüino 5 se arma de 3 frames */ + SDL_gfxBlitRGBA (penguin_images[PENGUIN_FRAME_5_2], NULL, penguin_images[PENGUIN_FRAME_5_1], NULL); + SDL_gfxBlitRGBA (penguin_images[PENGUIN_FRAME_5_3], NULL, penguin_images[PENGUIN_FRAME_5_1], NULL); + + sprintf (buffer_file, "%s/penguin_5.png", BUILD_DIR); + SDL_SavePNG (penguin_images[PENGUIN_FRAME_5_1], buffer_file); + + /* El pingüino 6 se arma de 6 frames */ + SDL_gfxBlitRGBA (penguin_images[PENGUIN_FRAME_6_2], NULL, penguin_images[PENGUIN_FRAME_6_1], NULL); + SDL_gfxBlitRGBA (penguin_images[PENGUIN_FRAME_6_3], NULL, penguin_images[PENGUIN_FRAME_6_1], NULL); + SDL_gfxBlitRGBA (penguin_images[PENGUIN_FRAME_6_4], NULL, penguin_images[PENGUIN_FRAME_6_1], NULL); + SDL_gfxBlitRGBA (penguin_images[PENGUIN_FRAME_6_5], NULL, penguin_images[PENGUIN_FRAME_6_1], NULL); + SDL_gfxBlitRGBA (penguin_images[PENGUIN_FRAME_6_6], NULL, penguin_images[PENGUIN_FRAME_6_1], NULL); + + sprintf (buffer_file, "%s/penguin_6.png", BUILD_DIR); + SDL_SavePNG (penguin_images[PENGUIN_FRAME_6_1], buffer_file); + + sprintf (buffer_file, "%s/penguin_7.png", BUILD_DIR); + SDL_SavePNG (penguin_images[PENGUIN_FRAME_7], buffer_file); + + sprintf (buffer_file, "%s/penguin_8.png", BUILD_DIR); + SDL_SavePNG (penguin_images[PENGUIN_FRAME_8], buffer_file); + + sprintf (buffer_file, "%s/penguin_9.png", BUILD_DIR); + SDL_SavePNG (penguin_images[PENGUIN_FRAME_9], buffer_file); + + sprintf (buffer_file, "%s/penguin_10.png", BUILD_DIR); + SDL_SavePNG (penguin_images[PENGUIN_FRAME_10], buffer_file); + + return 0; +} + +void setup_and_color_penguin (void) { + int g; + SDL_Surface * image, *color_surface; + SDL_Surface *temp_penguins[NUM_PENGUIN_IMGS]; + + char buffer_file[8192]; + char *systemdata_path = DATA_DIR; + + for (g = 0; g < NUM_PENGUIN_IMGS; g++) { + sprintf (buffer_file, "%s/%s", systemdata_path, penguin_images_names[g]); + image = IMG_Load (buffer_file); + + if (image == NULL) { + fprintf (stderr, + "Failed to load data file:\n" + "%s\n" + "The error returned by SDL is:\n" + "%s\n", buffer_file, SDL_GetError()); + SDL_Quit (); + exit (1); + } + + temp_penguins[g] = image; + /* TODO: Mostrar la carga de porcentaje */ + } + + color_surface = SDL_CreateRGBSurface (SDL_SWSURFACE, 196, 199, 32, RMASK, GMASK, BMASK, AMASK); + SDL_FillRect (color_surface, NULL, SDL_MapRGB (color_surface->format, penguin_colors[color_penguin].r, penguin_colors[color_penguin].g, penguin_colors[color_penguin].b)); + + for (g = 0; g < 4; g++) { + penguin_images[PENGUIN_FRAME_1 + g] = temp_penguins[IMG_PENGUIN_1_BACK + (g * 3)]; + + /* Colorear el pingüino */ + SDL_BlitSurface (color_surface, NULL, temp_penguins[IMG_PENGUIN_1_COLOR + (g * 3)], NULL); + + /* Copiar el color sobre el fondo */ + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_1_COLOR + (g * 3)], NULL, penguin_images[PENGUIN_FRAME_1 + g], NULL); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_1_COLOR + (g * 3)]); + temp_penguins[IMG_PENGUIN_1_COLOR + (g * 3)] = NULL; + + /* Copiar el frente */ + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_1_FRONT + (g * 3)], NULL, penguin_images[PENGUIN_FRAME_1 + g], NULL); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_1_FRONT + (g * 3)]); + temp_penguins[IMG_PENGUIN_1_FRONT + (g * 3)] = NULL; + } + + /* Duplicar el fondo del frame 5 */ + penguin_images[PENGUIN_FRAME_5_1] = temp_penguins[IMG_PENGUIN_5_BACK]; + penguin_images[PENGUIN_FRAME_5_2] = SDL_CreateRGBSurface (SDL_SWSURFACE, 196, 199, 32, RMASK, GMASK, BMASK, AMASK); + penguin_images[PENGUIN_FRAME_5_3] = SDL_CreateRGBSurface (SDL_SWSURFACE, 196, 199, 32, RMASK, GMASK, BMASK, AMASK); + + SDL_SetAlpha (penguin_images[PENGUIN_FRAME_5_1], 0, 0); + SDL_BlitSurface (penguin_images[PENGUIN_FRAME_5_1], NULL, penguin_images[PENGUIN_FRAME_5_2], NULL); + SDL_BlitSurface (penguin_images[PENGUIN_FRAME_5_1], NULL, penguin_images[PENGUIN_FRAME_5_3], NULL); + SDL_SetAlpha (penguin_images[PENGUIN_FRAME_5_1], SDL_SRCALPHA, SDL_ALPHA_OPAQUE); + + /* Colorear el pingüino */ + SDL_BlitSurface (color_surface, NULL, temp_penguins[IMG_PENGUIN_5_COLOR], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_5_COLOR], NULL, penguin_images[PENGUIN_FRAME_5_1], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_5_COLOR], NULL, penguin_images[PENGUIN_FRAME_5_2], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_5_COLOR], NULL, penguin_images[PENGUIN_FRAME_5_3], NULL); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_5_COLOR]); + temp_penguins[IMG_PENGUIN_5_COLOR] = NULL; + + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_5_1_FRONT], NULL, penguin_images[PENGUIN_FRAME_5_1], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_5_2_FRONT], NULL, penguin_images[PENGUIN_FRAME_5_2], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_5_3_FRONT], NULL, penguin_images[PENGUIN_FRAME_5_3], NULL); + + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_5_1_FRONT]); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_5_2_FRONT]); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_5_3_FRONT]); + + temp_penguins[IMG_PENGUIN_5_1_FRONT] = temp_penguins[IMG_PENGUIN_5_2_FRONT] = temp_penguins[IMG_PENGUIN_5_3_FRONT] = NULL; + + /* Vamos por el frame 6 */ + SDL_SetAlpha (temp_penguins[IMG_PENGUIN_6_1_BACK], 0, 0); + SDL_SetAlpha (temp_penguins[IMG_PENGUIN_6_2_BACK], 0, 0); + + SDL_BlitSurface (color_surface, NULL, temp_penguins[IMG_PENGUIN_6_1_COLOR], NULL); + SDL_BlitSurface (color_surface, NULL, temp_penguins[IMG_PENGUIN_6_2_COLOR], NULL); + + /* 6 frames de animación del frame 6 */ + for (g = 0; g < 6; g++) { + penguin_images[PENGUIN_FRAME_6_1 + g] = SDL_CreateRGBSurface (SDL_SWSURFACE, 196, 199, 32, RMASK, GMASK, BMASK, AMASK); + + /* Clonar el fondo */ + SDL_BlitSurface (temp_penguins[IMG_PENGUIN_6_1_BACK + (g % 2)], NULL, penguin_images[PENGUIN_FRAME_6_1 + g], NULL); + + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_6_1_COLOR + (g % 2)], NULL, penguin_images[PENGUIN_FRAME_6_1 + g], NULL); + + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_6_1_FRONT + g], NULL, penguin_images[PENGUIN_FRAME_6_1 + g], NULL); + + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_6_1_FRONT + g]); + temp_penguins[IMG_PENGUIN_6_1_FRONT + g] = NULL; + } + + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_6_1_BACK]); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_6_2_BACK]); + temp_penguins[IMG_PENGUIN_6_1_BACK] = temp_penguins[IMG_PENGUIN_6_2_BACK] = NULL; + + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_6_1_COLOR]); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_6_2_COLOR]); + temp_penguins[IMG_PENGUIN_6_1_COLOR] = temp_penguins[IMG_PENGUIN_6_2_COLOR] = NULL; + + /* Armar el frame 7 */ + penguin_images[PENGUIN_FRAME_7] = temp_penguins[IMG_PENGUIN_7_BACK]; + + /* Colorear el pingüino */ + SDL_BlitSurface (color_surface, NULL, temp_penguins[IMG_PENGUIN_7_COLOR], NULL); + + /* Copiar el color sobre el fondo */ + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_7_COLOR], NULL, penguin_images[PENGUIN_FRAME_7], NULL); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_7_COLOR]); + temp_penguins[IMG_PENGUIN_7_COLOR] = NULL; + + /* Copiar el frente */ + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_7_FRONT], NULL, penguin_images[PENGUIN_FRAME_7], NULL); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_7_FRONT]); + temp_penguins[IMG_PENGUIN_7_FRONT] = NULL; + + /* Generar los otros 3 estados */ + penguin_images[PENGUIN_FRAME_8] = temp_penguins[IMG_PENGUIN_8_BACK]; + penguin_images[PENGUIN_FRAME_9] = SDL_CreateRGBSurface (SDL_SWSURFACE, 196, 199, 32, RMASK, GMASK, BMASK, AMASK); + penguin_images[PENGUIN_FRAME_10] = SDL_CreateRGBSurface (SDL_SWSURFACE, 196, 199, 32, RMASK, GMASK, BMASK, AMASK); + + SDL_SetAlpha (penguin_images[PENGUIN_FRAME_8], 0, 0); + SDL_BlitSurface (penguin_images[PENGUIN_FRAME_8], NULL, penguin_images[PENGUIN_FRAME_9], NULL); + SDL_BlitSurface (penguin_images[PENGUIN_FRAME_8], NULL, penguin_images[PENGUIN_FRAME_10], NULL); + SDL_SetAlpha (penguin_images[PENGUIN_FRAME_8], SDL_SRCALPHA, SDL_ALPHA_OPAQUE); + + /* Colorear el pingüino */ + SDL_BlitSurface (color_surface, NULL, temp_penguins[IMG_PENGUIN_8_COLOR], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_8_COLOR], NULL, penguin_images[PENGUIN_FRAME_8], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_8_COLOR], NULL, penguin_images[PENGUIN_FRAME_9], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_8_COLOR], NULL, penguin_images[PENGUIN_FRAME_10], NULL); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_8_COLOR]); + temp_penguins[IMG_PENGUIN_8_COLOR] = NULL; + + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_8_1_FRONT], NULL, penguin_images[PENGUIN_FRAME_8], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_8_2_FRONT], NULL, penguin_images[PENGUIN_FRAME_9], NULL); + SDL_gfxBlitRGBA (temp_penguins[IMG_PENGUIN_8_3_FRONT], NULL, penguin_images[PENGUIN_FRAME_10], NULL); + + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_8_1_FRONT]); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_8_2_FRONT]); + SDL_FreeSurface (temp_penguins[IMG_PENGUIN_8_3_FRONT]); + + temp_penguins[IMG_PENGUIN_8_1_FRONT] = temp_penguins[IMG_PENGUIN_8_2_FRONT] = temp_penguins[IMG_PENGUIN_8_3_FRONT] = NULL; +} diff --git a/data/collider/gfx_blit_func.c b/data/collider/gfx_blit_func.c new file mode 120000 index 0000000..69d856a --- /dev/null +++ b/data/collider/gfx_blit_func.c @@ -0,0 +1 @@ +../../src/gfx_blit_func.c \ No newline at end of file diff --git a/data/collider/gfx_blit_func.h b/data/collider/gfx_blit_func.h new file mode 120000 index 0000000..50bc522 --- /dev/null +++ b/data/collider/gfx_blit_func.h @@ -0,0 +1 @@ +../../src/gfx_blit_func.h \ No newline at end of file diff --git a/data/collider/penguin_1.col b/data/collider/penguin_1.col new file mode 100755 index 0000000000000000000000000000000000000000..b1fb4e5bcb2664e76a04809dbd42e801c44de093 GIT binary patch literal 3004 zcmds(J#O4E5QQmhVRzf6QOx>m z^3$8)a5$7a1Z`i?ea7zxes7AtYS;Wd%f2;MI=RBWcl^y4*wV4R!q$$zvux|wo@G>R zpX(rmoqg)Cmz||u_j<5chetB<&gP*$?XeP*Dd$_&mAKH8OlIvcE^(z%*}dxKNHi(a zM;I?);xH9`WQkDU+mwyWis>L>U4#>aL%g-0#^`piUqm<7(H$(Q?ssJbh7GeV z6sp4jY5f-)*c~?w0YJ#Mfg{b;bMZG3w}yHF?47f%kEiHF?H0X4@WX&d7A{Gp&tQ zrwm7g=(W|l`WVwXZEgQ&b|rs$zU_JRnAT9M>oKj#wq82S>ba@ONp%eyJ2h_iGW&Y5 z`ifJ<=!TS|(sQbF2C5sN@T4tv}Nf?!IRTYMOpd5wbcb`Fb4bnJ*&Cd}KNuc|Lm5brYv6V>G$wQaJNflx6iR zm^vUQ6vUyWW7eEL?ab>kDHCObV*#6u9Lop0G8lBKLe5fmQ; zY;7|q*pbgJ(N6t`Z4~B%Yx2c~_7Mr+o_=Es8T^UDd;~kK-g_j_&l~faHJ`C*V@MqI zE@PXW!@{YaeOvQ(!dMmuJ80D zHU9_mC;NSbrFkjsQs#>No@CiMq)TGGXIVJ+dM!Q6Mvag6NaiF4eA8JkXRKcHp>{vc z!u`TMvAs+Efhw)t{hr_#f%8q$JCffU)3fEs*0lH8IPdhGZTH;H)Hcxc-6QAS9PMPF z&Lll2=tk393p+cO|!lS|)x5>sbZ;2f~e`e>= zvGv#@ZOS?Xp6Zq1plDb7zhvjc8KvFKb>%no>w%3rnco!sK4hlhkB0}l&l$jgH3I>2 IW9Ww8KmPO1oB#j- literal 0 HcmV?d00001 diff --git a/data/collider/penguin_2.col b/data/collider/penguin_2.col new file mode 100755 index 0000000000000000000000000000000000000000..516042bbac71ed1a576ed12dad4d9c2d5b1afb4a GIT binary patch literal 3096 zcmcJRO_JLn5QXLP!n@27I6!WYMRYW@&8>749o}L9j6~Se&N_~u)WFet;os!loM`_@}4K~`xA}_w(^W$mg`fV80LL^AmC^G)cEew zr1sMIb>OM-`@nPKkAV}T-%b0b1pz^8PEO?_|xZQh>tsQbU#Lw&l zm*YN0Og`DijK_V<@)`PNENPK%%3+Ti?~L!NkNe?koM4-5HPT*VYBnadl+e!BHlS3w*j{1f{X1&hXQU5Ebid+5h|%@q z{)9NJfeZr5g=Pu8i|0e!>ov*?k$T%v`d&Ht(tRE7UW_ZbXXpIu;4rCL4Eroy=wj(ej?PUcc+qtDRjY z+dDf?hBvMK$+6ypzJDL8w|Smk2zpk(Sr??=IG;j+*~|&dX4BuWnG52Yzu#vluiC;%uK}3$ f2hwv)&kMwC!NZ?M>cZ@ap=zx0x(oiCup5ydLQEG@ literal 0 HcmV?d00001 diff --git a/data/collider/penguin_4.col b/data/collider/penguin_4.col new file mode 100755 index 0000000000000000000000000000000000000000..a6dc525c03316987c0b37b6bdb27a09838fd9797 GIT binary patch literal 3696 zcmb`~L5|xn3(j&exvJuzQ4oDLz}wtNbOwmgP;)3bE{ z{<=g5?taUs`?g2st@yP1EHiA4Ew6rV#xvp!)W(OG=8_ulYxBwbt@&x-(fhr{C+|9k z?7XPUfsJQ=>^w1xKU+Lc%-m{%cw**Pi+6rA=LuW<-8`b(+7NmHPY^$YXYljDuiymn zP@`N@HclRJ%Rf3_7W}C3Sfj)VYV*Y!MVIr||4HM$NAM+YMLt86%+u1(>e>8+PUbIo zT{_71qbn;x!2k{kLt7QCk;IB^cGHXlaL%pQ{;o8pE3Tgek3^mGw@#npK?2a z_dcT2H+5HUw!U~zBrbG~=bKiYm0w>8c0#`J5lGUx&I!~$a9OwX8_wnm(N+A<(;+vc#(4!S&x{SXFT_Wr$IlT<$2J5 z?>vQNzI#2j{=0Q~=-s-<)=%f7x>6t2XIIZ!=QCeunQWb}dbs~U*R|&*2T$Pe{B_UA zk;C)X#e=)&DLj`yUkt>b`n) zVR7xp_dl!0+Rqw48o%Wsxp-R_@ZY%q`7DQVy8fT=HykJYPI(K#>S4`i;smimbqW!XgmU!^yZbA?`@N9YxFg7ykNLW*v(7>xQUiQ=cm zLXj*YAhG;RQ>6G!drnIopKK&kSoS>k)+MY9LIXqI?+25=sf$q_zYnxA#ThZmDnJbs_ndk@MQ?D3c?;Ic{}N6TUm1#cdg0Z^jWOt!w)6IyCP4XYRV1 zaar8*%DrBVZ*mRu86WkTnthP_b%4$I-t1Skl_S{ycpU8Yd0{Mm-pXhG-<#_`jO$ML zEg@&Am$y%GJLW;~y}k9T6~4+C^tm>i2Og9U`s_Nn{c?Ki`uz04zUwahTrc+BxYk(9 z5|3y=C3yUc#J}KyS1uEc=PTKx{dXSNp5B82FRJe6^4RS!^?NeOwH&^6{;-w2Dqr`` zU7w7p_kY*l;$j>dD!ygNOyl=`jJWG##8H6iMHuzf8Fzh;?BA7B{BGS>@;I?)&ik;E zJ@Y`E_j&f6L;7*`;_vXC>QZW4D-4-utrxiV|g7$|=Xg+ClG!neMn%`>;Vbo|0Rb$nu;J3ceNbv!b^cbsssV|PNY84`bQ`m^P9 zPYQ;3)h~u$2YfO-8U1W{HavcSqr0m=bb?DR=x*canBcPE=$LX$p{5^knN#!(hNtP# zVPaH9obJIrE@f)^1HRA$I%i2s1?X9x@XVf_%46rxh-a7yrPo&u&#H&@2SlfNH5my9Yda{iFI{bAZ|cQ_eZS@ORO34ltbB zCfiqKRAV|QpSHZ_EU^;!JaIgX=G!81@$)b-e=Ga^SI0B! zr;f{e^ze3MKKvQ*SI4zqlN(Rv^9Om7c742#xR0aihupj%Tj(gu=CnyX6#2)hDAL z?VBv82iZ6dcK(=!2`7{|94BJWP$Mx^4I*As!N* z%q4&D`im!?LU^&2yomn%8bYwf_$Hrd2!Z=1r{}~!O+KIe zm_;7+c+x1^yAFRG+;=#p9__adw+G)l905lAPlqoDhf)!GY_ga3>wvp1pQ63*^2dNb zBY$`86UXv&;#8R;ufX>%Ujv!v(@7~)nr-9^|v*5QfIEYmwc(Y%Ap3| z2lk%<5BGc>a5vyOhv#a3Z)HE?wzAhXpx&Qd`OmfC+CN<*YX6$o@#!<;|w;( z#;0-GKHz{V?hAg@rmSO-gm8HZ%W`IXqJ(OW1ya1IQLM^}7d0x(1?Lz-O1_pH+S0$P zc&bfV$5%Ynrp(J4#Cs<*KFb;s5TN8`jQ~@ex|rUYr-c@TX*a2Rm~d%~yk; zISgiNe&s0GT=Odj!Iqj|IZ`sVxg#R}O2w=L?taCWasYe=$noa^w-s08TXWC#`Jk?z zU%I=b54}G6{6%|_gPe)9aIX6HJ5Gwb<*2$he531+WvESgb8ok}!IJ*~*Q#r* literal 0 HcmV?d00001 diff --git a/data/collider/penguin_8.col b/data/collider/penguin_8.col new file mode 100755 index 0000000000000000000000000000000000000000..d3cb6894beaba95377bfaabe648614f653caf9dd GIT binary patch literal 2600 zcmd6pQEtN^42G%t(8pe25=Y5BrrjkRXUE7WD`qz3YTv14pP zIRt5M=-%=B#P36-dd)eXLddxaWsvh3D(NGZ&&*O|v)GXwM~pOW!P%)!eOQ{$2|oV| zi#`@JhYds2C5>T^oxRU+uXcM31?%$?Zq;tfu9Y1(c9*BvVPm&eJ0KU!vcr;Rv(}f~ zkS}e}C&TWlQx82FcH3cB$9Ub6E%b|HC*yN<>}c5H*uk*mSj~;qX^iPHyGtw`#`Kt7 zhfKc9%a9$}ZXGhI(=uX{ury*=h>-KpXB0M$Q`mTZ5-0iXCeC@0`4zTUt~o2r)oWI<|3^GvW*%*SDLxyEE;qQPIH}<{RCBYyP*l0f z2?`n}Zgm=G6pG&iqYW!{q9;6?$u@sMZ)XC1Ch~yl-TvE^(YYbu5QQ|(s%cMa1`RAl H8Orq=IPqAI literal 0 HcmV?d00001 diff --git a/data/collider/penguin_9.col b/data/collider/penguin_9.col new file mode 100755 index 0000000000000000000000000000000000000000..91e8762c513c7ad2f620d9c9fed8fb2543925a36 GIT binary patch literal 2348 zcmbW2!EM7Z3`G_Aklu3bp@0@CkRduk*C-&5(=j}XN64)?1Y!RtEsK(E9YP?A%;zsr z5=Eba*$4i<@%zQ^%Us$%PVS-Uim`j+*2kpnD0?ib^S;Y2%4C-fWaB>5Q09FmXXx$+ zj59rt*oD*W#v+o!bjV~tCX8Hna?wC5Ktwa+o~ zilIPc&4$Gn*|nof%6RqEs#uKi${Ist>$w|q_n~EpWninr2&gS{hmFVV3ay#XLEaj{ z>){)+pZ~s|<1y0b4P%ZR z7rx~E?8ALqSc}&6Z-D8Z9i3Z;olzcxVNgfg)-=c5{hVw*6H&L+yS?u%J|CJB{HU&i rrIYIj-)LFlxbg>osk!-`s2!d+Z$NE!0VeowsU{&XXJBAsw63-Pxq0a$ literal 0 HcmV?d00001 diff --git a/data/collider/savepng.c b/data/collider/savepng.c new file mode 100644 index 0000000..6eefbfd --- /dev/null +++ b/data/collider/savepng.c @@ -0,0 +1,155 @@ +/* + * SDL_SavePNG -- libpng-based SDL_Surface writer. + * + * This code is free software, available under zlib/libpng license. + * http://www.libpng.org/pub/png/src/libpng-LICENSE.txt + */ +#include +#include + +#define SUCCESS 0 +#define ERROR -1 + +#define USE_ROW_POINTERS + +#if SDL_BYTEORDER == SDL_BIG_ENDIAN +#define rmask 0xFF000000 +#define gmask 0x00FF0000 +#define bmask 0x0000FF00 +#define amask 0x000000FF +#else +#define rmask 0x000000FF +#define gmask 0x0000FF00 +#define bmask 0x00FF0000 +#define amask 0xFF000000 +#endif + +/* libpng callbacks */ +static void png_error_SDL(png_structp ctx, png_const_charp str) +{ + SDL_SetError("libpng: %s\n", str); +} +static void png_write_SDL(png_structp png_ptr, png_bytep data, png_size_t length) +{ + SDL_RWops *rw = (SDL_RWops*)png_get_io_ptr(png_ptr); + SDL_RWwrite(rw, data, sizeof(png_byte), length); +} + +SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src) +{ + SDL_Surface *surf; + SDL_Rect rect = { 0 }; + + /* NO-OP for images < 32bpp and 32bpp images that already have Alpha channel */ + if (src->format->BitsPerPixel <= 24 || src->format->Amask) { + src->refcount++; + return src; + } + + /* Convert 32bpp alpha-less image to 24bpp alpha-less image */ + rect.w = src->w; + rect.h = src->h; + surf = SDL_CreateRGBSurface(src->flags, src->w, src->h, 24, + src->format->Rmask, src->format->Gmask, src->format->Bmask, 0); + SDL_LowerBlit(src, &rect, surf, &rect); + + return surf; +} + +int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst) +{ + png_structp png_ptr; + png_infop info_ptr; + png_colorp pal_ptr; + SDL_Palette *pal; + int i, colortype; +#ifdef USE_ROW_POINTERS + png_bytep *row_pointers; +#endif + /* Initialize and do basic error checking */ + if (!dst) + { + SDL_SetError("Argument 2 to SDL_SavePNG_RW can't be NULL, expecting SDL_RWops*\n"); + return (ERROR); + } + if (!surface) + { + SDL_SetError("Argument 1 to SDL_SavePNG_RW can't be NULL, expecting SDL_Surface*\n"); + if (freedst) SDL_RWclose(dst); + return (ERROR); + } + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_SDL, NULL); /* err_ptr, err_fn, warn_fn */ + if (!png_ptr) + { + SDL_SetError("Unable to png_create_write_struct on %s\n", PNG_LIBPNG_VER_STRING); + if (freedst) SDL_RWclose(dst); + return (ERROR); + } + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + SDL_SetError("Unable to png_create_info_struct\n"); + png_destroy_write_struct(&png_ptr, NULL); + if (freedst) SDL_RWclose(dst); + return (ERROR); + } + if (setjmp(png_jmpbuf(png_ptr))) /* All other errors, see also "png_error_SDL" */ + { + png_destroy_write_struct(&png_ptr, &info_ptr); + if (freedst) SDL_RWclose(dst); + return (ERROR); + } + + /* Setup our RWops writer */ + png_set_write_fn(png_ptr, dst, png_write_SDL, NULL); /* w_ptr, write_fn, flush_fn */ + + /* Prepare chunks */ + colortype = PNG_COLOR_MASK_COLOR; + if (surface->format->BytesPerPixel > 0 + && surface->format->BytesPerPixel <= 8 + && (pal = surface->format->palette)) + { + colortype |= PNG_COLOR_MASK_PALETTE; + pal_ptr = (png_colorp)malloc(pal->ncolors * sizeof(png_color)); + for (i = 0; i < pal->ncolors; i++) { + pal_ptr[i].red = pal->colors[i].r; + pal_ptr[i].green = pal->colors[i].g; + pal_ptr[i].blue = pal->colors[i].b; + } + png_set_PLTE(png_ptr, info_ptr, pal_ptr, pal->ncolors); + free(pal_ptr); + } + else if (surface->format->BytesPerPixel > 3 || surface->format->Amask) + colortype |= PNG_COLOR_MASK_ALPHA; + + png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8, colortype, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + +// png_set_packing(png_ptr); + + /* Allow BGR surfaces */ + if (surface->format->Rmask == bmask + && surface->format->Gmask == gmask + && surface->format->Bmask == rmask) + png_set_bgr(png_ptr); + + /* Write everything */ + png_write_info(png_ptr, info_ptr); +#ifdef USE_ROW_POINTERS + row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*surface->h); + for (i = 0; i < surface->h; i++) + row_pointers[i] = (png_bytep)(Uint8*)surface->pixels + i * surface->pitch; + png_write_image(png_ptr, row_pointers); + free(row_pointers); +#else + for (i = 0; i < surface->h; i++) + png_write_row(png_ptr, (png_bytep)(Uint8*)surface->pixels + i * surface->pitch); +#endif + png_write_end(png_ptr, info_ptr); + + /* Done */ + png_destroy_write_struct(&png_ptr, &info_ptr); + if (freedst) SDL_RWclose(dst); + return (SUCCESS); +} + diff --git a/data/collider/savepng.h b/data/collider/savepng.h new file mode 100644 index 0000000..5fb9256 --- /dev/null +++ b/data/collider/savepng.h @@ -0,0 +1,46 @@ +#ifndef _SDL_SAVEPNG +#define _SDL_SAVEPNG +/* + * SDL_SavePNG -- libpng-based SDL_Surface writer. + * + * This code is free software, available under zlib/libpng license. + * http://www.libpng.org/pub/png/src/libpng-LICENSE.txt + */ +#include + +#ifdef __cplusplus +extern "C" { /* This helps CPP projects that include this header */ +#endif + +/* + * Save an SDL_Surface as a PNG file. + * + * Returns 0 success or -1 on failure, the error message is then retrievable + * via SDL_GetError(). + */ +#define SDL_SavePNG(surface, file) \ + SDL_SavePNG_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/* + * Save an SDL_Surface as a PNG file, using writable RWops. + * + * surface - the SDL_Surface structure containing the image to be saved + * dst - a data stream to save to + * freedst - non-zero to close the stream after being written + * + * Returns 0 success or -1 on failure, the error message is then retrievable + * via SDL_GetError(). + */ +extern int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *rw, int freedst); + +/* + * Return new SDL_Surface with a format suitable for PNG output. + */ +extern SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +