Commits

Anonymous committed b669ab1

rect handling cleanedup

Comments (0)

Files changed (5)

 # BREAK = change breaks existing code
 # BUG   = fixed a bug that was crashing
 
+Jan 23, 2001
+	display.update() no longer effects input Rects [BREAK]
+	Surface.fill() no longer effects input Rect [BREAK]
+	small memory leak in display.update() fixed
+
 Jan 18, 2001
 	cursor.read_xbm() renamed to cursor.load_xbm() [BREAK]
 

docs/ref/pygame_display.html

 This call will update a section (or sections) of the display
 screen. You must update an area of your display when you change
 its contents. If passed with no arguments, this will update the
-entire display surface. If you have many lists that need
+entire display surface. If you have many rects that need
 updating, it is best to combine them into a sequence and pass
 them all at once. This call will accept a sequence of rectstyle
-arguments
+arguments. (any None's in the list will be ignored.
 </ul><br>&nbsp;<br>
 
 

examples/aliens.py

 DIFFICULTY     = 8
 BOMB_ODDS      = 130
 DANGER         = 10
-SORRYSCORE     = 20
-GOODSCORE      = 60
+SORRYSCORE     = 18
+GOODSCORE      = 50
 
 #some globals for friendly access
 dirtyrects = [] # list of update_rects
 {
 	SDL_Surface* screen;
 	GAME_Rect *gr, temp = {0};
+	int wide, high;
 
+	/*determine type of argument we got*/
 	if(PyTuple_Size(arg) == 0)
 		gr = &temp;
 	else
+	{
 		gr = GameRect_FromObject(arg, &temp);
+		if(gr && gr != &temp)
+		{
+			memcpy(&temp, gr, sizeof(temp));
+			gr = &temp;
+		}
+	}
 	VIDEO_INIT_CHECK();
 
-	if(gr)
+	screen = SDL_GetVideoSurface();
+	if(!screen)
+		return RAISE(PyExc_SDLError, SDL_GetError());
+	wide = screen->w;
+	high = screen->h;
+
+	if(gr) /*single or no rect given*/
 	{
-		screen = SDL_GetVideoSurface();
-		if(!screen)
-			return RAISE(PyExc_SDLError, SDL_GetError());
-		
-		if(screencroprect(gr, screen->w, screen->h))
+		if(screencroprect(gr, wide, high))
 			SDL_UpdateRect(screen, gr->x, gr->y, gr->w, gr->h);
 	}
-	else
+	else /*sequence given*/
 	{
 		PyObject* seq;
 		PyObject* r;
 
 		if(PyTuple_Size(arg) != 1)
 			return RAISE(PyExc_ValueError, "update requires a rectstyle or sequence of recstyles");
-
 		seq = PyTuple_GET_ITEM(arg, 0);
 		if(!seq || !PySequence_Check(seq))
 			return RAISE(PyExc_ValueError, "update requires a rectstyle or sequence of recstyles");
 
-		VIDEO_INIT_CHECK();
-
-		screen = SDL_GetVideoSurface();
-		if(!screen)
-			return RAISE(PyExc_SDLError, SDL_GetError());
-		
 		num = PySequence_Length(seq);
 		rects = PyMem_New(SDL_Rect, num);
 		if(!rects) return NULL;
 		count = 0;
 		for(loop = 0; loop < num; ++loop)
 		{
+			GAME_Rect* cur_rect = (GAME_Rect*)(rects + count);
+
+			/*get rect from the sequence*/
 			r = PySequence_GetItem(seq, loop);
 			if(r == Py_None)
 			{
 				Py_DECREF(r);
 				continue;
 			}
-			gr = GameRect_FromObject(r, &temp);
+			gr = GameRect_FromObject(r, cur_rect);
+			Py_XDECREF(r);
 			if(!gr)
 			{
-				Py_XDECREF(r);
 				PyMem_Free(rects);
 				return RAISE(PyExc_ValueError, "update_rects requires a single list of rects");
 			}
-			if(!screencroprect(gr, screen->w, screen->h))
+
+			/*make sure we are using our own copy of the rect*/
+			if(gr != cur_rect)
+			{
+				memcpy(cur_rect, gr, sizeof(GAME_Rect));
+				gr = cur_rect;
+			}
+			/*bail out if rect not onscreen*/
+			if(!screencroprect(gr, wide, high))
 				continue;
-			rects[count].x = gr->x;
-			rects[count].y = gr->y;
-			rects[count].w = (unsigned short)gr->w;
-			rects[count].h = (unsigned short)gr->h;
+			if(gr->w < 1 && gr->h < 1)
+				continue;
+
 			++count;
 		}
 
 	SDL_Surface* src;
 	SDL_Surface* newsurf;
 	Uint32 flags;
-	
+
 	if(!PyArg_ParseTuple(args, "|O!", &PySurface_Type, &srcsurf))
 		return NULL;
 
 	else if(!(rect = GameRect_FromObject(r, &temp)))
 		return RAISE(PyExc_ValueError, "invalid rectstyle object");
 
+	/*we need a fresh copy so our Rect values don't get munged*/
+	if(rect != &temp)
+	{
+		memcpy(&temp, rect, sizeof(temp));
+		rect = &temp;
+	}
+
 	result = SDL_FillRect(surf, (SDL_Rect*)rect, color);
 	if(result == -1)
 		return RAISE(PyExc_SDLError, SDL_GetError());