Package-Name: snes9x
Gentoo-Package: games-emulation/snes9x
Homepage: http://www.snes9x.com/
# since 1.42, source is now in its own per-version directory
Source: http://www.lysator.liu.se/snes9x//(snes9x-\d+\.\d+(-\d+)?-src\.tar\.gz)/[\0-\377]*snes9x-(\d+.\d+)(?:-(\d+))?-src.tar.gz e:$1.($2?".$2":"") http://www.lysator.liu.se/snes9x/$0/snes9x-$0-src.tar.gz
Zap-Before-Install: 1
Repack:
	tar xzvfp "$(SOURCE)"
	test -d snes9x-"$(VERSION)" || mv snes9x-* snes9x-"$(VERSION)"
Compile:
#	cp -pf README* "$(PREFIX)/"
	cd snes9x && ./configure --prefix="$(PREFIX)" --without-glide --without-opengl --without-aido --with-joystick --with-assembler
	mv -f snes9x/Makefile snes9x/Makefile~
	sed 's/^\(OPTIMISE *=.*\) -O[0-9][0-9]*/\1 -O2 $(GCC_OPT_FLAGS)/' <snes9x/Makefile~ >snes9x/Makefile
	$(MAKE) -Csnes9x all SNES9XBIN=snes9x
	$(MAKE) -Csnes9x all SNES9XBIN=ssnes9x
	mkdir -p "$(PREFIX)"/bin
	cp -pf snes9x/{,s}snes9x "$(PREFIX)"/bin/
Install:
	chown root.console "$(PREFIX)"/bin/ssnes9x
	chmod 4750 "$(PREFIX)"/bin/ssnes9x
	$(MAKE) instbin BIN="snes9x ssnes9x"
Patch: <<EOT
######## begin hires-typo-fix.diff
--- ../snes9x-1.43-orig/snes9x/unix/svga.cpp	2004-12-31 07:15:46 +0900
+++ snes9x/unix/svga.cpp	2005-01-02 12:45:00 +0900
@@ -305,7 +305,7 @@
 	Settings.SixteenBit = FALSE;
     }
 
-    if (info->width >= 512 && info->height >= 578)
+    if (info->width >= 512 && info->height >= 478)
 	Settings.SupportHiRes = TRUE;
 
     if (!Settings.SixteenBit || info->width < 512 || info->height < 240)
######## end hires-typo-fix.diff
######## begin linux-2.6.17-joystick_h-fix.diff
--- ../snes9x-1.43-orig/snes9x/unix/unix.cpp	2004-12-31 07:15:47 +0900
+++ snes9x/unix/unix.cpp	2006-09-08 21:08:32 +0900
@@ -169,7 +169,9 @@
 
 #ifdef JOYSTICK_SUPPORT
 #if defined(__linux)
+#define class klass
 #include <linux/joystick.h>
+#undef class
 int js_fd [4] = {-1, -1, -1, -1};
 int js_map_button [4][16] = {
     {
######## end linux-2.6.17-joystick_h-fix.diff
######## begin loadsave-key-binding-fix.diff
--- ../snes9x-1.43-orig/snes9x/unix/x11.cpp	2004-12-31 07:15:47 +0900
+++ snes9x/unix/x11.cpp	2006-09-08 21:03:25 +0900
@@ -1213,26 +1213,26 @@
         // re-enable all sound channels
         Define(TOGGLE_SOUND, 8,         Alt(XK_F12), Ctrl(XK_F12));
         // numbered quicksaves
-        Define(WRITE_SAVE_NUM, 0,       XK_F1);
-        Define(WRITE_SAVE_NUM, 1,       XK_F2);
-        Define(WRITE_SAVE_NUM, 2,       XK_F3);
-        Define(WRITE_SAVE_NUM, 3,       XK_F4);
-        Define(WRITE_SAVE_NUM, 4,       XK_F5);
-        Define(WRITE_SAVE_NUM, 5,       XK_F6);
-        Define(WRITE_SAVE_NUM, 6,       XK_F7);
-        Define(WRITE_SAVE_NUM, 7,       XK_F8);
-        Define(WRITE_SAVE_NUM, 8,       XK_F9);
-        Define(WRITE_SAVE_NUM, 9,       XK_F10);
-        Define(LOAD_SAVE_NUM, 0,       Shift(XK_F1));
-        Define(LOAD_SAVE_NUM, 1,       Shift(XK_F2));
-        Define(LOAD_SAVE_NUM, 2,       Shift(XK_F3));
-        Define(LOAD_SAVE_NUM, 3,       Shift(XK_F4));
-        Define(LOAD_SAVE_NUM, 4,       Shift(XK_F5));
-        Define(LOAD_SAVE_NUM, 5,       Shift(XK_F6));
-        Define(LOAD_SAVE_NUM, 6,       Shift(XK_F7));
-        Define(LOAD_SAVE_NUM, 7,       Shift(XK_F8));
-        Define(LOAD_SAVE_NUM, 8,       Shift(XK_F9));
-        Define(LOAD_SAVE_NUM, 9,       Shift(XK_F10));
+        Define(WRITE_SAVE_NUM, 0,       Shift(XK_F1));
+        Define(WRITE_SAVE_NUM, 1,       Shift(XK_F2));
+        Define(WRITE_SAVE_NUM, 2,       Shift(XK_F3));
+        Define(WRITE_SAVE_NUM, 3,       Shift(XK_F4));
+        Define(WRITE_SAVE_NUM, 4,       Shift(XK_F5));
+        Define(WRITE_SAVE_NUM, 5,       Shift(XK_F6));
+        Define(WRITE_SAVE_NUM, 6,       Shift(XK_F7));
+        Define(WRITE_SAVE_NUM, 7,       Shift(XK_F8));
+        Define(WRITE_SAVE_NUM, 8,       Shift(XK_F9));
+        Define(WRITE_SAVE_NUM, 9,       Shift(XK_F10));
+        Define(LOAD_SAVE_NUM, 0,       XK_F1);
+        Define(LOAD_SAVE_NUM, 1,       XK_F2);
+        Define(LOAD_SAVE_NUM, 2,       XK_F3);
+        Define(LOAD_SAVE_NUM, 3,       XK_F4);
+        Define(LOAD_SAVE_NUM, 4,       XK_F5);
+        Define(LOAD_SAVE_NUM, 5,       XK_F6);
+        Define(LOAD_SAVE_NUM, 6,       XK_F7);
+        Define(LOAD_SAVE_NUM, 7,       XK_F8);
+        Define(LOAD_SAVE_NUM, 8,       XK_F9);
+        Define(LOAD_SAVE_NUM, 9,       XK_F10);
         // layer toggles
         Define(TOGGLE_LAYER,  0,       XK_1);
         Define(TOGGLE_LAYER,  1,       XK_2);
######## end loadsave-key-binding-fix.diff
######## begin window-height-fix.diff
--- ../snes9x-1.43-orig/snes9x/unix/x11.cpp	2004-12-31 07:15:47 +0900
+++ snes9x/unix/x11.cpp	2006-09-10 07:52:27 +0900
@@ -498,10 +498,11 @@
     XSetWindowAttributes attrib;
 
     attrib.background_pixel = BlackPixelOfScreen (GUI.screen);
+    /* height+2: gives us 239 -> 240 [really 241], 478 -> 480 */
     GUI.window = XCreateWindow (GUI.display, RootWindowOfScreen (GUI.screen),
 				(WidthOfScreen(GUI.screen) - GUI.window_width) / 2,
-				(HeightOfScreen(GUI.screen) - GUI.window_height) / 2,
-				GUI.window_width, GUI.window_height, 0, 
+				(HeightOfScreen(GUI.screen) - (GUI.window_height+2)) / 2,
+				GUI.window_width, GUI.window_height+2, 0, 
 				GUI.depth, InputOutput, GUI.visual, 
 				CWBackPixel, &attrib);
 
@@ -1782,7 +1783,9 @@
                  GUI.window_height != event.xconfigure.height))
             {
                 GUI.window_width = event.xconfigure.width;
-                GUI.window_height = event.xconfigure.height;
+		/* watch out for +2 in XCreateWindow */
+		if (event.xconfigure.height-2 != GUI.window_height)
+                    GUI.window_height = event.xconfigure.height;
                 IPPU.RenderThisFrame = TRUE;
                 IPPU.FrameSkip = Settings.SkipFrames;
                 SetupImage ();
######## end window-height-fix.diff
######## begin sound-capture.diff
--- ../snes9x-1.43-orig/snes9x/unix/svga.cpp	2005-01-02 12:45:00 +0900
+++ snes9x/unix/svga.cpp	2005-01-02 12:46:01 +0900
@@ -95,6 +95,7 @@
 #include <sys/io.h>
 #include <stdlib.h>
 #include <signal.h>
+#include <fcntl.h>
 
 #include <vga.h>
 #include <vgagl.h>
@@ -130,6 +131,8 @@
 
 extern uint32 joypads [5];
 
+extern int sound_copy_fd;
+
 #define ATTRCON_ADDR	0x3c0
 #define MISC_ADDR	0x3c2
 #define VGAENABLE_ADDR	0x3c3
@@ -629,6 +632,24 @@
 		Settings.SkipFrames++;
 	}
     }
+
+    if (KEY_PRESS(SCANCODE_R)
+     && (KEY_DOWN(SCANCODE_CONTROL) | KEY_DOWN(SCANCODE_LEFTCONTROL))
+    ) {
+	if (sound_copy_fd >= 0) {
+	    close(sound_copy_fd);
+	}
+	sound_copy_fd = open("audio.raw", O_WRONLY | O_CREAT | O_TRUNC, 0666);
+    }
+
+    if (KEY_PRESS(SCANCODE_S)
+     && (KEY_DOWN(SCANCODE_CONTROL) | KEY_DOWN(SCANCODE_LEFTCONTROL))
+    ) {
+	if (sound_copy_fd >= 0) {
+	    close(sound_copy_fd);
+	    sound_copy_fd = -1;
+	}
+    }
 	
     memcpy (prev_keystate, keystate, sizeof (prev_keystate));
 }
--- ../snes9x-1.43-orig/snes9x/unix/unix.cpp	2004-12-31 07:15:47 +0900
+++ snes9x/unix/unix.cpp	2005-01-02 12:56:16 +0900
@@ -222,6 +222,8 @@
 void InitTimer ();
 void *S9xProcessSound (void *);
 
+int sound_copy_fd = -1;
+
 char *rom_filename = NULL;
 char *snapshot_filename = NULL;
 char *SDD1_pack = NULL;
@@ -1439,6 +1441,9 @@
 	if (ALsetchannels(al_config, channels)) {
 		perror("ERROR with ALsetchannels");
 	}
+	if (sound_copy_fd >= 0) {
+	    write(sound_copy_fd, audio_buf, buf_size);
+	}
 
 	channels = ALgetchannels(al_config);
 #  if 0
@@ -2022,6 +2027,9 @@
             I = write (so.sound_fd, (char *) Buf + byte_offset, I);
             if (I > 0)
             {
+                if (sound_copy_fd >= 0) {
+                    write(sound_copy_fd, (char *) Buf + byte_offset, I);
+                }
                 bytes_to_write -= I;
                 byte_offset += I;
                 byte_offset &= SOUND_BUFFER_SIZE_MASK; /* wrap */
--- ../snes9x-1.43-orig/snes9x/unix/x11.cpp	2004-12-31 07:15:47 +0900
+++ snes9x/unix/x11.cpp	2005-01-02 12:50:18 +0900
@@ -191,6 +191,8 @@
 GUIData GUI;
 extern uint32 joypads [5];
 
+extern int sound_copy_fd;
+
 #if 0
 QApplication *app;
 Snes9xGUI *gui;
@@ -1335,6 +1337,22 @@
         {
             int key = XKeycodeToKeysym (GUI.display, event.xkey.keycode, 0);
             
+	    if (event.type == KeyPress && (event.xkey.state & ControlMask)) {
+		if (key == XK_r) {
+		    if (sound_copy_fd >= 0) {
+			close(sound_copy_fd);
+		    }
+		    sound_copy_fd = open("audio.raw",
+					 O_WRONLY | O_CREAT | O_TRUNC, 0666);
+		    break;
+		} else if (key == XK_s) {
+		    if (sound_copy_fd >= 0) {
+			close(sound_copy_fd);
+			sound_copy_fd = -1;
+		    }
+		}
+		break;
+	    }
             const KeyboardSetup::Keyfunction& func
                 = KBSetup.GetKeyFunction(key, event.xkey.state);
             switch(func.func)
######## end sound-capture.diff
######## rest is local stuff
--- ../snes9x-1.43-orig/snes9x/unix/svga.cpp	2005-01-02 12:46:01 +0900
+++ snes9x/unix/svga.cpp	2005-01-02 12:58:27 +0900
@@ -1,3 +1,4 @@
+//#include <sys/mman.h>  // for screen grabs --AC
 /*******************************************************************************
   Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
  
@@ -123,6 +124,7 @@
 static char prev_keystate [128] = "";
 static bool8 restore_modex = FALSE;
 static uint8 *DeltaScreen = NULL;
+static uint8 *InterpolateScreen = NULL;
 static vga_modeinfo *info = NULL;
 static uint32 video_page_size = 64 * 1024;
 static uint32 selected_video_page = ~0;
@@ -180,8 +182,18 @@
     {320, 200, G320x200x64K}, // 5
     {640, 480, G640x480x64K}, // 6
     {800, 600, G800x600x64K}, // 7
+    {320, 240, G320x240x64K}, // 8
+    {512, 480, G512x480x256}, // 9
+    {512, 480, G512x480x64K}, // 10
+    {256, 240, -1          }, // 11 (custom 8-bit mode, lo-res doublescan)
+    {256, 240, -1          }, // 12 (custom 16-bit mode, lo-res doublescan)
+    {320, 256, -1          }, // 13 (custom 8-bit mode, lo-res)
+    {320, 256, -1          }, // 14 (custom 16-bit mode, lo-res)
 };
 
+static void TVMode(int width, int height);
+
+
 int S9xMinCommandLineArgs ()
 {
     return (2);
@@ -282,7 +294,18 @@
 	else
 	    mode = 2;
     }
-    info = vga_getmodeinfo (modes [mode].mode);
+    if (mode >= 11) {
+	static vga_modeinfo modeinfo;
+	modeinfo.flags = CAPABLE_LINEAR;
+	modeinfo.width = modes [mode].width;
+	modeinfo.height = modes [mode].height;
+	modeinfo.bytesperpixel = (mode & 1) ? 1 : 2;
+	modeinfo.linewidth = modes [mode].width * modeinfo.bytesperpixel;
+	info = &modeinfo;
+    }
+    else
+	info = vga_getmodeinfo (modes [mode].mode);
+
     if (info->flags & IS_MODEX)
 	planar = 1;
 
@@ -320,11 +343,12 @@
 	GFX.Screen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);
 	GFX.SubScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);
 	DeltaScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);
+	InterpolateScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);
 	GFX.ZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);
 	GFX.SubZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);
 
-	if (!GFX.Screen || !GFX.SubScreen || !DeltaScreen || 
-	    !GFX.ZBuffer || !GFX.SubZBuffer)
+	if (!GFX.Screen || !GFX.SubScreen || !DeltaScreen ||
+	    !InterpolateScreen || !GFX.ZBuffer || !GFX.SubZBuffer)
 	{
 	    fprintf (stdout, "Cannot allocate screen buffer.\n");
 	    S9xExit ();
@@ -338,8 +362,9 @@
 	GFX.SubScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);
 	GFX.ZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);
 	GFX.SubZBuffer = (uint8 *) malloc ((GFX.Pitch >> 1) * IMAGE_HEIGHT);
+	DeltaScreen = (uint8 *) malloc (GFX.Pitch * IMAGE_HEIGHT);
 
-	if (!GFX.Screen || !GFX.SubScreen)
+	if (!GFX.Screen || !GFX.SubScreen || !DeltaScreen)
 	{
 	    fprintf (stdout, "Cannot allocate screen buffer.\n");
 	    S9xExit ();
@@ -378,6 +403,22 @@
     sig2handler.sa_flags = 0;
     sigaction (SIGUSR1, &sig1handler, &oldsig1handler);
     sigaction (SIGUSR2, &sig2handler, &oldsig2handler);
+
+    /* Custom mode settings. --AC */
+    /* Note that the pixel clock in line 1 is set slightly higher
+     * than that in line 2 to set a preference order (higher clock
+     * values are tried first).  mmt1 gives a nearly-full-screen
+     * display on my monitor, but is somewhat tweaked; mmt2 gives a
+     * slightly smaller display but comes straight from the VESA
+     * timings. */
+    /* note: 0x20 == DOUBLESCAN */
+    vga_addtiming(12589, 256,304,336,352, 240,242,243,252, 0x20);
+    vga_addtiming(12588, 256,304,352,400, 240,245,247,263, 0x20);
+    vga_addtiming(12588, 320,336,368,384, 256,261,263,279, 0);
+    modes[11].mode = vga_addmode(256, 240, 256, 256, 1);
+    modes[12].mode = vga_addmode(256, 240, 65536, 512, 2);
+    modes[13].mode = vga_addmode(320, 256, 256, 320, 1);
+    modes[14].mode = vga_addmode(320, 256, 65536, 640, 2);
 }
 
 void S9xDeinitDisplay ()
@@ -544,6 +585,7 @@
     if (fn > 0)
     {
 	if (!KEY_DOWN(SCANCODE_LEFTALT) && !KEY_DOWN(SCANCODE_LEFTSHIFT) &&
+	    !KEY_DOWN(SCANCODE_RIGHTSHIFT) &&
 	    !KEY_DOWN(SCANCODE_CONTROL) && !KEY_DOWN(SCANCODE_LEFTCONTROL))
 	{
 	    if (fn == 11)
@@ -660,10 +702,30 @@
 
 void S9xPutImage (int width, int height)
 {
+    uint8 *source;
+    int source_pitch;
+    int pitch = width * (Settings.SixteenBit ? 2 : 1);
     int y_buff;
     int y_start;
     int y_end;
-    int x_start = (screen_width - width) >> 1;
+    int x_start;
+
+    if (interpolation && height < 240)
+    {
+	TVMode(width, height);
+	width = 512;
+	height <<= 1;
+	pitch = 1024;
+	source = InterpolateScreen;
+	source_pitch = 514*2;
+    }
+    else
+    {
+	source = GFX.Screen;
+	source_pitch = GFX.Pitch;
+    }
+
+    x_start = (screen_width - width) >> 1;
     if (screen_height >= height)
     {
 	y_start = (screen_height - height) >> 1;
@@ -676,28 +738,30 @@
 	y_end = screen_height;
 	y_buff = (height - screen_height) >> 1;
     }
-	
+
     if (planar)
-	vga_copytoplanar256 (GFX.Screen + y_buff * GFX.Pitch,
+	vga_copytoplanar256 (source + y_buff * source_pitch,
 			     IMAGE_WIDTH,
 			     y_start * screen_pitch + x_start / 4,
 			     screen_pitch, width, y_end - y_start);
     else
     {
-	if (screen_pitch == width && screen_height >= height)
+	if (screen_width == width && screen_height >= height)
 	{
 #if 0
 	    memcpy (vga_getgraphmem () + screen_pitch * y_start,
-		    GFX.Screen, width * height);
+		    source, width * height);
 #else
 	    register uint32 *s = (uint32 *) (vga_getgraphmem () + screen_pitch * y_start);
 	    register uint32 *o = (uint32 *) DeltaScreen;
-	    register uint32 *n = (uint32 *) GFX.Screen;
-	    uint32 *end = (uint32 *) (GFX.Screen + width * height);
+	    register uint32 *n = (uint32 *) source;
+	    uint32 *end = (uint32 *) (source + pitch * height);
+//this does screen grabs--AC
+//{static int mapped=0;static uint32*filepos;if(!mapped){int fd=open("imagefile",O_RDWR|O_CREAT|O_TRUNC,0666);ftruncate(fd,1<<20);filepos=mmap(0,1<<20,PROT_READ|PROT_WRITE,MAP_FILE|MAP_SHARED,fd,0);mapped=1;}s=filepos+screen_pitch*y_start;}
 	    do
 	    {
 		if (*n != *o)
-		    *o = *s = *n;
+		    *s = *o = *n;
 
 		o++;
 		s++;
@@ -717,39 +781,68 @@
 		
 		x_fraction = (SNES_WIDTH * 0x10000) / width;
 		y_fraction = (SNES_HEIGHT_EXTENDED * 0x10000) / height;
-		
-		for (int y = 0; y < height; y++)
+
+		if (Settings.SixteenBit)
 		{
-		    register uint8 *d = (uint8 *) vga_getgraphmem () + y * screen_pitch;
-		    register uint8 *s = GFX.Screen + yy * GFX.Pitch;
-		    y_error += y_fraction;
-		    while (y_error >= 0x10000)
+		    for (int y = 0; y < height; y++)
 		    {
-			yy++;
-			y_error -= 0x10000;
+			register uint16 *d = (uint16 *) ((uint8 *) vga_getgraphmem () + y * screen_pitch);
+			register uint16 *s = (uint16 *) (source + yy * source_pitch);
+			y_error += y_fraction;
+			while (y_error >= 0x10000)
+			{
+			    yy++;
+			    y_error -= 0x10000;
+			}
+			x_error = 0;
+			for (register int x = 0; x < width; x++)
+			{
+			    *d++ = *s;
+			    x_error += x_fraction;
+
+			    while (x_error >= 0x10000)
+			    {
+				s++;
+				x_error -= 0x10000;
+			    }
+			}
 		    }
-		    x_error = 0;
-		    for (register int x = 0; x < width; x++)
+		}
+		else
+		{
+		    for (int y = 0; y < height; y++)
 		    {
-			*d++ = *s;
-			x_error += x_fraction;
-
-			while (x_error >= 0x10000)
+			register uint8 *d = (uint8 *) vga_getgraphmem () + y * screen_pitch;
+			register uint8 *s = source + yy * source_pitch;
+			y_error += y_fraction;
+			while (y_error >= 0x10000)
 			{
-			    s++;
-			    x_error -= 0x10000;
+			    yy++;
+			    y_error -= 0x10000;
+			}
+			x_error = 0;
+			for (register int x = 0; x < width; x++)
+			{
+			    *d++ = *s;
+			    x_error += x_fraction;
+
+			    while (x_error >= 0x10000)
+			    {
+				s++;
+				x_error -= 0x10000;
+			    }
 			}
 		    }
 		}
 	    }
 	    else
 	    {
-#if 0
-		uint8 *s = GFX.Screen + GFX.Pitch * y_buff;
+#if 1 /* gl_putbox makes my screen go diagonal -- AC */
+		uint8 *s = source + source_pitch * y_buff;
 		uint8 *p = vga_getgraphmem () + screen_pitch * y_start +
 			  x_start;
-		for (int y = y_start; y < y_end; y++, s += GFX.Pitch, p += screen_pitch)
-		    memcpy (p, s, width);
+		for (int y = y_start; y < y_end; y++, s += source_pitch, p += screen_pitch)
+		    memcpy (p, s, pitch);
 #else
 		gl_putbox (0, 0, width * 2, height * 2, GFX.Screen);
 #endif
@@ -906,9 +999,153 @@
     return (FALSE);
 }
 
+bool JustifierOffscreen()
+{
+  return (TRUE);
+}
+
+void JustifierButtons(uint32& /* justifiers */)
+{
+}
+
 void S9xMessage (int /* type */, int /* number */, const char *message)
 {
     fprintf (stderr, "%s\n", message);
 }
+
+static void TVMode (int width, int height)
+{
+    uint8 *nextLine, *srcPtr, *deltaPtr, *finish;
+    uint8 *dstPtr;
+    uint32 colorMask = ~(RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 16));
+    uint32 lowPixelMask = RGB_LOW_BITS_MASK;
+
+    srcPtr = GFX.Screen;
+    deltaPtr = DeltaScreen;
+    dstPtr = InterpolateScreen;
+    nextLine = InterpolateScreen + 514*2;
+
+    if (width == 256)
+    {
+	do
+	{
+	    uint32 *bP = (uint32 *) srcPtr;
+	    uint32 *xP = (uint32 *) deltaPtr;
+	    uint32 *dP = (uint32 *) dstPtr;
+	    uint32 *nL = (uint32 *) nextLine;
+	    uint32 currentPixel;
+	    uint32 nextPixel;
+	    uint32 currentDelta;
+	    uint32 nextDelta;
+
+	    finish = (uint8 *) bP + ((width + 2) << 1);
+	    nextPixel = *bP++;
+	    nextDelta = *xP++;
+
+	    do
+	    {
+		currentPixel = nextPixel;
+		currentDelta = nextDelta;
+		nextPixel = *bP++;
+		nextDelta = *xP++;
+
+		if ((nextPixel != nextDelta) || (currentPixel != currentDelta))
+		{
+		    uint32 colorA, colorB, product, darkened;
+
+		    *(xP - 2) = currentPixel;
+#ifdef LSB_FIRST
+		    colorA = currentPixel & 0xffff;
+#else
+		    colorA = (currentPixel & 0xffff0000) >> 16;
+#endif
+
+#ifdef LSB_FIRST
+		    colorB = (currentPixel & 0xffff0000) >> 16;
+		    *(dP) = product = colorA |
+				      ((((colorA & colorMask) >> 1) +
+					((colorB & colorMask) >> 1) +
+					(colorA & colorB & lowPixelMask)) << 16);
+#else
+		    colorB = currentPixel & 0xffff;
+		    *(dP) = product = (colorA << 16) | 
+				      (((colorA & colorMask) >> 1) +
+				       ((colorB & colorMask) >> 1) +
+				       (colorA & colorB & lowPixelMask));
+#endif
+		    darkened = (product = ((product & colorMask) >> 1));
+		    darkened += (product = ((product & colorMask) >> 1));
+		    darkened += (product & colorMask) >> 1;
+		    *(nL) = darkened;
+
+#ifdef LSB_FIRST
+		    colorA = nextPixel & 0xffff;
+		    *(dP + 1) = product = colorB |
+					  ((((colorA & colorMask) >> 1) +
+					    ((colorB & colorMask) >> 1) +
+					    (colorA & colorB & lowPixelMask)) << 16);
+#else
+		    colorA = (nextPixel & 0xffff0000) >> 16;
+		    *(dP + 1) = product = (colorB << 16) | 
+					   (((colorA & colorMask) >> 1) +
+					    ((colorB & colorMask) >> 1) + 
+					    (colorA & colorB & lowPixelMask));
+#endif
+		    darkened = (product = ((product & colorMask) >> 1));
+		    darkened += (product = ((product & colorMask) >> 1));
+		    darkened += (product & colorMask) >> 1;
+		    *(nL + 1) = darkened;
+		}
+
+		dP += 2;
+		nL += 2;
+	    }
+	    while ((uint8 *) bP < finish);
+
+	    deltaPtr += GFX.Pitch;
+	    srcPtr += GFX.Pitch;
+	    dstPtr += 514*2 * 2;
+	    nextLine += 514*2 * 2;
+	}
+	while (--height);
+    }
+    else
+    {
+	do
+	{
+	    uint32 *bP = (uint32 *) srcPtr;
+	    uint32 *xP = (uint32 *) deltaPtr;
+	    uint32 *dP = (uint32 *) dstPtr;
+	    uint32 currentPixel;
+
+	    finish = (uint8 *) bP + ((width + 2) << 1);
+
+	    do
+	    {
+		currentPixel = *bP++;
+
+		if (currentPixel != *xP++)
+		{
+		    uint32 product, darkened;
+
+		    *(xP - 1) = currentPixel;
+		    *dP = currentPixel;
+		    darkened = (product = ((currentPixel & colorMask) >> 1));
+		    darkened += (product = ((product & colorMask) >> 1));
+		    darkened += (product & colorMask) >> 1;
+		    *(uint32 *) ((uint8 *) dP + 514*2) = darkened;
+		}
+
+		dP++;
+	    }
+	    while ((uint8 *) bP < finish);
+
+	    deltaPtr += GFX.Pitch;
+	    srcPtr += GFX.Pitch;
+	    dstPtr += 514*2 * 2;
+	}
+	while (--height);
+    }
+}
 #endif
 
EOT

/pkg/snes9x/
/usr/bin/snes9x
/usr/bin/ssnes9x
