From 382dbfee37ec3d92294c94e9d6be82af4a8f7738 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 16 Oct 2011 13:56:59 -0700 Subject: resource: Add animation resources --- libgame/Makefile.am | 2 + libgame/game-animation-resource.c | 246 ++++++++++++++++++++++++++++++++++++++ libgame/game-animation-resource.h | 61 ++++++++++ libgame/game-animation.c | 22 ++++ libgame/game-animation.h | 2 + libgame/libgame.h | 1 + 6 files changed, 334 insertions(+) create mode 100644 libgame/game-animation-resource.c create mode 100644 libgame/game-animation-resource.h diff --git a/libgame/Makefile.am b/libgame/Makefile.am index 81ccf42..9de7c12 100644 --- a/libgame/Makefile.am +++ b/libgame/Makefile.am @@ -18,6 +18,7 @@ EXTRA_libgame_@LIBGAME_VERS@_la_SOURCES = \ libgame_@LIBGAME_VERS@_la_SOURCES = \ game-actor.c \ game-animation.c \ + game-animation-resource.c \ game-board.c \ game-colored.c \ game-container.c \ @@ -58,6 +59,7 @@ libgame_@LIBGAME_VERS@_la_SOURCES = \ basic_headers = \ game-actor.h \ game-animation.h \ + game-animation-resource.h \ game-board.h \ game-colored.h \ game-container.h \ diff --git a/libgame/game-animation-resource.c b/libgame/game-animation-resource.c new file mode 100644 index 0000000..99f0fe4 --- /dev/null +++ b/libgame/game-animation-resource.c @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2011 Benjamin Otte + * + * This program 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, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "game-private.h" + +#include "game-animation-resource.h" + +#include + +#include "game-animation.h" + + +enum { + PROP_0, + PROP_SIZE +}; + +G_DEFINE_TYPE (GameAnimationResource, game_animation_resource, GAME_TYPE_RESOURCE) + +static const GameRectangle game_animation_resource_default_size = { 0, 0, 1, 1 }; + +static void +game_animation_resource_get_property (GObject *object, guint param_id, GValue *value, + GParamSpec * pspec) +{ + GameAnimationResource *resource = GAME_ANIMATION_RESOURCE (object); + + switch (param_id) { + case PROP_SIZE: + g_value_set_boxed (value, &resource->size); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +game_animation_resource_set_property (GObject *object, guint param_id, const GValue *value, + GParamSpec *pspec) +{ + GameAnimationResource *resource = GAME_ANIMATION_RESOURCE (object); + + switch (param_id) { + case PROP_SIZE: + game_animation_resource_set_size (resource, g_value_get_boxed (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +game_animation_resource_dispose (GObject *object) +{ + GameAnimationResource *resource = GAME_ANIMATION_RESOURCE (object); + + g_ptr_array_set_size (resource->frames, 0); + g_ptr_array_set_size (resource->surfaces, 0); + + G_OBJECT_CLASS (game_animation_resource_parent_class)->dispose (object); +} + +static void +game_animation_resource_finalize (GObject *object) +{ + GameAnimationResource *resource = GAME_ANIMATION_RESOURCE (object); + + g_ptr_array_free (resource->frames, TRUE); + g_ptr_array_free (resource->surfaces, TRUE); + + G_OBJECT_CLASS (game_animation_resource_parent_class)->finalize (object); +} + +static gboolean +game_animation_resource_load (GameResource *res, GVariantIter *iter) +{ + GameAnimationResource *resource = GAME_ANIMATION_RESOURCE (res); + GameDataResource *data; + GVariant *variant; + GVariantIter *array; + + if (!GAME_RESOURCE_CLASS (game_animation_resource_parent_class)->load (res, iter)) + return FALSE; + + if (!g_variant_iter_next (iter, "d", &resource->size.x1) || + !g_variant_iter_next (iter, "d", &resource->size.y1) || + !g_variant_iter_next (iter, "d", &resource->size.x2) || + !g_variant_iter_next (iter, "d", &resource->size.y2) || + !g_variant_iter_next (iter, "av", &array)) + return FALSE; + + resource->size.x2 += resource->size.x1; + resource->size.y2 += resource->size.y1; + + while (g_variant_iter_loop (array, "v", &variant)) + { + data = GAME_DATA_RESOURCE (game_resource_load (GAME_OBJECT (resource)->game, variant)); + game_animation_resource_add_frame (resource, data); + g_object_unref (data); + } + g_variant_iter_free (array); + + return TRUE; +} + +static void +game_animation_resource_save (GameResource *res, GVariantBuilder *builder) +{ + GameAnimationResource *resource = GAME_ANIMATION_RESOURCE (res); + GVariant *variant; + guint i; + + GAME_RESOURCE_CLASS (game_animation_resource_parent_class)->save (res, builder); + + g_variant_builder_add (builder, "dddd", + resource->size.x1, + resource->size.y1, + resource->size.x2 - resource->size.x1, + resource->size.y2 - resource->size.y1); + + g_variant_builder_open (builder, G_VARIANT_TYPE ("av")); + + for (i = 0; i < resource->frames->len; i++) + { + variant = game_resource_save (GAME_RESOURCE (g_ptr_array_index (resource->frames, i))); + + g_variant_builder_add (builder, "v", variant); + + g_variant_unref (variant); + } + + g_variant_builder_close (builder); +} + +static GameObject * +game_animation_resource_spawn (GameResource *res) +{ + GameAnimationResource *resource = GAME_ANIMATION_RESOURCE (res); + + return GAME_OBJECT (game_animation_new_from_resource (resource)); +} + +static void +game_animation_resource_class_init (GameAnimationResourceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GameResourceClass *resource_class = GAME_RESOURCE_CLASS (klass); + + object_class->set_property = game_animation_resource_set_property; + object_class->get_property = game_animation_resource_get_property; + object_class->dispose = game_animation_resource_dispose; + object_class->finalize = game_animation_resource_finalize; + + g_object_class_install_property (object_class, PROP_SIZE, + g_param_spec_boxed ("sizee", _("size"), _("size the animation should be resized to"), + GAME_TYPE_RECTANGLE, G_PARAM_READWRITE)); + + resource_class->load = game_animation_resource_load; + resource_class->save = game_animation_resource_save; + resource_class->spawn = game_animation_resource_spawn; +} + +static void +game_animation_resource_init (GameAnimationResource *resource) +{ + resource->frames = g_ptr_array_new_with_free_func (g_object_unref); + resource->surfaces = g_ptr_array_new_with_free_func ((GDestroyNotify) cairo_surface_destroy); + + resource->size = game_animation_resource_default_size; +} + +cairo_surface_t * +game_animation_resource_load_surface (GameDataResource *data) +{ + GdkPixbufLoader *loader; + cairo_surface_t *surface; + GError *error = NULL; + + loader = gdk_pixbuf_loader_new (); + if (!gdk_pixbuf_loader_write (loader, + game_data_resource_get_data (data), + game_data_resource_get_size (data), + &error) || + !gdk_pixbuf_loader_close (loader, &error)) + { + g_warning ("Could not load animation: %s", error->message); + g_error_free (error); + return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); + } + + surface = game_cairo_surface_from_pixbuf (gdk_pixbuf_loader_get_pixbuf (loader)); + g_object_unref (loader); + + return surface; +} + +const GameRectangle * +game_animation_resource_get_size (GameAnimationResource *resource) +{ + g_return_val_if_fail (GAME_IS_ANIMATION_RESOURCE (resource), NULL); + + return &resource->size; +} + +void +game_animation_resource_set_size (GameAnimationResource *resource, + const GameRectangle * rect) +{ + g_return_if_fail (GAME_IS_ANIMATION_RESOURCE (resource)); + + if (rect == NULL) + rect = &game_animation_resource_default_size; + + resource->size = *rect; + + g_object_notify (G_OBJECT (resource), "size"); +} + +void +game_animation_resource_add_frame (GameAnimationResource *resource, + GameDataResource * data) +{ + g_return_if_fail (GAME_IS_ANIMATION_RESOURCE (resource)); + g_return_if_fail (GAME_IS_DATA_RESOURCE (data)); + + g_ptr_array_add (resource->frames, g_object_ref (data)); + g_ptr_array_add (resource->surfaces, game_animation_resource_load_surface (data)); +} + diff --git a/libgame/game-animation-resource.h b/libgame/game-animation-resource.h new file mode 100644 index 0000000..0264b10 --- /dev/null +++ b/libgame/game-animation-resource.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2011 Benjamin Otte + * + * This program 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, or (at your option) + * any later version. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GAME_ANIMATION_RESOURCE_H__ +#define __GAME_ANIMATION_RESOURCE_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define GAME_TYPE_ANIMATION_RESOURCE (game_animation_resource_get_type ()) +#define GAME_ANIMATION_RESOURCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAME_TYPE_ANIMATION_RESOURCE, GameAnimationResource)) +#define GAME_ANIMATION_RESOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAME_TYPE_ANIMATION_RESOURCE, GameAnimationResourceClass)) +#define GAME_IS_ANIMATION_RESOURCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAME_TYPE_ANIMATION_RESOURCE)) +#define GAME_IS_ANIMATION_RESOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAME_TYPE_ANIMATION_RESOURCE)) +#define GAME_ANIMATION_RESOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GAME_TYPE_ANIMATION_RESOURCE, GameAnimationResourceClass)) + +typedef struct _GameAnimationResource GameAnimationResource; +typedef struct _GameAnimationResourceClass GameAnimationResourceClass; + +struct _GameAnimationResource { + GameResource resource; + + /*< private >*/ + GPtrArray * frames; + GPtrArray * surfaces; + GameRectangle size; +}; + +struct _GameAnimationResourceClass { + GameResourceClass resource_class; +}; + +GType game_animation_resource_get_type (void) G_GNUC_CONST; + +const GameRectangle * game_animation_resource_get_size (GameAnimationResource * resource); +void game_animation_resource_set_size (GameAnimationResource * resource, + const GameRectangle * rect); +void game_animation_resource_add_frame (GameAnimationResource * resource, + GameDataResource * data); + +G_END_DECLS + +#endif /* __GAME_ANIMATION_RESOURCE_H__ */ diff --git a/libgame/game-animation.c b/libgame/game-animation.c index 61c8d2d..a6c47b6 100644 --- a/libgame/game-animation.c +++ b/libgame/game-animation.c @@ -236,3 +236,25 @@ game_animation_new_from_files (GameGame *game, const GameRectangle *size, } return GAME_GRAPHIC (anim); } + +GameGraphic * +game_animation_new_from_resource (GameAnimationResource *resource) +{ + GameAnimation *anim; + const GameRectangle *size; + guint i; + + g_return_val_if_fail (GAME_IS_ANIMATION_RESOURCE (resource), NULL); + + size = &resource->size; + anim = GAME_ANIMATION (game_game_add_object (GAME_OBJECT (resource)->game, + GAME_TYPE_ANIMATION, + "x", size->x1, "width", size->x2 - size->x1, + "y", size->y1, "height", size->y2 - size->y1, NULL)); + + for (i = 0; i < resource->surfaces->len; i++) { + game_animation_add_image (anim, cairo_surface_reference (g_ptr_array_index (resource->surfaces, i))); + } + + return GAME_GRAPHIC (anim); +} diff --git a/libgame/game-animation.h b/libgame/game-animation.h index fc5b8c0..77a8c96 100644 --- a/libgame/game-animation.h +++ b/libgame/game-animation.h @@ -22,6 +22,7 @@ #define __GAME_ANIMATION_H__ #include +#include #include G_BEGIN_DECLS @@ -55,6 +56,7 @@ GameGraphic * game_animation_new_from_files (GameGame * game, const GameRectangle * size, const char * pattern, GError ** error); +GameGraphic * game_animation_new_from_resource(GameAnimationResource *resource); G_END_DECLS diff --git a/libgame/libgame.h b/libgame/libgame.h index 0aa68c2..c5f4c15 100644 --- a/libgame/libgame.h +++ b/libgame/libgame.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include -- cgit v1.2.3