summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2011-10-16 13:56:59 -0700
committerBenjamin Otte <otte@redhat.com>2011-10-16 22:32:55 -0700
commit382dbfee37ec3d92294c94e9d6be82af4a8f7738 (patch)
tree31a65645b8ce2a73396a94aac844137aaa3a3ebf
parente5444cd401bfe8489fb579d7d4b2e698472ce782 (diff)
resource: Add animation resources
-rw-r--r--libgame/Makefile.am2
-rw-r--r--libgame/game-animation-resource.c246
-rw-r--r--libgame/game-animation-resource.h61
-rw-r--r--libgame/game-animation.c22
-rw-r--r--libgame/game-animation.h2
-rw-r--r--libgame/libgame.h1
6 files changed, 334 insertions, 0 deletions
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 <otte@gnome.org>
+ *
+ * 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 <cairo-gobject.h>
+
+#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 <otte@gnome.org>
+ *
+ * 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 <cairo.h>
+#include <libgame/game-data-resource.h>
+#include <libgame/game-geom-basics.h>
+
+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 <libgame/game-image.h>
+#include <libgame/game-animation-resource.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
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 <libgame/game-actor.h>
#include <libgame/game-animation.h>
+#include <libgame/game-animation-resource.h>
#include <libgame/game-board.h>
#include <libgame/game-colored.h>
#include <libgame/game-container.h>