All pastes #594625 Raw Edit

Untitled

public cpp v1 · immutable
#594625 ·published 2007-06-29 00:44 UTC
rendered paste body
/*    SEL - Simple DirectMedia Layer Extension Library    Copyright (C) 2002 Matej Knopp <knopp@users.sf.net>    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library 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    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* microtile array implementation *//*  * This is a microtile array implementation similiar to the one * from LibArt_LGPL. First, I wanted to use that one but unfortunately * I fount out that it suffered from a bad design and simply didn't meet * my requirements so I decided to write the implementation on my own. */#include "../sel-config.h"#include "sdl.h"#include <stdlib.h>#include <string.h>#define gem_malloc  malloc#define gem_free    freetypedef struct _GemUta GemUta;typedef struct _GemRect GemRect;typedef Uint32 GemUtaBBox;#define GEM_UTA_BBOX_CONS(x0, y0, x1, y1)  (((x0) << 24) | ((y0) << 16) | \                                            ((x1) << 8) | (y1))#define GEM_UTILE_EMPTY   0x00000000#define GEM_UTILE_FULL    0x01012020#define GEM_UTA_BBOX_X0(ub) ((ub) >> 24)#define GEM_UTA_BBOX_Y0(ub) (((ub) >> 16) & 0xff)#define GEM_UTA_BBOX_X1(ub) (((ub) >> 8) & 0xff)#define GEM_UTA_BBOX_Y1(ub) ((ub) & 0xff)#define GEM_UTILE_SHIFT     5#define GEM_UTILE_SIZE      (1 << GEM_UTILE_SHIFT)#define GEM_MIN(a,b) ((a) < (b) ? (a) : (b))#define GEM_MAX(a,b) ((a) > (b) ? (a) : (b))struct _GemUta{	int x;	int y;	int width;    /* number of tiles in one line */	int height;   /* number of tiles in one row */	GemUtaBBox *tiles;};struct _GemRect{	int x0;	int x1;	int y0;	int y1;};staticGemUta    * gem_uta_new        (int x, int y, int width, int height);staticGemUta    * gem_uta_new_coords (int x, int y, int width, int height);staticvoid        gem_uta_free       (GemUta * uta);staticvoid        gem_uta_union      (GemUta * uta1, const GemUta * uta2);staticvoid        gem_uta_add_rect   (GemUta * uta, const GemRect * rect);#define GEM_UTA_QUERY_CONTAIN		0#define GEM_UTA_QUERY_INTERSECT		1staticint         gem_uta_query_rect (const GemUta * uta,                                 const GemRect * rect, int query);staticSDL_Rect  * gem_uta_get_rects  (const GemUta * uta, int * num_rects,                                 int min_x, int min_y,                                int max_x, int max_y);#define GEM_UTILE_UNION(b1, b2) \	{ \		if (b1 == GEM_UTILE_FULL || b2 == GEM_UTILE_EMPTY) \			{ } \		else if (b1 == GEM_UTILE_EMPTY || b2 == GEM_UTILE_FULL) \			{ b1 = b2; } \		else { \			b1 = GEM_UTA_BBOX_CONS ( \				GEM_MIN (GEM_UTA_BBOX_X0(b1), \				         GEM_UTA_BBOX_X0(b2)), \				GEM_MIN (GEM_UTA_BBOX_Y0(b1), \				         GEM_UTA_BBOX_Y0(b2)), \				GEM_MAX (GEM_UTA_BBOX_X1(b1), \				         GEM_UTA_BBOX_X1(b2)), \				GEM_MAX (GEM_UTA_BBOX_Y1(b1), \				         GEM_UTA_BBOX_Y1(b2))); \		} \	}	static GemUta *gem_uta_new (int x, int y, int width, int height){	GemUta *uta;		uta = (GemUta *) gem_malloc (sizeof (GemUta));	uta->x = x;	uta->y = y;	uta->width = width;	uta->height = height;	uta->tiles = (GemUtaBBox *) 		gem_malloc (sizeof (GemUtaBBox) * width * height);	memset (uta->tiles, 0, sizeof (GemUtaBBox) * width * height);		return uta;}static GemUta *gem_uta_new_coords (int x, int y, int width, int height){	return gem_uta_new (x >> GEM_UTILE_SHIFT, y >> GEM_UTILE_SHIFT,	                    (width >> GEM_UTILE_SHIFT) + 1,	                    (height >> GEM_UTILE_SHIFT) + 1);}static voidgem_uta_free (GemUta * uta){	if (uta)	{		if (uta->tiles)			gem_free (uta->tiles);		gem_free (uta);	}}static void gem_uta_union (GemUta * uta1, const GemUta *uta2){	Sint32 x0, y0, x1, y1;	int x, y;	GemUtaBBox *_b1;	const GemUtaBBox *_b2;	if (!uta1 || !uta2)		return;	x0 = GEM_MAX (uta1->x, uta2->x);	y0 = GEM_MAX (uta2->y, uta2->y);	x1 = GEM_MIN (uta1->x + uta1->width - 1, uta2->x + uta2->width - 1);	y1 = GEM_MIN (uta1->y + uta1->height - 1, uta2->y + uta2->height - 1);	if (x0 > x1 || y0 > y1)		return;	_b1 = & (uta1->tiles [(y0 - uta1->y) * uta1->width + (x0 - uta1->x)]);	_b2 = & (uta2->tiles [(y0 - uta2->y) * uta2->width + (x0 - uta2->x)]);		for (y = y0; y <= y1; ++y)	{		GemUtaBBox *b1 = _b1;		const GemUtaBBox *b2 = _b2;		for (x = x0; x <= x1; ++x)		{			GEM_UTILE_UNION (*b1, *b2);					++b1;			++b2;		}		_b1 += uta1->width;		_b2 += uta2->width;	}}/* * Add a rectangle to the microtile array. * The coordinates of the rectangle are considered absolute. */static voidgem_uta_add_rect (GemUta * uta, const GemRect * _rect){	int xf0, xf1, yf0, yf1;	int width, height;	int x0, y0, x1, y1;	int x, y;	GemUtaBBox *_b;	GemUtaBBox *b;	GemUtaBBox bbox;	GemRect rect;	if (!uta || !_rect)		return;		rect = *_rect;		rect.x0 -= uta->x << GEM_UTILE_SHIFT;	rect.y0 -= uta->y << GEM_UTILE_SHIFT;	rect.x1 -= uta->x << GEM_UTILE_SHIFT;	rect.y1 -= uta->y << GEM_UTILE_SHIFT;		if (rect.x0 < 0)		rect.x0 = 0;	if (rect.y0 < 0)		rect.y0 = 0;	if (rect.x1 > (uta->width << GEM_UTILE_SHIFT))		rect.x1 = (uta->width << GEM_UTILE_SHIFT);	if (rect.y1 > (uta->height << GEM_UTILE_SHIFT))		rect.y1 = (uta->height << GEM_UTILE_SHIFT);		if (rect.x0 > rect.x1 || rect.y0 > rect.y1)		return;	width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) 	        - (rect.x0 >> GEM_UTILE_SHIFT);	height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) 	         - (rect.y0 >> GEM_UTILE_SHIFT);			xf0 = rect.x0 % (GEM_UTILE_SIZE);	yf0 = rect.y0 % (GEM_UTILE_SIZE);	xf1 = rect.x1 % (GEM_UTILE_SIZE);	yf1 = rect.y1 % (GEM_UTILE_SIZE);	x0 = rect.x0 >> GEM_UTILE_SHIFT;	y0 = rect.y0 >> GEM_UTILE_SHIFT;	x1 = rect.x1 >> GEM_UTILE_SHIFT;	y1 = rect.y1 >> GEM_UTILE_SHIFT;		_b = & (uta->tiles [(y0 * uta->width) + x0]);	if (width == 1 && height == 1)	{		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1);		GEM_UTILE_UNION (*_b, bbox);		return;	}	if (width == 1)	{		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, 		                          GEM_UTILE_SIZE);		GEM_UTILE_UNION (*_b, bbox);		_b += uta->width;		if (height > 2)		{			for (y = y0 + 1; y <= (y1 - 1); ++y)			{				bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, 				                          GEM_UTILE_SIZE);				GEM_UTILE_UNION (*_b, bbox);				_b += uta->width;			}		}		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1);		GEM_UTILE_UNION (*_b, bbox);		return;	}	else if (height == 1)	{		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, 		                          GEM_UTILE_SIZE, yf1 + 1);		GEM_UTILE_UNION (*_b, bbox);		++_b;		if (width > 2)		{			for (x = x0 + 1; x <= (x1 - 1); ++x)			{				bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1,				                          GEM_UTILE_SIZE, 				                          xf1 + 1);				GEM_UTILE_UNION (*_b, bbox);				++_b;			}		}		bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1);		GEM_UTILE_UNION (*_b, bbox);		return;	}		b = _b;	/* top-left corner */	bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, 	                          GEM_UTILE_SIZE);	GEM_UTILE_UNION (*b, bbox);	++b;	/* top edge */	if (width > 2)	{		for (x = x0 + 1; x <= (x1 - 1); ++x)		{			bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE,			                          GEM_UTILE_SIZE);			GEM_UTILE_UNION (*b, bbox);			++b;		}	}		/* top-right corner */	bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);	GEM_UTILE_UNION (*b, bbox);		_b += uta->width;	/* left edge, content, right edge */	if (height > 2)	{		for (y = y0 + 1; y <= (y1 - 1); ++y)		{			b = _b;						/* left edge */			bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE,			                          GEM_UTILE_SIZE);			GEM_UTILE_UNION (*b, bbox);			++b;			/* content */			if (width > 2)			{				for (x = x0 + 1; x <= (x1 - 1); ++x)				{					*b = GEM_UTILE_FULL;					++b;				}			}						/* right edge */			bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, 			                          GEM_UTILE_SIZE);			GEM_UTILE_UNION (*b, bbox);						_b += uta->width;		}	}	b = _b;	/* bottom-left corner */	bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1);	GEM_UTILE_UNION (*b, bbox);	++b;		/* bottom edge */	if (width > 2)	{		for (x = x0 + 1; x <= (x1 - 1); ++x)		{			bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, 									  yf1 + 1);			GEM_UTILE_UNION (*b, bbox);			++b;		}	}		/* bottom-left corner */	bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1);	GEM_UTILE_UNION (*b, bbox);	/* done. */	}#define GEM_UTILE_CONTAINS(b1, b2) \	( !(GEM_UTA_BBOX_X0 (b1) > GEM_UTA_BBOX_X0 (b2) || \	    GEM_UTA_BBOX_Y0 (b1) > GEM_UTA_BBOX_Y0 (b2) || \	    GEM_UTA_BBOX_X1 (b1) < GEM_UTA_BBOX_X1 (b2) || \	    GEM_UTA_BBOX_Y1 (b1) < GEM_UTA_BBOX_Y1 (b2)) ) #define GEM_UTILE_INTERSECTS(b1, b2) \	(!( (GEM_MAX (GEM_UTA_BBOX_X0 (b1), GEM_UTA_BBOX_X0 (b2)) > \	     GEM_MIN (GEM_UTA_BBOX_X1 (b1), GEM_UTA_BBOX_X1 (b2))) || \	    (GEM_MAX (GEM_UTA_BBOX_Y0 (b1), GEM_UTA_BBOX_Y0 (b2)) > \	     GEM_MIN (GEM_UTA_BBOX_Y1 (b1), GEM_UTA_BBOX_Y1 (b2)))))/* * Return if the uta contains or intersects the rectangle. */static intgem_uta_query_rect (const GemUta * uta, const GemRect * _rect, int query){	int xf0, xf1, yf0, yf1;	int width, height;	int x0, y0, x1, y1;	int x, y;	GemUtaBBox *_b;	GemUtaBBox *b;	GemUtaBBox bbox;	GemRect rect;	if (!uta || !_rect)		return 0;		rect = *_rect;		rect.x0 -= uta->x << GEM_UTILE_SHIFT;	rect.y0 -= uta->y << GEM_UTILE_SHIFT;	rect.x1 -= uta->x << GEM_UTILE_SHIFT;	rect.y1 -= uta->y << GEM_UTILE_SHIFT;		if (rect.x0 < 0)		rect.x0 = 0;	if (rect.y0 < 0)		rect.y0 = 0;	if (rect.x1 > (uta->width << GEM_UTILE_SHIFT))		rect.x1 = (uta->width << GEM_UTILE_SHIFT);	if (rect.y1 > (uta->height << GEM_UTILE_SHIFT))		rect.y1 = (uta->height << GEM_UTILE_SHIFT);		if (rect.x0 > rect.x1 || rect.y0 > rect.y1)		return 0;	width = ((rect.x1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) 	        - (rect.x0 >> GEM_UTILE_SHIFT);	height = ((rect.y1 + GEM_UTILE_SIZE) >> GEM_UTILE_SHIFT) 	         - (rect.y0 >> GEM_UTILE_SHIFT);			xf0 = rect.x0 % (GEM_UTILE_SIZE);	yf0 = rect.y0 % (GEM_UTILE_SIZE);	xf1 = rect.x1 % (GEM_UTILE_SIZE);	yf1 = rect.y1 % (GEM_UTILE_SIZE);	x0 = rect.x0 >> GEM_UTILE_SHIFT;	y0 = rect.y0 >> GEM_UTILE_SHIFT;	x1 = rect.x1 >> GEM_UTILE_SHIFT;	y1 = rect.y1 >> GEM_UTILE_SHIFT;		_b = & (uta->tiles [(y0 * uta->width) + x0]);	if (width == 1 && height == 1)	{		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, yf1 + 1);		if (query == GEM_UTA_QUERY_INTERSECT &&		    GEM_UTILE_INTERSECTS (*_b, bbox))			return 1;		else if (query == GEM_UTA_QUERY_CONTAIN &&		        GEM_UTILE_CONTAINS (*_b, bbox))			return 1;		return 0;				}#define CHECK(b1,b2) \	{ \		if (query == GEM_UTA_QUERY_INTERSECT && \		    GEM_UTILE_INTERSECTS (b1, b2)) \			return 1; \		else if (query == GEM_UTA_QUERY_CONTAIN && \		         !(GEM_UTILE_CONTAINS (b1, b2))) \			return 0; \	} 	if (width == 1)	{		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, xf1 + 1, 		                          GEM_UTILE_SIZE);		CHECK (*_b, bbox);		_b += uta->width;		if (height > 2)		{			for (y = y0 + 1; y <= (y1 - 1); ++y)			{				bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, 				                          GEM_UTILE_SIZE);				CHECK (*_b, bbox);				_b += uta->width;			}		}		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, xf1 + 1, yf1 + 1);		CHECK (*_b, bbox);		if (query == GEM_UTA_QUERY_INTERSECT)			return 0;		else if (query == GEM_UTA_QUERY_CONTAIN)			return 1;	}	else if (height == 1)	{		bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, 		                          GEM_UTILE_SIZE, yf1 + 1);		CHECK (*_b, bbox);		++_b;		if (width > 2)		{			for (x = x0 + 1; x <= (x1 - 1); ++x)			{				bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1,				                          GEM_UTILE_SIZE, 				                          xf1 + 1);				CHECK (*_b, bbox);				++_b;			}		}		bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, yf1 + 1);		CHECK (*_b, bbox);		if (query == GEM_UTA_QUERY_INTERSECT)			return 0;		else if (query == GEM_UTA_QUERY_CONTAIN)			return 1;	}		b = _b;	/* top-left corner */	bbox = GEM_UTA_BBOX_CONS (xf0 + 1, yf0 + 1, GEM_UTILE_SIZE, 	                          GEM_UTILE_SIZE);	CHECK (*b, bbox);	++b;	/* top edge */	if (width > 2)	{		for (x = x0 + 1; x <= (x1 - 1); ++x)		{			bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, GEM_UTILE_SIZE,			                          GEM_UTILE_SIZE);			CHECK (*b, bbox);			++b;		}	}		/* top-right corner */	bbox = GEM_UTA_BBOX_CONS (1, yf0 + 1, xf1 + 1, GEM_UTILE_SIZE);	CHECK (*b, bbox);		_b += uta->width;	/* left edge, content, right edge */	if (height > 2)	{		for (y = y0 + 1; y <= (y1 - 1); ++y)		{			b = _b;						/* left edge */			bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE,			                          GEM_UTILE_SIZE);			CHECK (*b, bbox);			++b;			/* content */			if (width > 2)			{				for (x = x0 + 1; x <= (x1 - 1); ++x)				{					CHECK (*b, GEM_UTILE_FULL);					++b;				}			}						/* right edge */			bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, 			                          GEM_UTILE_SIZE);			CHECK (*b, bbox);						_b += uta->width;		}	}	b = _b;	/* bottom-left corner */	bbox = GEM_UTA_BBOX_CONS (xf0 + 1, 1, GEM_UTILE_SIZE, yf1 + 1);	CHECK (*b, bbox);	++b;		/* bottom edge */	if (width > 2)	{		for (x = x0 + 1; x <= (x1 - 1); ++x)		{			bbox = GEM_UTA_BBOX_CONS (1, 1, GEM_UTILE_SIZE, 			                          yf1 + 1);			CHECK (*b, bbox);			++b;		}	}		/* bottom-left corner */	bbox = GEM_UTA_BBOX_CONS (1, 1, xf1 + 1, yf1 + 1);	CHECK (*b, bbox);#undef CHECK	/* done. */		if (query == GEM_UTA_QUERY_CONTAIN)		return 1;			return 0;}#undef CLAMP#define CLAMP(a,min,max) (a = (a < min ? min : (a > max ? max : a)))static SDL_Rect *gem_uta_get_rects (const GemUta *uta, int * num_rects,                    int min_x, int min_y, int max_x, int max_y){	const int size = uta->width * uta->height;#ifdef __GNUC__	GemRect rects [size];#else	GemRect *rects = (GemRect*) gem_malloc (size * sizeof (GemRect));#endif	SDL_Rect *result = NULL;	int n_rects = 0;	int x, y;	int x0, y0, x1, y1;#ifdef __GNUC__	int glom [uta->width * uta->height];#else	int *glom = (int*) gem_malloc (uta->width * uta->height);#endif	int i; /* current */		for (i = 0; i < uta->width * uta->height; ++i)		glom [i] = -1;	i = 0;			for (y = 0; y < uta->height; ++y)	{		for (x = 0; x < uta->width; ++x)		{#define TILE uta->tiles [i]			int start;			int finish = 0;			GemUtaBBox b;			b = uta->tiles [i];			if (TILE == GEM_UTILE_EMPTY)				goto next;									x0 = ((uta->x + x) << GEM_UTILE_SHIFT) 			      + GEM_UTA_BBOX_X0 (TILE) - 1;			y0 = ((uta->y + y) << GEM_UTILE_SHIFT) 			      + GEM_UTA_BBOX_Y0 (TILE) - 1;			y1 = ((uta->y + y) << GEM_UTILE_SHIFT) 			      + GEM_UTA_BBOX_Y1 (TILE) - 1;						CLAMP (x0, min_x, max_x);			CLAMP (y0, min_y, max_y);			CLAMP (y1, min_y, max_y);						start = i;						if (GEM_UTA_BBOX_X1 (TILE) != GEM_UTILE_SIZE ||			    x == uta->width - 1)			{ /* the tile does not continue */				goto done;			}						while (!finish)			{				++x;				++i;								if (x == uta->width ||				    GEM_UTA_BBOX_Y0 (TILE) 				       != GEM_UTA_BBOX_Y0 (b) ||				    GEM_UTA_BBOX_Y1 (TILE)					   != GEM_UTA_BBOX_Y1 (b) ||				    GEM_UTA_BBOX_X0 (TILE) != 1)				{					--x;					--i;					finish = 1;				}			}		done:			x1 = ((uta->x + x) << GEM_UTILE_SHIFT) 			      + GEM_UTA_BBOX_X1 (TILE) - 1;						CLAMP (x1, min_x, max_x);			if (glom [start] != -1 && /* try to glom */ 			    rects [glom [start]].x0 == x0 &&			    rects [glom [start]].x1 == x1 &&			    rects [glom [start]].y1 == y0 - 1)			{				rects [glom [start]].y1 = y1;				if (y != uta->height - 1)				{					glom [start + uta->width] 					      = glom [start];				}			}			else			{				rects [n_rects].x0 = x0;				rects [n_rects].y0 = y0;				rects [n_rects].x1 = x1;				rects [n_rects].y1 = y1;				if (y != uta->height - 1)				{					glom [start + uta->width] = n_rects;				}				n_rects ++;			}		next:			++i;#undef TILE		}	}		result = (SDL_Rect*) gem_malloc (sizeof (SDL_Rect) * n_rects);		for (i = 0; i < n_rects; ++i)	{		result [i].x = rects [i].x0;		result [i].y = rects [i].y0;		result [i].w = rects [i].x1 - rects [i].x0 + 1;		result [i].h = rects [i].y1 - rects [i].y0 + 1;	}	*num_rects = n_rects;#ifndef __GNUC__	free (glom);	free (rects);#endif	return result;}#include "uta.h"#include "error.h"namespace SEL{Uta::Uta ()    : m_uta (NULL){ }Uta::Uta (int x, int y, int w, int h)	: m_x (x), m_y (y), m_w (w), m_h (h){	m_uta = gem_uta_new_coords (x, y, w, h);	if (!m_uta)		throw Error ("Out of memory!");} Uta::~Uta (){	if (m_uta)		gem_uta_free (m_uta);}voidUta::clear (){	if (!m_uta)		return;			memset (m_uta->tiles, 0, 		m_uta->width * m_uta->height * sizeof(GemUtaBBox));}voidUta::init (int x, int y, int w, int h){	if (m_uta)		gem_uta_free (m_uta);	m_uta = gem_uta_new_coords (x, y, w, h);	m_x = x;	m_y = y;	m_w = w;	m_h = h;	if (!m_uta)		throw Error ("Out of memory!");} intUta::getRectangles (SDL::Rect * & rects, int min_x, int max_x,                     int min_y, int max_y) const{	if (!m_uta)		return 0;	int n_rects;		rects = gem_uta_get_rects (m_uta, &n_rects, min_x, max_x, min_y, max_y);	return n_rects;}intUta::getRectangles (SDL::Rect * & rects) const{	if (!m_uta)		return 0;	int n_rects;		rects = gem_uta_get_rects (m_uta, &n_rects, 				   m_x, m_y, m_x + m_w - 1, m_y + m_h - 1);	return n_rects;}bool Uta::contains (const SDL::Rect & rect) const{	if (!m_uta)		return false;	GemRect r;	r.x0 = rect.x;	r.y0 = rect.y;	r.x1 = rect.x + rect.w - 1;	r.y1 = rect.y + rect.h - 1;	return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_CONTAIN);}	bool Uta::intersects (const SDL::Rect & rect) const{	if (!m_uta)		return false;	GemRect r;	r.x0 = rect.x;	r.y0 = rect.y;	r.x1 = rect.x + rect.w - 1;	r.y1 = rect.y + rect.h - 1;	return gem_uta_query_rect (m_uta, &r, GEM_UTA_QUERY_INTERSECT);}voidUta::unite (const SDL::Rect & rect){	if (!m_uta || rect.w == 0 || rect.h == 0)		return;	GemRect r;	r.x0 = rect.x;	r.y0 = rect.y;	r.x1 = rect.x + rect.w - 1;	r.y1 = rect.y + rect.h - 1;	gem_uta_add_rect (m_uta, &r);}Uta &Uta::operator += (const SDL::Rect & rect){	if (!m_uta || rect.w == 0 || rect.h == 0)		return *this;	GemRect r;	r.x0 = rect.x;	r.y0 = rect.y;	r.x1 = rect.x + rect.w - 1;	r.y1 = rect.y + rect.h - 1;	gem_uta_add_rect (m_uta, &r);	return *this;}voidUta::unite (const Uta & uta){	if (m_uta)		gem_uta_union (m_uta, uta.m_uta);}Uta &Uta::operator += (const Uta & uta){	if (m_uta)		gem_uta_union (m_uta, uta.m_uta);	return *this;}}; // namespace SEL