Anonymous avatar Anonymous committed e047f85

advancemame scale2x

Comments (0)

Files changed (6)

 joystick src/joystick.c $(SDL)
 draw src/draw.c $(SDL)
 image src/image.c $(SDL)
-transform src/transform.c src/rotozoom.c $(SDL)
+transform src/transform.c src/rotozoom.c src/scale2x.c $(SDL)
 #macosx src/macosx.c src/setproctitle.c -Isrc
 
 
 # BREAK = change breaks existing code
 # BUG	= fixed a bug that was (or could have been) crashing
 
+November 12, 2002
+	AdvanceMAME Scale2X scaling now in transform.scale2x()
+
 October 22, 2002
     	mixer can queue sounds and music
 	channels can send finished event for sounds
 <a href=ref/pygame_transform.html#flip>pygame.transform.flip</a> - flips a surface on either axis<br>
 <a href=ref/pygame_transform.html#rotate>pygame.transform.rotate</a> - rotate a Surface<br>
 <a href=ref/pygame_transform.html#rotozoom>pygame.transform.rotozoom</a> - smoothly scale and/or rotate an image<br>
+<a href=ref/pygame_transform.html#scale2x>pygame.transform.scale2x</a> - doubles the size of the image with advanced scaling<br>
 <a href=ref/pygame_transform.html#scale>pygame.transform.scale</a> - scale a Surface to an arbitrary size<br>
 <!--ENDINDEX-->
 </ul>

docs/ref/pygame_transform.html

 scale a Surface to an arbitrary size</td></tr>
 
 
+<tr><td><a href=#scale2x>scale2x</a></td><td> -
+doubles the size of the image with advanced scaling</td></tr>
+
+
 </table>
 
 <hr>
 This transformation is not filtered.
 </ul><br>&nbsp;<br>
 
+<a name=scale2x><font size=+2><b>scale2x
+</b></font><br><font size=+1><tt>
+pygame.transform.scale2x(Surface) -> Surface
+</tt></font><ul>
+This will return a new image that is double the size of
+the original. It uses the AdvanceMAME Scale2X algorithm
+which does a 'jaggie-less' scale of bitmap graphics.
+<br>&nbsp;<br>
+This really only has an effect on simple images with solid
+colors. On photographic and antialiased images it will look
+like a regular unfiltered scale.
+</ul><br>&nbsp;<br>
+
 
 <hr>
 </body></html>
+/*
+    pygame - Python Game Library
+    Copyright (C) 2000-2001  Pete Shinners
+
+    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
+
+    Pete Shinners
+    pete@shinners.org
+*/
+
+/*
+   This implements the AdvanceMAME Scale2x feature found on this page,
+   http://advancemame.sourceforge.net/scale2x.html
+   
+   It is an incredibly simple and powerful image doubling routine that does
+   an astonishing job of doubling game graphic data while interpolating out
+   the jaggies. Congrats to the AdvanceMAME team, I'm very impressed and
+   surprised with this code!
+*/
+
+
+
+#include <SDL.h>
+#define MAX(a,b)    (((a) > (b)) ? (a) : (b))
+#define MIN(a,b)    (((a) < (b)) ? (a) : (b))
+
+
+#define READINT24(x)      ((x)[0]<<16 | (x)[1]<<8 | (x)[2]) 
+#define WRITEINT24(x, i)  {(x)[0]=i>>16; (x)[1]=(i>>8)&0xff; x[2]=i&0xff; }
+
+/*
+  this requires a destination surface already setup to be twice as
+  large as the source. oh, and formats must match too. this will just
+  blindly assume you didn't flounder.
+*/
+
+void scale2x(SDL_Surface *src, SDL_Surface *dst)
+{
+	int looph, loopw;
+	
+	Uint8* srcpix = (Uint8*)src->pixels;
+	Uint8* dstpix = (Uint8*)dst->pixels;
+
+	const int srcpitch = src->pitch;
+	const int dstpitch = dst->pitch;
+	const int width = src->w;
+	const int height = src->h;
+
+	switch(src->format->BytesPerPixel)
+	{
+	case 1: { 
+	    	Uint8 E0, E1, E2, E3, B, D, E, F, H;
+		for(looph = 0; looph < height; ++looph)
+		{
+			for(loopw = 0; loopw < width; ++ loopw)
+			{
+			    	B = *(Uint8*)(srcpix + (MAX(0,looph-1)*srcpitch) + (1*loopw));
+			    	D = *(Uint8*)(srcpix + (looph*srcpitch) + (1*MAX(0,loopw-1)));
+			    	E = *(Uint8*)(srcpix + (looph*srcpitch) + (1*loopw));
+			    	F = *(Uint8*)(srcpix + (looph*srcpitch) + (1*MIN(width-1,loopw+1)));
+			    	H = *(Uint8*)(srcpix + (MIN(height-1,looph+1)*srcpitch) + (1*loopw));
+				
+				E0 = D == B && B != F && D != H ? D : E;
+    	    	    	    	E1 = B == F && B != D && F != H ? F : E;
+				E2 = D == H && D != B && H != F ? D : E;
+				E3 = H == F && D != H && B != F ? F : E;
+
+				*(Uint8*)(dstpix + looph*2*dstpitch + loopw*2*1) = E0;
+				*(Uint8*)(dstpix + looph*2*dstpitch + (loopw*2+1)*1) = E1;
+				*(Uint8*)(dstpix + (looph*2+1)*dstpitch + loopw*2*1) = E2;
+				*(Uint8*)(dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*1) = E3;
+			}
+		}break;}
+	case 2: { 
+	    	Uint16 E0, E1, E2, E3, B, D, E, F, H;
+		for(looph = 0; looph < height; ++looph)
+		{
+			for(loopw = 0; loopw < width; ++ loopw)
+			{
+			    	B = *(Uint16*)(srcpix + (MAX(0,looph-1)*srcpitch) + (2*loopw));
+			    	D = *(Uint16*)(srcpix + (looph*srcpitch) + (2*MAX(0,loopw-1)));
+			    	E = *(Uint16*)(srcpix + (looph*srcpitch) + (2*loopw));
+			    	F = *(Uint16*)(srcpix + (looph*srcpitch) + (2*MIN(width-1,loopw+1)));
+			    	H = *(Uint16*)(srcpix + (MIN(height-1,looph+1)*srcpitch) + (2*loopw));
+				
+				E0 = D == B && B != F && D != H ? D : E;
+    	    	    	    	E1 = B == F && B != D && F != H ? F : E;
+				E2 = D == H && D != B && H != F ? D : E;
+				E3 = H == F && D != H && B != F ? F : E;
+
+				*(Uint16*)(dstpix + looph*2*dstpitch + loopw*2*2) = E0;
+				*(Uint16*)(dstpix + looph*2*dstpitch + (loopw*2+1)*2) = E1;
+				*(Uint16*)(dstpix + (looph*2+1)*dstpitch + loopw*2*2) = E2;
+				*(Uint16*)(dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*2) = E3;
+			}
+		}break;}
+	case 3: { 
+	    	int E0, E1, E2, E3, B, D, E, F, H;
+		for(looph = 0; looph < height; ++looph)
+		{
+			for(loopw = 0; loopw < width; ++ loopw)
+			{
+			    	B = READINT24(srcpix + (MAX(0,looph-1)*srcpitch) + (3*loopw));
+			    	D = READINT24(srcpix + (looph*srcpitch) + (3*MAX(0,loopw-1)));
+			    	E = READINT24(srcpix + (looph*srcpitch) + (3*loopw));
+			    	F = READINT24(srcpix + (looph*srcpitch) + (3*MIN(width-1,loopw+1)));
+			    	H = READINT24(srcpix + (MIN(height-1,looph+1)*srcpitch) + (3*loopw));
+				
+				E0 = D == B && B != F && D != H ? D : E;
+    	    	    	    	E1 = B == F && B != D && F != H ? F : E;
+				E2 = D == H && D != B && H != F ? D : E;
+				E3 = H == F && D != H && B != F ? F : E;
+
+				WRITEINT24((dstpix + looph*2*dstpitch + loopw*2*3), E0);
+				WRITEINT24((dstpix + looph*2*dstpitch + (loopw*2+1)*3), E1);
+				WRITEINT24((dstpix + (looph*2+1)*dstpitch + loopw*2*3), E2);
+				WRITEINT24((dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*3), E3);
+			}
+		}break;}
+	default: { /*case 4:*/
+	    	Uint32 E0, E1, E2, E3, B, D, E, F, H;
+		for(looph = 0; looph < height; ++looph)
+		{
+			for(loopw = 0; loopw < width; ++ loopw)
+			{
+			    	B = *(Uint32*)(srcpix + (MAX(0,looph-1)*srcpitch) + (4*loopw));
+			    	D = *(Uint32*)(srcpix + (looph*srcpitch) + (4*MAX(0,loopw-1)));
+			    	E = *(Uint32*)(srcpix + (looph*srcpitch) + (4*loopw));
+			    	F = *(Uint32*)(srcpix + (looph*srcpitch) + (4*MIN(width-1,loopw+1)));
+			    	H = *(Uint32*)(srcpix + (MIN(height-1,looph+1)*srcpitch) + (4*loopw));
+				
+				E0 = D == B && B != F && D != H ? D : E;
+    	    	    	    	E1 = B == F && B != D && F != H ? F : E;
+				E2 = D == H && D != B && H != F ? D : E;
+				E3 = H == F && D != H && B != F ? F : E;
+
+				*(Uint32*)(dstpix + looph*2*dstpitch + loopw*2*4) = E0;
+				*(Uint32*)(dstpix + looph*2*dstpitch + (loopw*2+1)*4) = E1;
+				*(Uint32*)(dstpix + (looph*2+1)*dstpitch + loopw*2*4) = E2;
+				*(Uint32*)(dstpix + (looph*2+1)*dstpitch + (loopw*2+1)*4) = E3;
+			}
+		}break;}
+	}
+}
+
 #include <math.h>
 
 
+void scale2x(SDL_Surface *src, SDL_Surface *dst);
+
+
+
 static SDL_Surface* newsurf_fromsurf(SDL_Surface* surf, int width, int height)
 {
 	SDL_Surface* newsurf;
 
 
 
+    /*DOC*/ static char doc_scale2x[] =
+    /*DOC*/    "pygame.transform.scale2x(Surface) -> Surface\n"
+    /*DOC*/    "doubles the size of the image with advanced scaling\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "This will return a new image that is double the size of\n"
+    /*DOC*/    "the original. It uses the AdvanceMAME Scale2X algorithm\n"
+    /*DOC*/    "which does a 'jaggie-less' scale of bitmap graphics.\n"
+    /*DOC*/    "\n"
+    /*DOC*/    "This really only has an effect on simple images with solid\n"
+    /*DOC*/    "colors. On photographic and antialiased images it will look\n"
+    /*DOC*/    "like a regular unfiltered scale.\n"
+    /*DOC*/ ;
+
+static PyObject* surf_scale2x(PyObject* self, PyObject* arg)
+{
+	PyObject *surfobj;
+	SDL_Surface* surf, *newsurf;
+	int width, height;
+
+	/*get all the arguments*/
+	if(!PyArg_ParseTuple(arg, "O!", &PySurface_Type, &surfobj))
+		return NULL;
+	surf = PySurface_AsSurface(surfobj);
+
+	width = surf->w * 2;
+	height = surf->h * 2;
+	
+	newsurf = newsurf_fromsurf(surf, width, height);
+	if(!newsurf) return NULL;
+
+	SDL_LockSurface(newsurf);
+	PySurface_Lock(surfobj);
+
+	scale2x(surf, newsurf);
+
+	PySurface_Unlock(surfobj);
+	SDL_UnlockSurface(newsurf);
+
+	return PySurface_New(newsurf);
+}
+
+
+
+
     /*DOC*/ static char doc_rotate[] =
     /*DOC*/    "pygame.transform.rotate(Surface, angle) -> Surface\n"
     /*DOC*/    "rotate a Surface\n"
 	{ "rotate", surf_rotate, 1, doc_rotate },
 	{ "flip", surf_flip, 1, doc_flip },
 	{ "rotozoom", surf_rotozoom, 1, doc_rotozoom},
-
+	{ "scale2x", surf_scale2x, 1, doc_scale2x},
+		
 	{ NULL, NULL }
 };
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.