Agrego generador de datos de colisión.

master
Félix Arreola Rodríguez 2018-06-03 17:38:38 -05:00
parent 9a932762e9
commit 4149eb480b
19 changed files with 955 additions and 0 deletions

View File

@ -120,6 +120,7 @@ AC_CONFIG_FILES([ po/Makefile.in
data/Makefile
etc/Makefile
etc/Info.plist
data/collider/Makefile
])
AC_OUTPUT

View File

@ -77,3 +77,5 @@ EXTRA_DIST = \
desktop/128x128/coffee_bag.png \
desktop/256x256/coffee_bag.png \
coffee_bag.ico
SUBDIRS = collider

View File

@ -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

View File

@ -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 <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <SDL.h>
#include <SDL_image.h>
#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;
}

View File

@ -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 <stdlib.h>
#include <stdio.h>
#include <SDL.h>
#include <SDL_image.h>
#include <sys/types.h>
#include <unistd.h>
#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;
}

View File

@ -0,0 +1 @@
../../src/gfx_blit_func.c

View File

@ -0,0 +1 @@
../../src/gfx_blit_func.h

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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 <SDL.h>
#include <png.h>
#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);
}

View File

@ -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 <SDL_video.h>
#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