gnome-games r8649 - trunk/gnometris



Author: jclinton
Date: Tue Feb  3 18:56:05 2009
New Revision: 8649
URL: http://svn.gnome.org/viewvc/gnome-games?rev=8649&view=rev

Log:
Implement a Clutter tile cache in Renderer

This commit implements a tile cache using CLUTTER_CAIRO as the source
surface. The game field uses a CLUTTER_CLONE_TEXTURE to set the cairo
surface as its parent. Resize or theme change events automatically
destroy the cache and recreate it using the new level of precision.
Additionally, theme changes completely destroy the renderer object and
recreate it.

I intentionally did not reuse the code in use for Aisleriot as I have no
idea what its doing and this seems incredibly simple by comparison

Also, this commit fixes a few whitespace things and moves NCOLOURS to
blocks.h so that it is more globally accessible.

Modified:
   trunk/gnometris/blockops-noclutter.cpp
   trunk/gnometris/blockops.cpp
   trunk/gnometris/blocks.h
   trunk/gnometris/field.cpp
   trunk/gnometris/field.h
   trunk/gnometris/renderer-noclutter.h
   trunk/gnometris/renderer.cpp
   trunk/gnometris/renderer.h
   trunk/gnometris/tetris.cpp

Modified: trunk/gnometris/blockops-noclutter.cpp
==============================================================================
--- trunk/gnometris/blockops-noclutter.cpp	(original)
+++ trunk/gnometris/blockops-noclutter.cpp	Tue Feb  3 18:56:05 2009
@@ -23,11 +23,6 @@
 #include "blockops-noclutter.h"
 #include "blocks.h"
 
-// #include "field-noclutter.h"
-
-#define NCOLOURS 7
-
-
 BlockOps::BlockOps() :
 	useTarget (false),
 	blocknr (0),

Modified: trunk/gnometris/blockops.cpp
==============================================================================
--- trunk/gnometris/blockops.cpp	(original)
+++ trunk/gnometris/blockops.cpp	Tue Feb  3 18:56:05 2009
@@ -23,11 +23,6 @@
 #include "blockops.h"
 #include "blocks.h"
 
-// #include "field.h"
-
-#define NCOLOURS 7
-
-
 BlockOps::BlockOps() :
 	blocknr (0),
 	rot (0),

Modified: trunk/gnometris/blocks.h
==============================================================================
--- trunk/gnometris/blocks.h	(original)
+++ trunk/gnometris/blocks.h	Tue Feb  3 18:56:05 2009
@@ -22,6 +22,8 @@
  * For more details see the file COPYING.
  */
 
+#define NCOLOURS 7
+
 extern int blockTable[][4][4][4];
 extern int tableSize;
 

Modified: trunk/gnometris/field.cpp
==============================================================================
--- trunk/gnometris/field.cpp	(original)
+++ trunk/gnometris/field.cpp	Tue Feb  3 18:56:05 2009
@@ -42,7 +42,6 @@
 {
 	themeID = 0;
 	renderer = NULL;
-	rendererTheme = -1;
 
 	w = games_clutter_embed_new();
 
@@ -65,20 +64,31 @@
 void
 Field::rescaleField ()
 {
+	// don't waste our time if GTK+ is just going through allocation
+	if (w->allocation.width < 5 or w->allocation.height < 5)
+		return;
+
 	ClutterActor *stage;
+	stage = games_clutter_embed_get_stage (GAMES_CLUTTER_EMBED (w));
+	width = w->allocation.width;
+	height = w->allocation.height;
+	cell_width = width/COLUMNS;
+	cell_height = height/LINES;
+
 	cairo_t *bg_cr;
 
+	if (renderer)
+		renderer->rescaleCache (cell_width, cell_height);
+	else {
+		renderer = rendererFactory (themeID, cell_width, cell_height);
+	}
+
 	if (background) {
-		clutter_actor_set_size (CLUTTER_ACTOR(background),
-					w->allocation.width,
-					w->allocation.height);
+		clutter_actor_set_size (CLUTTER_ACTOR(background), width, height);
 		clutter_cairo_surface_resize (CLUTTER_CAIRO(background),
-					      w->allocation.width,
-					      w->allocation.height);
+					      width, height);
 	} else {
-		background = clutter_cairo_new (w->allocation.width,
-						w->allocation.height);
-		stage = games_clutter_embed_get_stage (GAMES_CLUTTER_EMBED (w));
+		background = clutter_cairo_new (width, height);
 		/*FIXMEjclinton: eventually allow solid color background
 		 * for software rendering case */
 		ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff };
@@ -92,15 +102,11 @@
 
 	if (foreground) {
 		clutter_actor_set_size (CLUTTER_ACTOR(foreground),
-					w->allocation.width,
-					w->allocation.height);
+					width, height);
 		clutter_cairo_surface_resize (CLUTTER_CAIRO(foreground),
-					      w->allocation.width,
-					      w->allocation.height);
+					      width, height);
 	} else {
-		foreground = clutter_cairo_new (w->allocation.width,
-						w->allocation.height);
-		stage = games_clutter_embed_get_stage (GAMES_CLUTTER_EMBED (w));
+		foreground = clutter_cairo_new (width, height);
 		clutter_group_add (CLUTTER_GROUP (stage),
 				   foreground);
 		clutter_actor_set_position (CLUTTER_ACTOR(foreground),
@@ -121,8 +127,8 @@
 
 		/* FIXME: This doesn't handle tiled backgrounds in the obvious way. */
 		gdk_cairo_set_source_pixbuf (bg_cr, backgroundImage, 0, 0);
-		xscale = 1.0*gdk_pixbuf_get_width (backgroundImage)/w->allocation.width;
-		yscale = 1.0*gdk_pixbuf_get_height (backgroundImage)/w->allocation.height;
+		xscale = 1.0*gdk_pixbuf_get_width (backgroundImage)/width;
+		yscale = 1.0*gdk_pixbuf_get_height (backgroundImage)/height;
 		cairo_matrix_init_scale (&m, xscale, yscale);
 		cairo_pattern_set_matrix (cairo_get_source (bg_cr), &m);
 	} else if (backgroundColor)
@@ -132,16 +138,13 @@
 
 	cairo_paint (bg_cr);
 	cairo_destroy (bg_cr);
-	this->drawMessage ();
-	renderer->rescaleCache ();
+	drawMessage ();
+	clutter_actor_show_all (stage);
 }
 
 gboolean
 Field::configure(GtkWidget *widget, GdkEventConfigure *event, Field *field)
 {
-	field->width = widget->allocation.width;
-	field->height = widget->allocation.height;
-
 	field->rescaleField ();
 	return TRUE;
 }
@@ -260,5 +263,17 @@
 void
 Field::setTheme (gint id)
 {
+	// don't waste time if theme is the same (like from initOptions)
+	if (themeID == id)
+		return;
+
 	themeID = id;
+	if (renderer) {
+		delete renderer;
+		renderer = rendererFactory (themeID, cell_width,
+					    cell_height);
+	} else {
+		renderer = rendererFactory (themeID, cell_width,
+					    cell_height);
+	}
 }

Modified: trunk/gnometris/field.h
==============================================================================
--- trunk/gnometris/field.h	(original)
+++ trunk/gnometris/field.h	Tue Feb  3 18:56:05 2009
@@ -26,12 +26,13 @@
 #include "blockops.h"
 #include "renderer.h"
 
+
 class Field:public BlockOps {
 public:
 	Field ();
 	~Field ();
 
-	void setBackground (GdkPixbuf * bgImage);	//, bool tiled); fixme: move tiling here.
+	void setBackground (GdkPixbuf * bgImage); //, bool tiled); fixme: move tiling here.
 	void setBackground (GdkColor * bgColor);
 	void placeBlock (int x, int y, int bcolor, bool remove);
 	void showPauseMessage ();
@@ -47,8 +48,10 @@
 private:
 	GtkWidget * w;
 
-	int width;
-	int height;
+	guint width;
+	guint height;
+	guint cell_width;
+	guint cell_height;
 
 	ClutterActor *background;
 	ClutterActor *foreground;
@@ -57,7 +60,6 @@
 	bool showPause;
 	bool showGameOver;
 	Renderer *renderer;
-	gint rendererTheme;
 
 	GdkPixbuf *backgroundImage;
 	bool backgroundImageTiled;

Modified: trunk/gnometris/renderer-noclutter.h
==============================================================================
--- trunk/gnometris/renderer-noclutter.h	(original)
+++ trunk/gnometris/renderer-noclutter.h	Tue Feb  3 18:56:05 2009
@@ -27,6 +27,7 @@
 #include <cairo.h>
 #include <glib.h>
 
+#include "blocks.h"
 #include "blockops.h"
 
 struct ThemeTableEntry {

Modified: trunk/gnometris/renderer.cpp
==============================================================================
--- trunk/gnometris/renderer.cpp	(original)
+++ trunk/gnometris/renderer.cpp	Tue Feb  3 18:56:05 2009
@@ -53,18 +53,16 @@
 	return 0;
 }
 
-Renderer * rendererFactory (gint id, ClutterActor *dst,
-			    Block **src, int w,
-			    int h, int pxw, int pxh)
+Renderer * rendererFactory (gint id, gint pxw, gint pxh)
 {
 	switch (id) {
 	case 2:
-		return new TangoBlock (dst, src, w, h, pxw, pxh, TRUE);
+		return new TangoBlock (pxw, pxh, TRUE);
 	case 1:
-		return new TangoBlock (dst, src, w, h, pxw, pxh, FALSE);
+		return new TangoBlock (pxw, pxh, FALSE);
 	case 0:
 	default:
-		return new Renderer (dst, src, w, h, pxw, pxh);
+		return new Renderer (pxw, pxh);
 	}
 }
 
@@ -82,23 +80,61 @@
    for the preview widget and possibly the theme previewer, so make no
    assumptions. */
 
-Renderer::Renderer (ClutterActor *dst, Block **src,
-		    int w, int h, int pxw, int pxh)
+Renderer::Renderer (gint pxw, gint pxh)
 {
-	target = dst;
-	data = src;
-	width = w;
-	height = h;
 	pxwidth = pxw;
 	pxheight = pxh;
+
+	if (pxwidth == 0 || pxheight == 0) {
+		for (int i = 0; i<NCOLOURS; i++)
+			cache[i] = NULL;
+	} else {
+		for (int i = 0; i<NCOLOURS; i++) {
+			cache[i] = clutter_cairo_new (pxwidth, pxheight);
+			cairo_t *cr = clutter_cairo_create (CLUTTER_CAIRO(cache[i]));
+			drawCell (cr, i);
+			cairo_destroy (cr);
+		}
+	}
 }
 
 Renderer::~Renderer ()
 {
 }
 
-void Renderer::rescaleCache ()
+ClutterActor* Renderer::getCacheCellById (gint id)
+{
+	return cache[id];
+}
+
+void Renderer::rescaleCache (gint x, gint y)
 {
+	if (x == 0 or y == 0)
+		return;
+
+	pxwidth = x;
+	pxheight = y;
+
+	if(cache[0]) {
+		for (int i = 0; i<NCOLOURS; i++) {
+			clutter_actor_set_size (CLUTTER_ACTOR(cache[i]),
+						pxwidth, pxheight);
+			clutter_cairo_surface_resize (CLUTTER_CAIRO(cache[i]),
+						      pxwidth, pxheight);
+			cairo_t *cr = clutter_cairo_create (CLUTTER_CAIRO(cache[i]));
+			cairo_scale(cr, 1.0 * pxwidth, 1.0 * pxheight);
+			drawCell (cr, i);
+			cairo_destroy (cr);
+		}
+	} else {
+		for (int i = 0; i<NCOLOURS; i++) {
+			cache[i] = clutter_cairo_new (pxwidth, pxheight);
+			cairo_t *cr = clutter_cairo_create (CLUTTER_CAIRO(cache[i]));
+			cairo_scale(cr, 1.0 * pxwidth, 1.0 * pxheight);
+			drawCell (cr, i);
+			cairo_destroy (cr);
+		}
+	}
 }
 
 void Renderer::drawCell (cairo_t *cr, guint color)
@@ -119,30 +155,7 @@
 	cairo_paint (cr);
 }
 
-void Renderer::drawForeground (cairo_t *cr)
-{
-	int color;
-
-	cairo_scale(cr, 1.0 * pxwidth / width, 1.0 * pxheight / height);
-
-	for (color = 0; color<7; color++) {
-		drawCell (cr, color);
-	}
-}
-
-void Renderer::render ()
-{
-	cairo_t *cr;
-
-	cr = clutter_cairo_create (CLUTTER_CAIRO(target));
-
-	drawForeground (cr);
-
-	cairo_destroy (cr);
-}
-
-TangoBlock::TangoBlock (ClutterActor * dst, Block ** src,
-	    int w, int h, int pxw, int pxh, gboolean grad) : Renderer (dst, src, w, h, pxw, pxh)
+TangoBlock::TangoBlock (gint pxw, gint pxh, gboolean grad) : Renderer (pxw, pxh)
 {
 	usegrads = grad;
 }
@@ -223,23 +236,23 @@
 		case 3:
 		case 4:
 			cairo_pattern_add_color_stop_rgba (pat, 0.0, 1.0,
-								1.0,
-								1.0,
-								1.0);
+							   1.0,
+							   1.0,
+							   1.0);
 			cairo_pattern_add_color_stop_rgba (pat, 1.0, 1.0,
-								1.0,
-								1.0,
-								0.0);
+							   1.0,
+							   1.0,
+							   0.0);
 			break;
 		default:
 			cairo_pattern_add_color_stop_rgba (pat, 0.0, 0.9295,
-								0.9295,
-								0.9295,
-								1.0);
+							   0.9295,
+							   0.9295,
+							   1.0);
 			cairo_pattern_add_color_stop_rgba (pat, 1.0, 0.9295,
-								0.9295,
-								0.9295,
-								0.0);
+							   0.9295,
+							   0.9295,
+							   0.0);
 			break;
 		}
 		cairo_set_source (cr, pat);

Modified: trunk/gnometris/renderer.h
==============================================================================
--- trunk/gnometris/renderer.h	(original)
+++ trunk/gnometris/renderer.h	Tue Feb  3 18:56:05 2009
@@ -28,6 +28,7 @@
 #include <glib.h>
 #include <clutter-cairo/clutter-cairo.h>
 
+#include "blocks.h"
 #include "blockops.h"
 
 struct ThemeTableEntry {
@@ -39,34 +40,25 @@
 
 class Renderer {
 public:
-	Renderer (ClutterActor * dst, Block ** src,
-		  int w, int h, int pxw, int pxh);
+	Renderer (gint pxw, gint pxh);
 	virtual ~ Renderer ();
-	virtual void render ();
 
-	void rescaleCache ();
+	void rescaleCache (gint pxw, gint pxh);
+	ClutterActor* getCacheCellById (gint id);
 
-	Block **data;
-	int width;
-	int height;
-	int pxwidth;
-	int pxheight;
+	gint pxwidth;
+	gint pxheight;
 protected:
-	ClutterActor *target;
-
+	ClutterActor* cache[NCOLOURS];
 	virtual void drawCell (cairo_t * cr, guint color);
-	virtual void drawForeground (cairo_t * cr);
 };
 
-Renderer *rendererFactory (gint id, cairo_surface_t * dst,
-			   Block ** src, int w,
-			   int h, int pxw, int pxh);
+Renderer *rendererFactory (gint id, gint pxw, gint pxh);
 gint themeNameToNumber (const gchar * id);
 
 class TangoBlock:public Renderer {
 public:
-	TangoBlock (ClutterActor * dst, Block ** src,
-		    int w, int h, int pxw, int pxh, gboolean grad);
+	TangoBlock (gint pxw, gint pxh, gboolean grad);
 
 protected:
 	virtual void drawCell (cairo_t * cr, guint color);

Modified: trunk/gnometris/tetris.cpp
==============================================================================
--- trunk/gnometris/tetris.cpp	(original)
+++ trunk/gnometris/tetris.cpp	Tue Feb  3 18:56:05 2009
@@ -83,7 +83,6 @@
 	RESET
 };
 
-
 Tetris::Tetris(int cmdlLevel):
 	themeno (0),
 	field(0),



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]