Commits

pygame  committed bc5028f

draw cleanups and mixer chunks

  • Participants
  • Parent commits 54b0c75

Comments (0)

Files changed (6)

 September 27, 2001
 	drawing filled circles returns bounding rect
 	ellipses and circles drawn inside given area
+	mixer init can take chunksize
+	fix in clipped horizontal line drawing [BUG]
 
 September 26, 2001
 	key.set_repeat() raises exception error, smarter args

File docs/index.html

 <a href=ref/pygame_display.html#toggle_fullscreen>pygame.display.toggle_fullscreen</a> - switch the display fullscreen mode<br>
 <a href=ref/pygame_display.html#update>pygame.display.update</a> - update an area of the display<br>
 <a href=ref/pygame_draw.html#circle>pygame.draw.circle</a> - draw a circle on a surface<br>
+<a href=ref/pygame_draw.html#circle>pygame.draw.circle</a> - draw a circle on a surface<br>
+<a href=ref/pygame_draw.html#ellipse>pygame.draw.ellipse</a> - draw an ellipse on a surface<br>
 <a href=ref/pygame_draw.html#ellipse>pygame.draw.ellipse</a> - draw an ellipse on a surface<br>
 <a href=ref/pygame_draw.html#line>pygame.draw.line</a> - draw a line on a surface<br>
+<a href=ref/pygame_draw.html#line>pygame.draw.line</a> - draw a line on a surface<br>
+<a href=ref/pygame_draw.html#lines>pygame.draw.lines</a> - draw multiple connected lines on a surface<br>
 <a href=ref/pygame_draw.html#lines>pygame.draw.lines</a> - draw multiple connected lines on a surface<br>
 <a href=ref/pygame_draw.html#polygon>pygame.draw.polygon</a> - draws a polygon on a surface<br>
+<a href=ref/pygame_draw.html#polygon>pygame.draw.polygon</a> - draws a polygon on a surface<br>
 <a href=ref/pygame_draw.html#rect>pygame.draw.rect</a> - draws a polygon on a surface<br>
+<a href=ref/pygame_draw.html#rect>pygame.draw.rect</a> - draws a rectangle on a surface<br>
 <a href=ref/pygame_event.html#Event>pygame.event.Event</a> - create new event object<br>
 <a href=ref/pygame_event.html#event_name>pygame.event.event_name</a> - name for event type<br>
 <a href=ref/pygame_event.html#get>pygame.event.get</a> - get all of an event type from the queue<br>

File docs/ref/pygame_draw.html

 draw a circle on a surface</td></tr>
 
 
+<tr><td><a href=#circle>circle</a></td><td> -
+draw a circle on a surface</td></tr>
+
+
+<tr><td><a href=#ellipse>ellipse</a></td><td> -
+draw an ellipse on a surface</td></tr>
+
+
 <tr><td><a href=#ellipse>ellipse</a></td><td> -
 draw an ellipse on a surface</td></tr>
 
 draw a line on a surface</td></tr>
 
 
+<tr><td><a href=#line>line</a></td><td> -
+draw a line on a surface</td></tr>
+
+
 <tr><td><a href=#lines>lines</a></td><td> -
 draw multiple connected lines on a surface</td></tr>
 
 
+<tr><td><a href=#lines>lines</a></td><td> -
+draw multiple connected lines on a surface</td></tr>
+
+
 <tr><td><a href=#polygon>polygon</a></td><td> -
 draws a polygon on a surface</td></tr>
 
 
+<tr><td><a href=#polygon>polygon</a></td><td> -
+draws a polygon on a surface</td></tr>
+
+
+<tr><td><a href=#rect>rect</a></td><td> -
+draws a rectangle on a surface</td></tr>
+
+
 <tr><td><a href=#rect>rect</a></td><td> -
 draws a polygon on a surface</td></tr>
 
 This function will temporarily lock the surface.
 </ul><br>&nbsp;<br>
 
+<a name=circle><font size=+2><b>circle
+</b></font><br><font size=+1><tt>
+pygame.draw.circle(Surface, color, pos, radius, width) -> Rect
+</tt></font><ul>
+Draws a circular shape on the Surface. The given position
+is the center of the circle, and radius is the size. The width
+argument is the thickness to draw the outer edge. If width is
+zero then the circle will be filled.
+<br>&nbsp;<br>
+The color argument can be either a RGB sequence or mapped color integer.
+<br>&nbsp;<br>
+This function will temporarily lock the surface.
+</ul><br>&nbsp;<br>
+
 <a name=ellipse><font size=+2><b>ellipse
 </b></font><br><font size=+1><tt>
 pygame.draw.ellipse(Surface, color, Rect, width) -> Rect
 </tt></font><ul>
-Draws a circular shape on the Surface. The given rectangle
+Draws an elliptical shape on the Surface. The given rectangle
 is the area that the circle will fill. The width argument is
 the thickness to draw the outer edge. If width is zero then
 the ellipse will be filled.
 This function will temporarily lock the surface.
 </ul><br>&nbsp;<br>
 
+<a name=ellipse><font size=+2><b>ellipse
+</b></font><br><font size=+1><tt>
+pygame.draw.ellipse(Surface, color, Rect, width) -> Rect
+</tt></font><ul>
+Draws an elliptical shape on the Surface. The given rectangle
+is the area that the circle will fill. The width argument is
+the thickness to draw the outer edge. If width is zero then
+the ellipse will be filled.
+<br>&nbsp;<br>
+The color argument can be either a RGB sequence or mapped color integer.
+<br>&nbsp;<br>
+This function will temporarily lock the surface.
+</ul><br>&nbsp;<br>
+
+<a name=line><font size=+2><b>line
+</b></font><br><font size=+1><tt>
+pygame.draw.line(Surface, color, startpos, endpos, width=1) -> Rect
+</tt></font><ul>
+Draws a line on a surface. This will respect the clipping
+rectangle. A bounding box of the effected area is returned
+as a rectangle.
+<br>&nbsp;<br>
+The color argument can be either a RGB sequence or mapped color integer.
+<br>&nbsp;<br>
+This function will temporarily lock the surface.
+</ul><br>&nbsp;<br>
+
 <a name=line><font size=+2><b>line
 </b></font><br><font size=+1><tt>
 pygame.draw.line(Surface, color, startpos, endpos, width=1) -> Rect
 This function will temporarily lock the surface.
 </ul><br>&nbsp;<br>
 
+<a name=lines><font size=+2><b>lines
+</b></font><br><font size=+1><tt>
+pygame.draw.lines(Surface, color, closed, point_array, width=1) -> Rect
+</tt></font><ul>
+Draws a sequence on a surface. You must pass at least two points
+in the sequence of points. The closed argument is a simple boolean
+and if true, a line will be draw between the first and last points.
+Note that specifying a linewidth wider than 1 does not fill in the
+gaps between the lines. Therefore wide lines and sharp corners won't
+be joined seamlessly.
+<br>&nbsp;<br>
+This will respect the clipping rectangle. A bounding box of the
+effected area is returned as a rectangle.
+<br>&nbsp;<br>
+The color argument can be either a RGB sequence or mapped color integer.
+<br>&nbsp;<br>
+This function will temporarily lock the surface.
+</ul><br>&nbsp;<br>
+
 <a name=polygon><font size=+2><b>polygon
 </b></font><br><font size=+1><tt>
 pygame.draw.polygon(Surface, color, pointslist, width) -> Rect
 Draws a polygonal shape on the Surface. The given pointlist
 is the vertices of the polygon. The width argument is
 the thickness to draw the outer edge. If width is zero then
-the ellipse will be filled.
+the polygonal shape will be filled.
+<br>&nbsp;<br>
+The color argument can be either a RGB sequence or mapped color integer.
+<br>&nbsp;<br>
+This function will temporarily lock the surface.
+</ul><br>&nbsp;<br>
+
+<a name=polygon><font size=+2><b>polygon
+</b></font><br><font size=+1><tt>
+pygame.draw.polygon(Surface, color, pointslist, width) -> Rect
+</tt></font><ul>
+Draws a polygonal shape on the Surface. The given pointlist
+is the vertices of the polygon. The width argument is
+the thickness to draw the outer edge. If width is zero then
+the polygon will be filled.
 <br>&nbsp;<br>
 The color argument can be either a RGB sequence or mapped color integer.
 <br>&nbsp;<br>
 </b></font><br><font size=+1><tt>
 pygame.draw.rect(Surface, color, Rect, width) -> Rect
 </tt></font><ul>
-Draws a polygonal shape on the Surface. The given Rect
+Draws a rectangular shape on the Surface. The given Rect
 is the area of the rectangle. The width argument is
 the thickness to draw the outer edge. If width is zero then
-the ellipse will be filled.
+the rectangle will be filled.
 <br>&nbsp;<br>
 The color argument can be either a RGB sequence or mapped color integer.
 <br>&nbsp;<br>
 can be hardware accelerated when the moons are in alignement.
 </ul><br>&nbsp;<br>
 
+<a name=rect><font size=+2><b>rect
+</b></font><br><font size=+1><tt>
+pygame.draw.rect(Surface, color, Rect, width) -> Rect
+</tt></font><ul>
+Draws a rectangular shape on the Surface. The given Rect
+is the area of the rectangle. The width argument is
+the thickness to draw the outer edge. If width is zero then
+the rectangle will be filled.
+<br>&nbsp;<br>
+The color argument can be either a RGB sequence or mapped color integer.
+<br>&nbsp;<br>
+This function will temporarily lock the surface.
+<br>&nbsp;<br>
+Keep in mind the <a href=Surface.html#fill>Surface.fill()</a> method works just as well
+for drawing filled rectangles. In fact the <a href=Surface.html#fill>Surface.fill()</a>
+can be hardware accelerated when the moons are in alignement.
+</ul><br>&nbsp;<br>
+
 
 <hr>
 </body></html>

File docs/ref/pygame_mixer.html

 
 <a name=init><font size=+2><b>init
 </b></font><br><font size=+1><tt>
-pygame.mixer.init([freq, [size, [stereo]]]) -> None
+pygame.mixer.init([freq, [size, [stereo, [buffersize]]]]) -> None
 </tt></font><ul>
 Initializes the mixer module. Usually no arguments will be
 needed, the defaults are 22050 frequency data in stereo with
 signed 16bit data. The size argument can be 8 or 16 for unsigned
-data, or -8 or -16 for signed data.
+data, or -8 or -16 for signed data. The default buffersize is
+1024 samples, sometimes a larger value is required.
 <br>&nbsp;<br>
 On many platforms it is important that the display module is
 initialized before the audio. (that is, if the display will be
 
 <a name=pre_init><font size=+2><b>pre_init
 </b></font><br><font size=+1><tt>
-pygame.mixer.pre_init([freq, [size, [stereo]]]) -> None
+pygame.mixer.pre_init([freq, [size, [stereo, [buffersize]]]]) -> None
 </tt></font><ul>
 This routine is usefull when you want to customize the sound
 mixer playback modes. The values you pass will change the default
 static int clipline(int* pts, int left, int top, int right, int bottom);
 static void drawline(SDL_Surface* surf, Uint32 color, int startx, int starty, int endx, int endy);
 static void drawhorzline(SDL_Surface* surf, Uint32 color, int startx, int starty, int endx);
+static void drawvertline(SDL_Surface* surf, Uint32 color, int x1, int y1, int y2);
 static void draw_ellipse(SDL_Surface *dst, int x, int y, int rx, int ry, Uint32 color);
 static void draw_fillellipse(SDL_Surface *dst, int x, int y, int rx, int ry, Uint32 color);
 static void draw_fillpoly(SDL_Surface *dst, int *vx, int *vy, int n, Uint32 color);
     /*DOC*/    "pygame.draw.ellipse(Surface, color, Rect, width) -> Rect\n"
     /*DOC*/    "draw an ellipse on a surface\n"
     /*DOC*/    "\n"
-    /*DOC*/    "Draws a circular shape on the Surface. The given rectangle\n"
+    /*DOC*/    "Draws an elliptical shape on the Surface. The given rectangle\n"
     /*DOC*/    "is the area that the circle will fill. The width argument is\n"
     /*DOC*/    "the thickness to draw the outer edge. If width is zero then\n"
     /*DOC*/    "the ellipse will be filled.\n"
 	else
 		return RAISE(PyExc_TypeError, "invalid color argument");
 
+	if ( width < 0 )
+		return RAISE(PyExc_ValueError, "negative width");
+	if ( width > rect->w / 2 || width > rect->h / 2 )
+		return RAISE(PyExc_ValueError, "width greater than ellipse radius");
 
 	if(!PySurface_Lock(surfobj)) return NULL;
 
     /*DOC*/    "Draws a circular shape on the Surface. The given position\n"
     /*DOC*/    "is the center of the circle, and radius is the size. The width\n"
     /*DOC*/    "argument is the thickness to draw the outer edge. If width is\n"
-    /*DOC*/    "zero then the ellipse will be filled.\n"
+    /*DOC*/    "zero then the circle will be filled.\n"
     /*DOC*/    "\n"
     /*DOC*/    "The color argument can be either a RGB sequence or mapped color integer.\n"
     /*DOC*/    "\n"
 	else
 		return RAISE(PyExc_TypeError, "invalid color argument");
 
+	if ( radius < 0 )
+		return RAISE(PyExc_ValueError, "negative radius");
+	if ( width < 0 )
+		return RAISE(PyExc_ValueError, "negative width");
+	if ( width > radius )
+		return RAISE(PyExc_ValueError, "width greater than radius");
+
 
 	if(!PySurface_Lock(surfobj)) return NULL;
 
     /*DOC*/    "Draws a polygonal shape on the Surface. The given pointlist\n"
     /*DOC*/    "is the vertices of the polygon. The width argument is\n"
     /*DOC*/    "the thickness to draw the outer edge. If width is zero then\n"
-    /*DOC*/    "the ellipse will be filled.\n"
+    /*DOC*/    "the polygon will be filled.\n"
     /*DOC*/    "\n"
     /*DOC*/    "The color argument can be either a RGB sequence or mapped color integer.\n"
     /*DOC*/    "\n"
 		return ret;
 	}
 
-	
+
 	surf = PySurface_AsSurface(surfobj);
 
 	if(surf->format->BytesPerPixel <= 0 || surf->format->BytesPerPixel > 4)
     /*DOC*/    "pygame.draw.rect(Surface, color, Rect, width) -> Rect\n"
     /*DOC*/    "draws a polygon on a surface\n"
     /*DOC*/    "\n"
-    /*DOC*/    "Draws a polygonal shape on the Surface. The given Rect\n"
+    /*DOC*/    "Draws a rectangular shape on the Surface. The given Rect\n"
     /*DOC*/    "is the area of the rectangle. The width argument is\n"
     /*DOC*/    "the thickness to draw the outer edge. If width is zero then\n"
-    /*DOC*/    "the ellipse will be filled.\n"
+    /*DOC*/    "the rectangle will be filled.\n"
     /*DOC*/    "\n"
     /*DOC*/    "The color argument can be either a RGB sequence or mapped color integer.\n"
     /*DOC*/    "\n"
 		return 0;
 	if(pts[1] == pts[3])
 		drawhorzline(surf, color, pts[0], pts[1], pts[2]);
+	else if(pts[0] == pts[2])
+		drawvertline(surf, color, pts[0], pts[1], pts[3]);
 	else
 		drawline(surf, color, pts[0], pts[1], pts[2], pts[3]);
 	return 1;
 
 
 
+static int set_at(SDL_Surface* surf, int x, int y, Uint32 color)
+{
+	SDL_PixelFormat* format = surf->format;
+	Uint8* pixels = (Uint8*)surf->pixels;
+	Uint8* byte_buf, rgb[4];
+
+	if(x < surf->clip_rect.x || x >= surf->clip_rect.x + surf->clip_rect.w ||
+				y < surf->clip_rect.y || y >= surf->clip_rect.y + surf->clip_rect.h)
+	return 0;
+
+	switch(format->BytesPerPixel)
+	{
+		case 1:
+			*((Uint8*)pixels + y * surf->pitch + x) = (Uint8)color;
+			break;
+		case 2:
+			*((Uint16*)(pixels + y * surf->pitch) + x) = (Uint16)color;
+			break;
+		case 4:
+			*((Uint32*)(pixels + y * surf->pitch) + x) = color;
+/*			  *((Uint32*)(pixels + y * surf->pitch) + x) =
+				 ~(*((Uint32*)(pixels + y * surf->pitch) + x)) * 31;
+*/			  break;
+		default:/*case 3:*/
+			SDL_GetRGB(color, format, rgb, rgb+1, rgb+2);
+			byte_buf = (Uint8*)(pixels + y * surf->pitch) + x * 3;
+			*(byte_buf + (format->Rshift >> 3)) = rgb[0];
+			*(byte_buf + (format->Gshift >> 3)) = rgb[1];
+			*(byte_buf + (format->Bshift >> 3)) = rgb[2];
+			break;
+	}
+	return 1;
+}
+
 
 /*here's my sdl'ized version of bresenham*/
 static void drawline(SDL_Surface* surf, Uint32 color, int x1, int y1, int x2, int y2)
 	default: /*case 4*/
 		for(; pixel <= end; pixel+=4) {
 			*(Uint32*)pixel = color;
-		}break;
+/*			  *(Uint32*)pixel = ~(*(Uint32*)pixel)*31;
+*/		  }break;
 	}
 }
 
 static void drawhorzlineclip(SDL_Surface* surf, Uint32 color, int x1, int y1, int x2)
 {
+	if(y1 < surf->clip_rect.y || y1 >= surf->clip_rect.y + surf->clip_rect.h)
+		return;
+
+	if ( x2 < x1 )
+	{
+	 int temp = x1;
+	 x1 = x2; x2 = temp;
+	}
+
 	if(y1 < surf->clip_rect.y || y1 > surf->clip_rect.y + surf->clip_rect.h)
 		return;
 	x1 = max(x1, surf->clip_rect.x);
-	x2 = min(x2, surf->clip_rect.x + surf->clip_rect.w);
-	if(x2 - x1 < 1)
-		return;
-	drawhorzline(surf, color, x1, y1, x2);
+	x2 = min(x2, surf->clip_rect.x + surf->clip_rect.w-1);
+	if(x1 == x2)
+		set_at( surf, x1, y1, color);
+	else
+		drawhorzline(surf, color, x1, y1, x2);
 }
 
+static void drawvertline(SDL_Surface* surf, Uint32 color, int x1, int y1, int y2)
+{
+       Uint8   *pixel, *end;
+       Uint8   *colorptr;
+       Uint32  pitch = surf->pitch;
 
-static int set_at(SDL_Surface* surf, int x, int y, Uint32 color)
+       if(y1 == y2) return;
+
+       pixel = ((Uint8*)surf->pixels) + x1 * surf->format->BytesPerPixel;
+       if(y1 < y2)
+       {
+	   end	  = pixel + surf->pitch * y2;
+	   pixel += surf->pitch * y1;
+       }
+       else
+       {
+	   end	  = pixel + surf->pitch * y1;
+	   pixel += surf->pitch * y2;
+       }
+
+       switch(surf->format->BytesPerPixel)
+       {
+       case 1:
+	       for(; pixel <= end; pixel+=pitch) {
+		       *pixel = (Uint8)color;
+	       }break;
+       case 2:
+	       for(; pixel <= end; pixel+=pitch) {
+		       *(Uint16*)pixel = (Uint16)color;
+	       }break;
+       case 3:
+	       if(SDL_BYTEORDER == SDL_BIG_ENDIAN) color <<= 8;
+	       colorptr = (Uint8*)&color;
+	       for(; pixel <= end; pixel+=pitch) {
+		       pixel[0] = colorptr[0];
+		       pixel[1] = colorptr[1];
+		       pixel[2] = colorptr[2];
+	       }break;
+       default: /*case 4*/
+	       for(; pixel <= end; pixel+=pitch) {
+		       *(Uint32*)pixel = color;
+	       }break;
+       }
+}
+
+
+static void drawvertlineclip(SDL_Surface* surf, Uint32 color, int x1, int y1, int y2)
 {
-	SDL_PixelFormat* format = surf->format;
-	Uint8* pixels = (Uint8*)surf->pixels;
-	Uint8* byte_buf, rgb[4];
-
-	if(x < surf->clip_rect.x || x >= surf->clip_rect.x + surf->clip_rect.w ||
-				y < surf->clip_rect.y || y >= surf->clip_rect.y + surf->clip_rect.h)
-	return 0;
-
-	switch(format->BytesPerPixel)
+	if(x1 < surf->clip_rect.x || x1 >= surf->clip_rect.x + surf->clip_rect.w)
+	return;
+	if ( y2 < y1 )
 	{
-		case 1:
-			*((Uint8*)pixels + y * surf->pitch + x) = (Uint8)color;
-			break;
-		case 2:
-			*((Uint16*)(pixels + y * surf->pitch) + x) = (Uint16)color;
-			break;
-		case 4:
-			*((Uint32*)(pixels + y * surf->pitch) + x) = color;
-			break;
-		default:/*case 3:*/
-			SDL_GetRGB(color, format, rgb, rgb+1, rgb+2);
-			byte_buf = (Uint8*)(pixels + y * surf->pitch) + x * 3;
-			*(byte_buf + (format->Rshift >> 3)) = rgb[0];
-			*(byte_buf + (format->Gshift >> 3)) = rgb[1];
-			*(byte_buf + (format->Bshift >> 3)) = rgb[2];	
-			break;
+		int temp = y1;
+		y1 = y2; y2 = temp;
 	}
-	return 1;
+	y1 = max(y1, surf->clip_rect.y);
+	y2 = min(y2, surf->clip_rect.y + surf->clip_rect.h-1);
+	if(y2 - y1 < 1)
+		set_at( surf, x1, y1, color);
+	else
+		drawvertline(surf, color, x1, y1, y2);
 }
 
 
 	int xmj, xpj, ymi, ypi;
 	int xmk, xpk, ymh, yph;
 	
-#if 0
-	/* Special case for rx=0 - draw a vline */
-	if (rx==0)
-		return(vlineColor (dst, x, (Sint16)(y-ry), (Sint16)(y+ry), color));  
-	/* Special case for ry=0 - draw a hline */
-	if (ry==0)
-		return(hlineColor (dst, (Sint16)(x-rx), (Sint16)(x+rx), y, color));  
-	
-	/* Test bounding box */
-	x1=x-rx;
-	y1=y-ry;
-	x2=x+rx;
-	y2=y+ry;
-	if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
-		return(0);
+	if (rx==0 && ry==0) {  /* Special case - draw a single pixel */
+		set_at( dst, x, y, color);
+		return;
 	}
-#endif
-	
+	if (rx==0) { /* Special case for rx=0 - draw a vline */
+		drawvertlineclip( dst, color, x, (Sint16)(y-ry), (Sint16)(y+ry) );
+		return;
+	}
+	if (ry==0) { /* Special case for ry=0 - draw a hline */
+		drawhorzlineclip( dst, color, (Sint16)(x-rx), y, (Sint16)(x+rx) );
+		return;
+	}
+
+
 	/* Init vars */
 	oh = oi = oj = ok = 0xFFFF;
-	
-	/* Draw */
 	if (rx > ry) {
 		ix = 0;
 		iy = rx * 64;
 		do {
-			h = (ix + 32) >> 6;
-			i = (iy + 32) >> 6;
+			h = (ix + 16) >> 6;
+			i = (iy + 16) >> 6;
 			j = (h * ry) / rx;
 			k = (i * ry) / rx;
-			
+
 			if (((ok!=k) && (oj!=k)) || ((oj!=j) && (ok!=j)) || (k!=j)) {
 				xph=x+h-1;
 				xmh=x-h;
 				if (k>0) {
 					ypk=y+k-1;
 					ymk=y-k;
-					set_at(dst, xmh, ypk, color);
+					if(h > 0) {
+						set_at(dst, xmh, ypk, color);
+						set_at(dst, xmh, ymk, color);
+					}
 					set_at(dst, xph, ypk, color);
-					set_at(dst, xmh, ymk, color);
 					set_at(dst, xph, ymk, color);
-				/*} else {
-					set_at(dst, xmh, y, color);
-					set_at(dst, xph, y, color);
-				*/}
+				}
 				ok=k;
 				xpi=x+i-1;
 				xmi=x-i;
 					set_at(dst, xpi, ypj, color);
 					set_at(dst, xmi, ymj, color);
 					set_at(dst, xpi, ymj, color);
-				/*} else {
-					set_at(dst, xmi, y, color);
-					set_at(dst, xpi, y, color);
-				*/}
+				}
 				oj=j;
 			}
 			ix = ix + iy / rx;
 			iy = iy - ix / rx;
-			
+
 		} while (i > h);
 	} else {
 		ix = 0;
 			i = (iy + 32) >> 6;
 			j = (h * rx) / ry;
 			k = (i * rx) / ry;
-			
+
 			if (((oi!=i) && (oh!=i)) || ((oh!=h) && (oi!=h) && (i!=h))) {
 				xmj=x-j;
 				xpj=x+j-1;
 				if (i>0) {
 					ypi=y+i-1;
 					ymi=y-i;
-					set_at(dst, xmj, ypi,color);
-					set_at(dst, xpj, ypi,color);
-					set_at(dst, xmj, ymi,color);
-					set_at(dst, xpj, ymi,color);
-				/*} else {
-					set_at(dst, xmj, y,color);
-					set_at(dst, xpj, y,color);
-				*/}
+					if(j > 0) {
+						set_at(dst, xmj, ypi, color);
+						set_at(dst, xmj, ymi, color);
+					}
+					set_at(dst, xpj, ypi, color);
+					set_at(dst, xpj, ymi, color);
+				}
 				oi=i;
 				xmk=x-k;
 				xpk=x+k-1;
 					set_at(dst, xpk, yph, color);
 					set_at(dst, xmk, ymh, color);
 					set_at(dst, xpk, ymh, color);
-				/*} else {
-					set_at(dst, xmk, y, color);
-					set_at(dst, xpk, y, color);			 
-				*/}
+				}
 				oh=h;
 			}
 			ix = ix + iy / ry;
 	int ix, iy;
 	int h, i, j, k;
 	int oh, oi, oj, ok;
-	int xmh, xph;
-	int xmi, xpi;
-	int xmj, xpj;
-	int xmk, xpk;
-	
-	printf("  draw_fillellipse: pos=%d,%d r=%d,%d\n", x, y, rx, ry);
-#if 0
-	/* Special case for rx=0 - draw a vline */
-	if (rx==0) {
-		return(vlineColor (dst, x, (Sint16)(y-ry), (Sint16)(y+ry), color));  
+
+	if (rx==0 && ry==0) {  /* Special case - draw a single pixel */
+		set_at( dst, x, y, color);
+		return;
 	}
-	/* Special case for ry=0 - draw a hline */
-	if (ry==0) {
-		return(hlineColor (dst, (Sint16)(x-rx), (Sint16)(x+rx), y, color));  
+	if (rx==0) { /* Special case for rx=0 - draw a vline */
+		drawvertlineclip( dst, color, x, (Sint16)(y-ry), (Sint16)(y+ry) );
+		return;
 	}
-	
-	/* Test bounding box */
-	x1=x-rx;
-	y1=y-ry;
-	x2=x+rx;
-	y2=y+ry;
-	if (!(clipLine(dst,&x1,&y1,&x2,&y2))) {
-		return(0);
+	if (ry==0) { /* Special case for ry=0 - draw a hline */
+		drawhorzlineclip( dst, color, (Sint16)(x-rx), y, (Sint16)(x+rx) );
+		return;
 	}
-#endif
-	
+
 	/* Init vars */
 	oh = oi = oj = ok = 0xFFFF;
 	
 	/* Draw */
-	if (rx > ry) {
+	if (rx >= ry) {
 		ix = 0;
 		iy = rx * 64;
 		
 		do {
-			h = (ix + 32) >> 6;
-			i = (iy + 32) >> 6;
+			h = (ix + 16/*32*/) >> 6;
+			i = (iy + 16/*32*/) >> 6;
 			j = (h * ry) / rx;
 			k = (i * ry) / rx;
 			if ((ok!=k) && (oj!=k)) {
-				xph=x+h;
-				xmh=x-h;
-				/*if (k>0) {*/
-					drawhorzlineclip(dst, color, xmh, y+k, xph-1);
-					drawhorzlineclip(dst, color, xmh, y-k-1, xph-1);
-				/*} else {
-					drawhorzlineclip(dst, ~color, xmh,  y, xph);
-				}*/
+				drawhorzlineclip(dst, color, x-h, y+k, x+h-1);
+				drawhorzlineclip(dst, color, x-h, y-k-1, x+h-1);
 				ok=k;
 			}
 			if ((oj!=j) && (ok!=j) && (k!=j))  {
-				xmi=x-i;
-				xpi=x+i;
-				/*if (j>0) {*/
-					drawhorzlineclip(dst, color, xmi, y+j, xpi-1);
-					drawhorzlineclip(dst, color, xmi, y-j-1, xpi-1);
-				/*} else {
-					drawhorzlineclip(dst, ~color, xmi, y, xpi);
-				}*/
+				drawhorzlineclip(dst, color, x-i, y+j, x+i-1);
+				drawhorzlineclip(dst, color, x-i, y-j-1, x+i-1);
 				oj=j;
 			}
 			ix = ix + iy / rx;
 			k = (i * rx) / ry;
 			
 			if ((oi!=i) && (oh!=i)) {
-				xmj=x-j;
-				xpj=x+j; 
-				/*if (i>0) {*/
-					drawhorzlineclip(dst, color, xmj, y+i, xpj-1);
-					drawhorzlineclip(dst, color, xmj, y-i-1, xpj-1);
-				/*} else {
-					drawhorzlineclip(dst, color, xmj, y, xpj);
-				}*/
+				drawhorzlineclip(dst, color, x-j, y+i, x+j-1);
+				drawhorzlineclip(dst, color, x-j, y-i-1, x+j-1);
 				oi=i;
 			}
 			if ((oh!=h) && (oi!=h) && (i!=h)) {
-				xmk=x-k;
-				xpk=x+k;
-				/*if (h>0) {*/
-					drawhorzlineclip(dst, color, xmk, y+h, xpk-1);
-					drawhorzlineclip(dst, color, xmk, y-h-1, xpk-1);
-				/*} else {
-					drawhorzlineclip(dst, color, xmk, y, xpk-1);
-				}*/
+				drawhorzlineclip(dst, color, x+k, y+h, x+k-1);
+				drawhorzlineclip(dst, color, x+k, y-h-1, x+k-1);
 				oh=h;
 			}
 			
 #include "pygame.h"
 #include "mixer.h"
 
+#define MIX_DEFAULT_CHUNKSIZE	1024
 
 
 
 
 static int request_frequency = MIX_DEFAULT_FREQUENCY;
 static int request_size = MIX_DEFAULT_FORMAT;
-static int request_stereo = 1;
+static int request_stereo = MIX_DEFAULT_CHANNELS;
+static int request_chunksize = MIX_DEFAULT_CHUNKSIZE;
 
 Mix_Music** current_music;
 
 
 static PyObject* autoinit(PyObject* self, PyObject* arg)
 {
-	int freq, size, stereo;
+	int freq, size, stereo, chunk;
+	int i;
 	freq = request_frequency;
 	size = request_size;
 	stereo = request_stereo;
+	chunk = request_chunksize;
 
-	if(!PyArg_ParseTuple(arg, "|iii", &freq, &size, &stereo))
+	if(!PyArg_ParseTuple(arg, "|iiii", &freq, &size, &stereo, &chunk))
 		return NULL;
 	if(stereo)
 		stereo = 2;
 	else
 		stereo = 1;
 
+	/*make chunk a power of 2*/
+	for(i=0; 1<<i < chunk; ++i); //yes, semicolon on for loop
+	chunk = max(1<<i, 256);
+
 	if(!SDL_WasInit(SDL_INIT_AUDIO))
 	{
 		PyGame_RegisterQuit(autoquit);
 		if(SDL_InitSubSystem(SDL_INIT_AUDIO) == -1)
 			return PyInt_FromLong(0);
 
-		if(Mix_OpenAudio(freq, (Uint16)size, stereo, 1024) == -1)
+		if(Mix_OpenAudio(freq, (Uint16)size, stereo, chunk) == -1)
 		{
 			SDL_QuitSubSystem(SDL_INIT_AUDIO);
 			return PyInt_FromLong(0);
 
 
     /*DOC*/ static char doc_init[] =
-    /*DOC*/    "pygame.mixer.init([freq, [size, [stereo]]]) -> None\n"
+    /*DOC*/    "pygame.mixer.init([freq, [size, [stereo, [buffersize]]]]) -> None\n"
     /*DOC*/    "initialize mixer module\n"
     /*DOC*/    "\n"
     /*DOC*/    "Initializes the mixer module. Usually no arguments will be\n"
     /*DOC*/    "needed, the defaults are 22050 frequency data in stereo with\n"
     /*DOC*/    "signed 16bit data. The size argument can be 8 or 16 for unsigned\n"
-    /*DOC*/    "data, or -8 or -16 for signed data.\n"
+    /*DOC*/    "data, or -8 or -16 for signed data. The default buffersize is\n"
+    /*DOC*/    "1024 samples, sometimes a larger value is required.\n"
     /*DOC*/    "\n"
     /*DOC*/    "On many platforms it is important that the display module is\n"
     /*DOC*/    "initialized before the audio. (that is, if the display will be\n"
 	int value;
 
 	result = autoinit(self, arg);
+	if(!result)
+		return NULL;
 	value = PyObject_IsTrue(result);
 	Py_DECREF(result);
 	if(!value)
 
 
     /*DOC*/ static char doc_pre_init[] =
-    /*DOC*/    "pygame.mixer.pre_init([freq, [size, [stereo]]]) -> None\n"
+    /*DOC*/    "pygame.mixer.pre_init([freq, [size, [stereo, [buffersize]]]]) -> None\n"
     /*DOC*/    "presets the init default values\n"
     /*DOC*/    "\n"
     /*DOC*/    "This routine is usefull when you want to customize the sound\n"
 {
 	request_frequency = MIX_DEFAULT_FREQUENCY;
 	request_size = MIX_DEFAULT_FORMAT;
-	request_stereo = request_stereo;
+	request_stereo = MIX_DEFAULT_CHANNELS;
+	request_chunksize = MIX_DEFAULT_CHUNKSIZE;
 
-	if(!PyArg_ParseTuple(arg, "|iii", &request_frequency, &request_size,
-				&request_stereo))
+	if(!PyArg_ParseTuple(arg, "|iiii", &request_frequency, &request_size,
+				&request_stereo, &request_chunksize))
 		return NULL;
 
 	RETURN_NONE