changeset 4799:a0e096916474

Rewrote test program for shaped windows. It definitely displays recognizable pictures now, but the resizing and shaping functionality isn't behaving correctly, possibly due to a miscalculation of alpha values.
author Eli Gottlieb <eligottlieb@gmail.com>
date Sun, 18 Jul 2010 21:31:22 -0400
parents 980614a70cfc
children 6d4be626225f
files src/video/SDL_shape.c test/Makefile.in test/README test/testeyes.c test/testeyes_bitmap.h test/testeyes_mask_bitmap.h test/testshape.c
diffstat 7 files changed, 179 insertions(+), 282 deletions(-) [+]
line wrap: on
line diff
--- a/src/video/SDL_shape.c	Sun Jul 18 15:15:05 2010 -0400
+++ b/src/video/SDL_shape.c	Sun Jul 18 21:31:22 2010 -0400
@@ -63,14 +63,17 @@
 	Uint32 bitmap_pixel;
 	if(SDL_MUSTLOCK(shape))
 		SDL_LockSurface(shape);
-	for(x = 0;x<shape->w;x++)
-		for(y = 0;y<shape->h;y++) {
-			pixel = (Uint8 *)(shape->pixels) + (y*shape->pitch) + (x*shape->format->BytesPerPixel);
+	pixel = (Uint8*)shape->pixels;
+	for(y = 0;y<shape->h;y++) {
+		pixel = (Uint8 *)(shape->pixels) + y * shape->pitch;
+		for(x=0;x<shape->w;x++) {
 			alpha = 0;
 			SDL_GetRGBA(*(Uint32*)pixel,shape->format,&r,&g,&b,&alpha);
 			bitmap_pixel = y*shape->w + x;
 			bitmap[bitmap_pixel / ppb] |= (alpha >= alphacutoff ? value : 0) << ((ppb - 1) - (bitmap_pixel % ppb));
+			pixel += shape->format->BytesPerPixel;
 		}
+	}
 	if(SDL_MUSTLOCK(shape))
 		SDL_UnlockSurface(shape);
 }
--- a/test/Makefile.in	Sun Jul 18 15:15:05 2010 -0400
+++ b/test/Makefile.in	Sun Jul 18 21:31:22 2010 -0400
@@ -7,7 +7,7 @@
 CFLAGS  = @CFLAGS@
 LIBS	= @LIBS@
 
-TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testatomic$(EXE) testaudioinfo$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testdraw2$(EXE) testdyngles$(EXE) testdyngl$(EXE) testerror$(EXE) testeyes$(EXE) testfile$(EXE) testfill$(EXE) testgamma$(EXE) testgl2$(EXE) testgles$(EXE) testgl$(EXE) testhaptic$(EXE) testhread$(EXE) testiconv$(EXE) testime$(EXE) testintersections$(EXE) testjoystick$(EXE) testkeys$(EXE) testloadso$(EXE) testlock$(EXE) testmmousetablet$(EXE) testmultiaudio$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testpower$(EXE) testresample$(EXE) testsem$(EXE) testsprite2$(EXE) testsprite$(EXE) testspriteminimal$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm2$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE)
+TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testalpha$(EXE) testatomic$(EXE) testaudioinfo$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcursor$(EXE) testdraw2$(EXE) testdyngles$(EXE) testdyngl$(EXE) testerror$(EXE) testfile$(EXE) testfill$(EXE) testgamma$(EXE) testgl2$(EXE) testgles$(EXE) testgl$(EXE) testhaptic$(EXE) testhread$(EXE) testiconv$(EXE) testime$(EXE) testintersections$(EXE) testjoystick$(EXE) testkeys$(EXE) testloadso$(EXE) testlock$(EXE) testmmousetablet$(EXE) testmultiaudio$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testpower$(EXE) testresample$(EXE) testsem$(EXE) testshape$(EXE) testsprite2$(EXE) testsprite$(EXE) testspriteminimal$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm2$(EXE) testwm$(EXE) threadwin$(EXE) torturethread$(EXE)
 
 all: Makefile $(TARGETS)
 
@@ -62,9 +62,6 @@
 testerror$(EXE): $(srcdir)/testerror.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
 
-testeyes$(EXE): $(srcdir)/testeyes.c
-	$(CC) -o $@ $? -std=c99 $(CFLAGS) $(LIBS)
-
 testfile$(EXE): $(srcdir)/testfile.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
 
@@ -113,6 +110,9 @@
 testsem$(EXE): $(srcdir)/testsem.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
 
+testshape$(EXE): $(srcdir)/testshape.c
+	$(CC) -o $@ $? -std=c99 $(CFLAGS) $(LIBS)
+
 testspriteminimal$(EXE): $(srcdir)/testspriteminimal.c
 	$(CC) -o $@ $? $(CFLAGS) $(LIBS) @MATHLIB@
 
--- a/test/README	Sun Jul 18 15:15:05 2010 -0400
+++ b/test/README	Sun Jul 18 21:31:22 2010 -0400
@@ -12,7 +12,6 @@
 	testcursor	Tests custom mouse cursor
 	testdyngl	Tests dynamically loading OpenGL library
 	testerror	Tests multi-threaded error handling
-	testeyes	Tests shaped windows
 	testfile	Tests RWops layer
 	testgamma	Tests video device gamma ramp
 	testgl		A very simple example of using OpenGL with SDL
@@ -29,6 +28,7 @@
 	testpalette	Tests palette color cycling
 	testplatform	Tests types, endianness and cpu capabilities
 	testsem		Tests SDL's semaphore implementation
+	testshape	Tests shaped windows
 	testsprite	Example of fast sprite movement on the screen
 	testsprite2	Improved version of testsprite
 	testtimer	Test the timer facilities
--- a/test/testeyes.c	Sun Jul 18 15:15:05 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,232 +0,0 @@
-#include <stdlib.h>
-#include <math.h>
-#include <SDL_events.h>
-#include <SDL_rect.h>
-#include <SDL_pixels.h>
-#include <SDL_video.h>
-#include <SDL_shape.h>
-#include "testeyes_bitmap.h"
-#include "testeyes_mask_bitmap.h"
-
-/* The following code for the calculation of pupil positions has been taken and rewritten from the original xeyes.  The
-   copyright notice is included as follows, and the code is now under the same license as the rest of this file. */
-/*
-
-Copyright (c) 1991  X Consortium
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
-OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of the X Consortium shall
-not be used in advertising or otherwise to promote the sale, use or
-other dealings in this Software without prior written authorization
-from the X Consortium.
-
-*/
-# define NUM_EYES	2
-# define EYE_X(n)	((n) * 2.0)
-# define EYE_Y(n)	(0.0)
-# define EYE_THICK	(0.175)	/* thickness of eye rim */
-# define EYE_OFFSET	(0.1)	/* padding between eyes */
-# define EYE_WIDTH	(2.0 - (EYE_THICK + EYE_OFFSET) * 2)
-# define EYE_HEIGHT	EYE_WIDTH
-# define EYE_HWIDTH	(EYE_WIDTH / 2.0)
-# define EYE_HHEIGHT	(EYE_HEIGHT / 2.0)
-# define BALL_WIDTH	(0.3)
-# define BALL_HEIGHT	BALL_WIDTH
-# define BALL_PAD	(0.05)
-# define BALL_DIST	((EYE_WIDTH - BALL_WIDTH) / 2.0 - BALL_PAD)
-
-SDL_Point computePupil (int num,SDL_Point mouse) {
-	double dx = mouse.x - EYE_X(num);
-	double dy = mouse.y - EYE_Y(num);
-	double cx = 0.0,cy = 0.0;
-	if(dx == 0 && dy == 0) {
-		cx = EYE_X(num);
-		cy = EYE_Y(num);
-	}
-	else {
-		double angle = atan2((double)dy,(double)dx);
-		double cosa = cos(angle);
-		double sina = sin(angle);
-		double hypotenuse = hypot(EYE_HHEIGHT * cosa, EYE_HWIDTH * sina);
-		double dist = BALL_DIST * hypot((EYE_HWIDTH * EYE_HHEIGHT) * cosa / hypotenuse,
-					        (EYE_HWIDTH * EYE_HHEIGHT) * sina / hypotenuse);
-		if(dist > hypot((double)dx,(double)dy)) {
-			cx = dx + EYE_X(num);
-			cy = dy + EYE_Y(num);
-		}
-		else {
-			cx = dist * cosa + EYE_X(num);
-			cy = dist * sina + EYE_Y(num);
-		}
-	}
-	SDL_Point ret = {cx,cy};
-	return ret;
-}
-
-/* Here begins the code exclusively and entirely written by Eli Gottlieb in May 2010. */
-typedef struct {
-	SDL_Rect left;
-	SDL_Rect right;
-} Pupil_Pair;
-typedef struct {
-	SDL_Point left;
-	SDL_Point right;
-} Pupil_Points;
-
-Pupil_Pair compute_pupil_positions(SDL_Point target) {
-	Pupil_Pair result;
-	Pupil_Points points;
-	points.left = computePupil(0,target);
-	points.right = computePupil(1,target);
-	result.left.x = points.left.x - BALL_WIDTH / 2.0;
-	result.left.y = points.left.y - BALL_HEIGHT / 2.0;
-	result.right.x = points.right.x - BALL_WIDTH / 2.0;
-	result.right.y = points.right.y - BALL_HEIGHT / 2.0;
-	result.left.w = result.right.w = BALL_WIDTH;
-	result.left.h = result.left.w = BALL_HEIGHT;
-	return result;
-}
-
-void render_eyes(SDL_Window *window,SDL_Texture *eyes_texture,Pupil_Pair pupils) {
-	SDL_SelectRenderer(window);
-	
-	//Clear render-target to blue.
-	SDL_SetRenderDrawColor(0x00,0x00,0xff,0xff);
-	SDL_RenderClear();
-	
-	//Render the whites of the eyes.
-	SDL_Rect srcdestrect = {0,0,eyes_width,eyes_height};
-	SDL_RenderCopy(eyes_texture,&srcdestrect,&srcdestrect);
-	
-	//Render the pupils.
-	SDL_SetRenderDrawColor(0x00,0x00,0x00,0xff);
-	const SDL_Rect eyes[2] = {pupils.left,pupils.right};
-	SDL_RenderFillRects((const SDL_Rect**)&eyes,2);
-	
-	SDL_RenderPresent();
-}
-
-int main(int argc,char** argv) {
-	if(SDL_VideoInit(NULL,0) == -1) {
-		printf("Could not initialize SDL video.\n");
-		exit(-1);
-	}
-	
-	SDL_Window *window = SDL_CreateShapedWindow("Big Brother is watching you.",eyes_x_hot,eyes_y_hot,eyes_width,eyes_height,SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
-	if(window == NULL) {
-		SDL_VideoQuit();
-		printf("Could not create shaped window for eyes.\n");
-		exit(-2);
-	}
-	if(SDL_CreateRenderer(window,-1,SDL_RENDERER_PRESENTFLIP2) == -1) {
-		SDL_DestroyWindow(window);
-		SDL_VideoQuit();
-		printf("Could not create rendering context for SDL_Eyes window.\n");
-		exit(-3);
-	}
-	
-	int bpp = 0;
-	Uint32 r = 0,g = 0,b = 0,a = 0;
-	SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB4444,&bpp,&r,&g,&b,&a);
-	SDL_Surface *eyes = SDL_CreateRGBSurface(0,eyes_width,eyes_height,bpp,r,g,b,a);
-	if(eyes == NULL) {
-		SDL_DestroyRenderer(window);
-		SDL_DestroyWindow(window);
-		SDL_VideoQuit();
-		printf("Could not create eyes surface.\n");
-		exit(-4);
-	}
-	
-	void *pixels = NULL;
-	int pitch = 0;
-	SDL_Rect rect = {0,0,eyes_width,eyes_height};
-	if(SDL_MUSTLOCK(eyes))
-		SDL_LockSurface(eyes);
-	pixels = eyes->pixels;
-	pitch = eyes->pitch;
-	for(int y=0;y<eyes_height;y++)
-		for(int x=0;x<eyes_width;x++) {
-			Uint8 brightness = *(Uint8*)(eyes_bits+(eyes_width/8)*y+(x/8)) & (1 << (7 - x % 8)) ? 255 : 0;
-			*(Uint16*)(pixels+pitch*y+x*16/8) = SDL_MapRGBA(eyes->format,brightness,brightness,brightness,255);
-		}
-	if(SDL_MUSTLOCK(eyes))
-		SDL_UnlockSurface(eyes);
-	SDL_Texture *eyes_texture = SDL_CreateTextureFromSurface(0,eyes);
-	if(eyes_texture == NULL) {
-		SDL_FreeSurface(eyes);
-		SDL_DestroyRenderer(window);
-		SDL_DestroyWindow(window);
-		SDL_VideoQuit();
-		printf("Could not create eyes texture.\n");
-		exit(-5);
-	}
-
-	SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_ARGB4444,&bpp,&r,&g,&b,&a);
-	SDL_Surface *mask = SDL_CreateRGBSurface(0,eyesmask_width,eyesmask_height,bpp,r,g,b,a);
-	if(mask == NULL) {
-		SDL_DestroyTexture(eyes_texture);
-		SDL_FreeSurface(eyes);
-		SDL_DestroyRenderer(window);
-		SDL_DestroyWindow(window);
-		SDL_VideoQuit();
-		printf("Could not create shape mask texture.\n");
-		exit(-5);
-	}
-	
-	if(SDL_MUSTLOCK(mask))
-		SDL_LockSurface(mask);
-	pixels = mask->pixels;
-	pitch = mask->pitch;
-	for(int y=0;y<eyesmask_height;y++)
-		for(int x=0;x<eyesmask_width;x++) {
-			Uint8 alpha = *(Uint8*)(eyesmask_bits+(eyesmask_width/8)*y+(x/8)) & (1 << (7 - x % 8)) ? 1 : 0;
-			*(Uint16*)(pixels+pitch*y+x*bpp/8) = SDL_MapRGBA(mask->format,0,0,0,alpha);
-		}
-	if(SDL_MUSTLOCK(mask))
-		SDL_UnlockSurface(mask);
-	
-	SDL_WindowShapeMode mode = {ShapeModeDefault,1};
-	SDL_SetWindowShape(window,mask,&mode);
-	
-	SDL_Event event;
-	int event_pending = 0;
-	event_pending = SDL_PollEvent(&event);
-	SDL_Point mouse_position;
-	Pupil_Pair pupil_positions;
-	SDL_SelectMouse(0);
-	SDL_GetMouseState(&mouse_position.x,&mouse_position.y);
-	pupil_positions = compute_pupil_positions(mouse_position);
-	while(event.type != SDL_QUIT) {
-		if(event.type == SDL_MOUSEMOTION) {
-			mouse_position.x = event.motion.x;
-			mouse_position.y = event.motion.y;
-			pupil_positions = compute_pupil_positions(mouse_position);
-		}
-		render_eyes(window,eyes_texture,pupil_positions);
-		event_pending = SDL_PollEvent(&event);
-	}
-	
-	SDL_FreeSurface(mask);
-	SDL_DestroyTexture(eyes_texture);
-	SDL_DestroyWindow(window);
-	//Call SDL_VideoQuit() before quitting.
-	SDL_VideoQuit();
-}
--- a/test/testeyes_bitmap.h	Sun Jul 18 15:15:05 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#define eyes_width 48
-#define eyes_height 32
-#define eyes_x_hot 0
-#define eyes_y_hot 0
-static unsigned char eyes_bits[] = {
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x78, 0x00, 0x00, 0x1e, 0x00, 0x00, 0xfe, 0x01, 0x80, 0x7f, 0x00,
-   0x00, 0x87, 0x03, 0xc0, 0xe1, 0x00, 0x80, 0x01, 0x06, 0x60, 0x80, 0x01,
-   0xc0, 0x00, 0x0c, 0x30, 0x00, 0x03, 0x60, 0x00, 0x18, 0x18, 0x00, 0x06,
-   0x30, 0x00, 0x30, 0x0c, 0x00, 0x0c, 0x30, 0x00, 0x30, 0x0c, 0x00, 0x0c,
-   0x10, 0x00, 0x20, 0x04, 0x00, 0x08, 0x18, 0x00, 0x60, 0x06, 0x00, 0x18,
-   0x18, 0x00, 0x60, 0x06, 0x00, 0x18, 0x18, 0x00, 0x60, 0x06, 0x00, 0x18,
-   0x18, 0x00, 0x60, 0x06, 0x00, 0x18, 0x18, 0x00, 0x60, 0x06, 0x00, 0x18,
-   0x18, 0x00, 0x60, 0x06, 0x00, 0x18, 0x18, 0x80, 0x63, 0x06, 0x00, 0x18,
-   0x18, 0x80, 0x63, 0x06, 0xe0, 0x18, 0x18, 0x80, 0x63, 0x06, 0xe0, 0x18,
-   0x18, 0x00, 0x60, 0x06, 0xe0, 0x18, 0x18, 0x00, 0x20, 0x06, 0x00, 0x08,
-   0x10, 0x00, 0x30, 0x04, 0x00, 0x0c, 0x10, 0x00, 0x10, 0x04, 0x00, 0x04,
-   0x30, 0x00, 0x18, 0x0c, 0x00, 0x06, 0x60, 0x00, 0x08, 0x18, 0x00, 0x02,
-   0x40, 0x00, 0x0c, 0x10, 0x00, 0x03, 0xc0, 0x00, 0x06, 0x30, 0x80, 0x01,
-   0x80, 0x83, 0x03, 0xe0, 0xe0, 0x00, 0x00, 0xff, 0x01, 0xc0, 0x7f, 0x00,
-   0x00, 0xfe, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
--- a/test/testeyes_mask_bitmap.h	Sun Jul 18 15:15:05 2010 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#define eyesmask_width 48
-#define eyesmask_height 32
-#define eyesmask_x_hot 0
-#define eyesmask_y_hot 0
-static unsigned char eyesmask_bits[] = {
-   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-   0x00, 0x78, 0x00, 0x00, 0x1e, 0x00, 0x00, 0xfe, 0x01, 0x80, 0x7f, 0x00,
-   0x00, 0xff, 0x03, 0xc0, 0xff, 0x00, 0x80, 0xff, 0x07, 0xe0, 0xff, 0x01,
-   0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x03, 0xe0, 0xff, 0x1f, 0xf8, 0xff, 0x07,
-   0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x0f, 0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x0f,
-   0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x0f, 0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f,
-   0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f, 0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f,
-   0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f, 0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f,
-   0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f, 0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f,
-   0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f, 0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f,
-   0xf8, 0xff, 0x7f, 0xfe, 0xff, 0x1f, 0xf8, 0xff, 0x3f, 0xfe, 0xff, 0x0f,
-   0xf0, 0xff, 0x3f, 0xfc, 0xff, 0x0f, 0xf0, 0xff, 0x1f, 0xfc, 0xff, 0x07,
-   0xf0, 0xff, 0x1f, 0xfc, 0xff, 0x07, 0xe0, 0xff, 0x0f, 0xf8, 0xff, 0x03,
-   0xc0, 0xff, 0x0f, 0xf0, 0xff, 0x03, 0xc0, 0xff, 0x07, 0xf0, 0xff, 0x01,
-   0x80, 0xff, 0x03, 0xe0, 0xff, 0x00, 0x00, 0xff, 0x01, 0xc0, 0x7f, 0x00,
-   0x00, 0xfe, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testshape.c	Sun Jul 18 21:31:22 2010 -0400
@@ -0,0 +1,168 @@
+#include <stdlib.h>
+#include <math.h>
+#include <SDL_events.h>
+#include <SDL_rect.h>
+#include <SDL_pixels.h>
+#include <SDL_video.h>
+#include <SDL_shape.h>
+
+#define SHAPED_WINDOW_X 150
+#define SHAPED_WINDOW_Y 150
+#define SHAPED_WINDOW_DIMENSION 640
+
+int main(int argc,char** argv) {
+        if(argc < 2) {
+        	printf("SDL_Shape requires at least one bitmap file as argument.\n");
+        	exit(-1);
+        }
+	
+	if(SDL_VideoInit(NULL,0) == -1) {
+		printf("Could not initialize SDL video.\n");
+		exit(-2);
+	}
+	
+	Uint8 num_pictures = argc - 1;
+	SDL_Surface **pictures = malloc(sizeof(SDL_Surface*)*num_pictures);
+	int i = 0;
+	for(i=0;i<num_pictures;i++)
+		pictures[i] = NULL;
+	for(i=0;i<num_pictures;i++) {
+		SDL_Surface *original = SDL_LoadBMP(argv[i+1]);
+		if(original == NULL) {
+			int j = 0;
+			for(j=0;j<num_pictures;j++)
+				if(pictures[j] != NULL)
+					SDL_FreeSurface(pictures[j]);
+			free(pictures);
+			SDL_VideoQuit();
+			printf("Could not load surface from named bitmap file.\n");
+			exit(-3);
+		}
+		//THIS CONVERSION ROUTINE IS FRAGILE!  It relies in the fact that only certain portions of the format structure must be filled in to use it.
+		SDL_PixelFormat format = {NULL,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+		SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGBA8888,&format.BitsPerPixel,&format.Rmask,&format.Gmask,&format.Bmask,&format.Amask);
+		format.BytesPerPixel = format.BitsPerPixel / 8 + (format.BitsPerPixel % 8 > 0 ? 1 : 0);
+		pictures[i] = SDL_ConvertSurface(original,&format,0);
+		//We have no more need of the original now that we have our desired format.
+		SDL_FreeSurface(original);
+		if(pictures[i] == NULL) {
+			int j = 0;
+			for(j=0;j<num_pictures;j++)
+				if(pictures[j] != NULL)
+					SDL_FreeSurface(pictures[j]);
+			free(pictures);
+			SDL_VideoQuit();
+			printf("Could not convert bitmap surface to desired format.\n");
+			exit(-3);
+		}
+		
+		if(SDL_MUSTLOCK(pictures[i]))
+			SDL_LockSurface(pictures[i]);
+			
+		void* pixels = pictures[i]->pixels;
+		unsigned int pitch = pictures[i]->pitch;
+		int y =0,x = 0;
+		for(y=0;y<pictures[i]->h;y++)
+			for(x=0;x<pictures[i]->w;x++) {
+				Uint32* pixel = pixels+y*pitch+x*pictures[i]->format->BytesPerPixel;
+				Uint8 r = 0,g = 0,b = 0;
+				SDL_GetRGB(*pixel,pictures[i]->format,&r,&g,&b);
+				if(r == g == b == 0x00)
+					*pixel = SDL_MapRGBA(pictures[i]->format,r,g,b,0);
+			}
+			
+		if(SDL_MUSTLOCK(pictures[i]))
+			SDL_UnlockSurface(pictures[i]);
+	}
+	
+	SDL_Window *window = SDL_CreateShapedWindow("SDL_Shape test",SHAPED_WINDOW_X,SHAPED_WINDOW_Y,SHAPED_WINDOW_DIMENSION,SHAPED_WINDOW_DIMENSION,SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN);
+	if(window == NULL) {
+		for(i=0;i<num_pictures;i++)
+			SDL_FreeSurface(pictures[i]);
+		free(pictures);
+		SDL_VideoQuit();
+		printf("Could not create shaped window for SDL_Shape.\n");
+		exit(-4);
+	}
+	if(SDL_CreateRenderer(window,-1,SDL_RENDERER_PRESENTFLIP2) == -1) {
+		SDL_DestroyWindow(window);
+		for(i=0;i<num_pictures;i++)
+			SDL_FreeSurface(pictures[i]);
+		free(pictures);
+		SDL_VideoQuit();
+		printf("Could not create rendering context for SDL_Shape window.\n");
+		exit(-5);
+	}
+	
+	SDL_Texture **textures = malloc(sizeof(SDL_Texture*)*num_pictures);
+	for(i=0;i<num_pictures;i++)
+		textures[i] = NULL;
+	for(i=0;i<num_pictures;i++) {
+		textures[i] = SDL_CreateTextureFromSurface(0,pictures[i]);
+		if(textures[i] == NULL) {
+			int j = 0;
+			for(j=0;j<num_pictures;i++)
+				if(textures[i] != NULL)
+					SDL_DestroyTexture(textures[i]);
+			free(textures);
+			for(i=0;i<num_pictures;i++)
+				SDL_FreeSurface(pictures[i]);
+			free(pictures);
+			SDL_DestroyRenderer(window);
+			SDL_DestroyWindow(window);
+			SDL_VideoQuit();
+			printf("Could not create texture for SDL_shape.\n");
+			exit(-6);
+		}
+	}
+	
+	SDL_Event event;
+	int event_pending = 0;
+	event_pending = SDL_PollEvent(&event);
+	unsigned int current_picture = 0;
+	SDL_WindowShapeMode mode = {ShapeModeDefault,1};
+	SDL_SetWindowShape(window,pictures[current_picture],&mode);
+	int mouse_down = 0;
+	Uint32 format,access;
+	SDL_Rect texture_dimensions = {0,0,0,0};
+	SDL_QueryTexture(textures[current_picture],&format,&access,&texture_dimensions.w,&texture_dimensions.h);
+	SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
+	while(event.type != SDL_QUIT) {
+		if(event.type == SDL_MOUSEBUTTONDOWN)
+			mouse_down = 1;
+		if(mouse_down && event.type == SDL_MOUSEBUTTONUP) {
+			mouse_down = 0;
+			current_picture += 1;
+			if(current_picture >= num_pictures)
+				current_picture = 0;
+			SDL_QueryTexture(textures[current_picture],&format,&access,&texture_dimensions.w,&texture_dimensions.h);
+			SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
+			SDL_SetWindowShape(window,pictures[current_picture],&mode);
+		}
+		
+		SDL_SelectRenderer(window);
+	
+		//Clear render-target to blue.
+		SDL_SetRenderDrawColor(0x00,0x00,0xff,0xff);
+		SDL_RenderClear();
+		
+		//Render the texture.
+		SDL_RenderCopy(textures[current_picture],&texture_dimensions,&texture_dimensions);
+		
+		SDL_RenderPresent();
+		event_pending = SDL_PollEvent(&event);
+	}
+	
+	//Free the textures.
+	for(i=0;i<num_pictures;i++)
+		SDL_DestroyTexture(textures[i]);
+	free(textures);
+	//Destroy the window.
+	SDL_DestroyWindow(window);
+	//Free the original surfaces backing the textures.
+	for(i=0;i<num_pictures;i++)
+		SDL_FreeSurface(pictures[i]);
+	free(pictures);
+	//Call SDL_VideoQuit() before quitting.
+	SDL_VideoQuit();
+}