Commit 332ca3ba authored by Jason Clinton's avatar Jason Clinton

Added an actor to render a whole slot instead of trying to create

separate actors for each visible card in the slot. For now this breaks
animations and highlights.

svn path=/trunk/; revision=8159
parent be16138b
......@@ -29,6 +29,8 @@ sol_SOURCES = \
conf.h \
game.c \
game.h \
slot-renderer.c \
slot-renderer.h \
sol.c \
stats-dialog.c \
stats-dialog.h \
......
......@@ -43,6 +43,7 @@
#include "baize.h"
#include "card-cache.h"
#include "card.h"
#include "slot-renderer.h"
#define AISLERIOT_BOARD_GET_PRIVATE(board)(G_TYPE_INSTANCE_GET_PRIVATE ((board), AISLERIOT_TYPE_BOARD, AisleriotBoardPrivate))
......@@ -831,23 +832,6 @@ slot_update_geometry (AisleriotBoard *board,
slot->needs_update = FALSE;
}
static void
truncate_card_images_array (GPtrArray *card_images, guint size)
{
guint i;
for (i = size; i < card_images->len; i++) {
ClutterActor *actor = g_ptr_array_index (card_images, i);
if (actor) {
clutter_actor_destroy (actor);
g_object_unref (actor);
}
}
g_ptr_array_set_size (card_images, size);
}
static void
destroy_animation_data (ClutterActor *actor, AnimationData *data)
{
......@@ -922,6 +906,7 @@ add_animation (AisleriotBoard *board,
static void
check_animations (AisleriotBoard *board)
{
#if 0
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *slots;
int slot_num, i;
......@@ -1021,6 +1006,7 @@ check_animations (AisleriotBoard *board)
}
g_array_free (removed_cards, TRUE);
#endif
}
static void
......@@ -1029,79 +1015,24 @@ slot_update_card_images_full (AisleriotBoard *board,
int highlight_start_card_id)
{
AisleriotBoardPrivate *priv = board->priv;
GPtrArray *card_images;
guint n_cards, first_exposed_card_id, i;
guint8 *cards;
int cardx, cardy;
ClutterActor *stage
= gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (board));
card_images = slot->card_images;
truncate_card_images_array (card_images, 0);
if (!priv->geometry_set)
return;
cards = slot->cards->data;
n_cards = slot->cards->len;
g_assert (n_cards >= slot->exposed);
first_exposed_card_id = n_cards - slot->exposed;
/* No need to get invisible cards from cache, which will just
* slow us down!
*/
for (i = 0; i < first_exposed_card_id; ++i) {
g_ptr_array_add (card_images, NULL);
}
cardx = slot->rect.x;
cardy = slot->rect.y;
if (slot->slot_texture) {
clutter_actor_destroy (slot->slot_texture);
g_object_unref (slot->slot_texture);
slot->slot_texture = NULL;
}
if (slot->cards->len == 0) {
CoglHandle cogl_tex;
gboolean show_highlight;
slot->slot_texture = g_object_ref_sink (clutter_texture_new ());
show_highlight = priv->show_highlight && slot == priv->highlight_slot;
cogl_tex = aisleriot_card_cache_get_slot_texture (priv->textures,
show_highlight);
clutter_texture_set_cogl_texture (CLUTTER_TEXTURE (slot->slot_texture),
cogl_tex);
if (slot->slot_renderer == NULL) {
slot->slot_renderer = aisleriot_slot_renderer_new (priv->textures, slot);
g_object_ref_sink (slot->slot_renderer);
clutter_actor_set_position (slot->slot_texture, cardx, cardy);
clutter_actor_set_position (slot->slot_renderer,
slot->rect.x, slot->rect.y);
clutter_container_add (CLUTTER_CONTAINER (stage), slot->slot_texture, NULL);
clutter_container_add (CLUTTER_CONTAINER (stage),
slot->slot_renderer, NULL);
}
for (i = first_exposed_card_id; i < n_cards; ++i) {
Card card = CARD (cards[i]);
gboolean is_highlighted;
ClutterActor *card_tex = aisleriot_card_new (priv->textures, card);
is_highlighted = (i >= highlight_start_card_id);
aisleriot_card_set_highlighted (AISLERIOT_CARD (card_tex),
is_highlighted);
clutter_actor_set_position (card_tex, cardx, cardy);
clutter_container_add (CLUTTER_CONTAINER (stage), card_tex, NULL);
g_ptr_array_add (card_images, g_object_ref_sink (card_tex));
cardx += slot->pixeldx;
cardy += slot->pixeldy;
}
clutter_actor_queue_redraw (slot->slot_renderer);
}
static void
......@@ -1258,8 +1189,6 @@ drag_begin (AisleriotBoard *board)
/* Take the cards off of the stack */
g_byte_array_set_size (cards, priv->moving_cards_origin_card_id);
truncate_card_images_array (hslot->card_images,
priv->moving_cards_origin_card_id);
width = priv->card_size.width + (num_moving_cards - 1) * hslot->pixeldx;
height = priv->card_size.height + (num_moving_cards - 1) * hslot->pixeldy;
......
......@@ -232,28 +232,19 @@ static void
clear_slots (AisleriotGame *game,
gboolean notify)
{
guint i, n_slots, card_num;
guint i, n_slots;
n_slots = game->slots->len;
for (i = 0; i < n_slots; ++i) {
Slot *slot = game->slots->pdata[i];
for (card_num = 0; card_num < slot->card_images->len; card_num++) {
ClutterActor *actor = g_ptr_array_index (slot->card_images, card_num);
if (actor) {
clutter_actor_destroy (actor);
g_object_unref (actor);
}
}
if (slot->slot_texture) {
clutter_actor_destroy (slot->slot_texture);
g_object_unref (slot->slot_texture);
if (slot->slot_renderer) {
clutter_actor_destroy (slot->slot_renderer);
g_object_unref (slot->slot_renderer);
}
g_byte_array_free (slot->cards, TRUE);
g_byte_array_free (slot->old_cards, TRUE);
g_ptr_array_free (slot->card_images, TRUE);
g_slice_free (Slot, slot);
}
......@@ -599,8 +590,6 @@ cscmi_add_slot (SCM slot_data)
slot->expanded_down = expanded_down != FALSE;
slot->expanded_right = expanded_right != FALSE;
slot->card_images = g_ptr_array_sized_new (SLOT_CARDS_N_PREALLOC);
slot->needs_update = TRUE;
/* this will update the slot length too */
......
......@@ -57,10 +57,8 @@ typedef struct {
/* The location in pixel units. Filled in by the scaling code. */
GdkRectangle rect;
/* ClutterActor *, reference owned */
GPtrArray *card_images;
/* Actor for the slot */
ClutterActor *slot_texture;
ClutterActor *slot_renderer;
guint expanded_right : 1;
guint expanded_down : 1;
......
/*
* Copyright © 2008 Neil Roberts
*
* 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 <config.h>
#include <clutter/clutter-actor.h>
#include <gtk/gtk.h>
#include <cogl/cogl.h>
#include "slot-renderer.h"
static void aisleriot_slot_renderer_dispose (GObject *object);
static void aisleriot_slot_renderer_finalize (GObject *object);
static void aisleriot_slot_renderer_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void aisleriot_slot_renderer_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void aisleriot_slot_renderer_paint (ClutterActor *actor);
static void aisleriot_slot_renderer_set_cache (AisleriotSlotRenderer *srend,
AisleriotCardCache *cache);
G_DEFINE_TYPE (AisleriotSlotRenderer, aisleriot_slot_renderer,
CLUTTER_TYPE_ACTOR);
#define AISLERIOT_SLOT_RENDERER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), AISLERIOT_TYPE_SLOT_RENDERER, \
AisleriotSlotRendererPrivate))
struct _AisleriotSlotRendererPrivate
{
AisleriotCardCache *cache;
Slot *slot;
gboolean show_highlight;
guint highlight_start_card_id;
};
enum
{
PROP_0,
PROP_CACHE,
PROP_SLOT
};
static void
aisleriot_slot_renderer_class_init (AisleriotSlotRendererClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *) klass;
ClutterActorClass *actor_class = (ClutterActorClass *) klass;
GParamSpec *pspec;
gobject_class->dispose = aisleriot_slot_renderer_dispose;
gobject_class->finalize = aisleriot_slot_renderer_finalize;
gobject_class->set_property = aisleriot_slot_renderer_set_property;
gobject_class->get_property = aisleriot_slot_renderer_get_property;
actor_class->paint = aisleriot_slot_renderer_paint;
pspec = g_param_spec_object ("cache", NULL, NULL,
AISLERIOT_TYPE_CARD_CACHE,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB);
g_object_class_install_property (gobject_class, PROP_CACHE, pspec);
pspec = g_param_spec_pointer ("slot", NULL, NULL,
G_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB);
g_object_class_install_property (gobject_class, PROP_SLOT, pspec);
g_type_class_add_private (klass, sizeof (AisleriotSlotRendererPrivate));
}
static void
aisleriot_slot_renderer_init (AisleriotSlotRenderer *self)
{
AisleriotSlotRendererPrivate *priv;
priv = self->priv = AISLERIOT_SLOT_RENDERER_GET_PRIVATE (self);
priv->highlight_start_card_id = G_MAXUINT;
}
static void
aisleriot_slot_renderer_dispose (GObject *object)
{
AisleriotSlotRenderer *self = (AisleriotSlotRenderer *) object;
aisleriot_slot_renderer_set_cache (self, NULL);
G_OBJECT_CLASS (aisleriot_slot_renderer_parent_class)->dispose (object);
}
static void
aisleriot_slot_renderer_finalize (GObject *object)
{
AisleriotSlotRenderer *self = (AisleriotSlotRenderer *) object;
G_OBJECT_CLASS (aisleriot_slot_renderer_parent_class)->finalize (object);
}
ClutterActor *
aisleriot_slot_renderer_new (AisleriotCardCache *cache, Slot *slot)
{
ClutterActor *self = g_object_new (AISLERIOT_TYPE_SLOT_RENDERER,
"cache", cache,
"slot", slot,
NULL);
return self;
}
static void
aisleriot_slot_renderer_set_cache (AisleriotSlotRenderer *srend,
AisleriotCardCache *cache)
{
AisleriotSlotRendererPrivate *priv = srend->priv;
if (cache)
g_object_ref (cache);
if (priv->cache)
g_object_unref (priv->cache);
priv->cache = cache;
}
static void
aisleriot_slot_renderer_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
AisleriotSlotRenderer *srend = AISLERIOT_SLOT_RENDERER (object);
AisleriotSlotRendererPrivate *priv = srend->priv;
switch (property_id) {
case PROP_CACHE:
aisleriot_slot_renderer_set_cache (srend, g_value_get_object (value));
break;
case PROP_SLOT:
priv->slot = g_value_get_pointer (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
aisleriot_slot_renderer_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
/* All properties are write-only */
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
aisleriot_slot_renderer_paint (ClutterActor *actor)
{
AisleriotSlotRenderer *srend = (AisleriotSlotRenderer *) actor;
AisleriotSlotRendererPrivate *priv = srend->priv;
guint n_cards, first_exposed_card_id, i;
guint8 *cards;
int cardx, cardy;
g_return_if_fail (priv->cache != NULL);
g_return_if_fail (priv->slot != NULL);
cards = priv->slot->cards->data;
n_cards = priv->slot->cards->len;
g_assert (n_cards >= priv->slot->exposed);
first_exposed_card_id = n_cards - priv->slot->exposed;
if (priv->slot->cards->len == 0) {
CoglHandle cogl_tex;
guint tex_width, tex_height;
cogl_tex = aisleriot_card_cache_get_slot_texture (priv->cache,
priv->show_highlight);
tex_width = cogl_texture_get_width (cogl_tex);
tex_height = cogl_texture_get_height (cogl_tex);
cogl_texture_rectangle (cogl_tex,
0, 0,
CLUTTER_INT_TO_FIXED (tex_width),
CLUTTER_INT_TO_FIXED (tex_height),
0, 0, CFX_ONE, CFX_ONE);
}
cardx = 0;
cardy = 0;
for (i = first_exposed_card_id; i < n_cards; ++i) {
Card card = CARD (cards[i]);
gboolean is_highlighted;
CoglHandle cogl_tex;
guint tex_width, tex_height;
is_highlighted = (i >= priv->highlight_start_card_id);
cogl_tex = aisleriot_card_cache_get_card_texture (priv->cache,
card,
is_highlighted);
tex_width = cogl_texture_get_width (cogl_tex);
tex_height = cogl_texture_get_height (cogl_tex);
cogl_texture_rectangle (cogl_tex,
CLUTTER_INT_TO_FIXED (cardx),
CLUTTER_INT_TO_FIXED (cardy),
CLUTTER_INT_TO_FIXED (cardx + tex_width),
CLUTTER_INT_TO_FIXED (cardy + tex_height),
0, 0, CFX_ONE, CFX_ONE);
cardx += priv->slot->pixeldx;
cardy += priv->slot->pixeldy;
}
}
/*
* Copyright © 2008 Neil Roberts
*
* 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 __AISLERIOT_SLOT_RENDERER_H__
#define __AISLERIOT_SLOT_RENDERER_H__
#include <clutter/clutter-actor.h>
#include <libgames-support/games-card-images.h>
#include "card-cache.h"
#include "game.h"
G_BEGIN_DECLS
#define AISLERIOT_TYPE_SLOT_RENDERER \
(aisleriot_slot_renderer_get_type())
#define AISLERIOT_SLOT_RENDERER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
AISLERIOT_TYPE_SLOT_RENDERER, \
AisleriotSlotRenderer))
#define AISLERIOT_SLOT_RENDERER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST ((klass), \
AISLERIOT_TYPE_SLOT_RENDERER, \
AisleriotSlotRendererClass))
#define AISLERIOT_IS_SLOT_RENDERER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
AISLERIOT_TYPE_SLOT_RENDERER))
#define AISLERIOT_IS_SLOT_RENDERER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
AISLERIOT_TYPE_SLOT_RENDERER))
#define AISLERIOT_SLOT_RENDERER_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
AISLERIOT_TYPE_SLOT_RENDERER, \
AisleriotSlotRendererClass))
typedef struct _AisleriotSlotRenderer AisleriotSlotRenderer;
typedef struct _AisleriotSlotRendererClass AisleriotSlotRendererClass;
typedef struct _AisleriotSlotRendererPrivate AisleriotSlotRendererPrivate;
struct _AisleriotSlotRendererClass
{
ClutterActorClass parent_class;
};
struct _AisleriotSlotRenderer
{
ClutterActor parent;
AisleriotSlotRendererPrivate *priv;
};
GType aisleriot_slot_renderer_get_type (void) G_GNUC_CONST;
ClutterActor *aisleriot_slot_renderer_new (AisleriotCardCache *cache,
Slot *slot);
G_END_DECLS
#endif /* __AISLERIOT_SLOT_RENDERER_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment