test/testshape.c
author Eli Gottlieb <eligottlieb@gmail.com>
Sun, 18 Jul 2010 21:31:22 -0400
changeset 4799 a0e096916474
child 4800 6d4be626225f
permissions -rw-r--r--
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.
     1 #include <stdlib.h>
     2 #include <math.h>
     3 #include <SDL_events.h>
     4 #include <SDL_rect.h>
     5 #include <SDL_pixels.h>
     6 #include <SDL_video.h>
     7 #include <SDL_shape.h>
     8 
     9 #define SHAPED_WINDOW_X 150
    10 #define SHAPED_WINDOW_Y 150
    11 #define SHAPED_WINDOW_DIMENSION 640
    12 
    13 int main(int argc,char** argv) {
    14         if(argc < 2) {
    15         	printf("SDL_Shape requires at least one bitmap file as argument.\n");
    16         	exit(-1);
    17         }
    18 	
    19 	if(SDL_VideoInit(NULL,0) == -1) {
    20 		printf("Could not initialize SDL video.\n");
    21 		exit(-2);
    22 	}
    23 	
    24 	Uint8 num_pictures = argc - 1;
    25 	SDL_Surface **pictures = malloc(sizeof(SDL_Surface*)*num_pictures);
    26 	int i = 0;
    27 	for(i=0;i<num_pictures;i++)
    28 		pictures[i] = NULL;
    29 	for(i=0;i<num_pictures;i++) {
    30 		SDL_Surface *original = SDL_LoadBMP(argv[i+1]);
    31 		if(original == NULL) {
    32 			int j = 0;
    33 			for(j=0;j<num_pictures;j++)
    34 				if(pictures[j] != NULL)
    35 					SDL_FreeSurface(pictures[j]);
    36 			free(pictures);
    37 			SDL_VideoQuit();
    38 			printf("Could not load surface from named bitmap file.\n");
    39 			exit(-3);
    40 		}
    41 		//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.
    42 		SDL_PixelFormat format = {NULL,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    43 		SDL_PixelFormatEnumToMasks(SDL_PIXELFORMAT_RGBA8888,&format.BitsPerPixel,&format.Rmask,&format.Gmask,&format.Bmask,&format.Amask);
    44 		format.BytesPerPixel = format.BitsPerPixel / 8 + (format.BitsPerPixel % 8 > 0 ? 1 : 0);
    45 		pictures[i] = SDL_ConvertSurface(original,&format,0);
    46 		//We have no more need of the original now that we have our desired format.
    47 		SDL_FreeSurface(original);
    48 		if(pictures[i] == NULL) {
    49 			int j = 0;
    50 			for(j=0;j<num_pictures;j++)
    51 				if(pictures[j] != NULL)
    52 					SDL_FreeSurface(pictures[j]);
    53 			free(pictures);
    54 			SDL_VideoQuit();
    55 			printf("Could not convert bitmap surface to desired format.\n");
    56 			exit(-3);
    57 		}
    58 		
    59 		if(SDL_MUSTLOCK(pictures[i]))
    60 			SDL_LockSurface(pictures[i]);
    61 			
    62 		void* pixels = pictures[i]->pixels;
    63 		unsigned int pitch = pictures[i]->pitch;
    64 		int y =0,x = 0;
    65 		for(y=0;y<pictures[i]->h;y++)
    66 			for(x=0;x<pictures[i]->w;x++) {
    67 				Uint32* pixel = pixels+y*pitch+x*pictures[i]->format->BytesPerPixel;
    68 				Uint8 r = 0,g = 0,b = 0;
    69 				SDL_GetRGB(*pixel,pictures[i]->format,&r,&g,&b);
    70 				if(r == g == b == 0x00)
    71 					*pixel = SDL_MapRGBA(pictures[i]->format,r,g,b,0);
    72 			}
    73 			
    74 		if(SDL_MUSTLOCK(pictures[i]))
    75 			SDL_UnlockSurface(pictures[i]);
    76 	}
    77 	
    78 	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);
    79 	if(window == NULL) {
    80 		for(i=0;i<num_pictures;i++)
    81 			SDL_FreeSurface(pictures[i]);
    82 		free(pictures);
    83 		SDL_VideoQuit();
    84 		printf("Could not create shaped window for SDL_Shape.\n");
    85 		exit(-4);
    86 	}
    87 	if(SDL_CreateRenderer(window,-1,SDL_RENDERER_PRESENTFLIP2) == -1) {
    88 		SDL_DestroyWindow(window);
    89 		for(i=0;i<num_pictures;i++)
    90 			SDL_FreeSurface(pictures[i]);
    91 		free(pictures);
    92 		SDL_VideoQuit();
    93 		printf("Could not create rendering context for SDL_Shape window.\n");
    94 		exit(-5);
    95 	}
    96 	
    97 	SDL_Texture **textures = malloc(sizeof(SDL_Texture*)*num_pictures);
    98 	for(i=0;i<num_pictures;i++)
    99 		textures[i] = NULL;
   100 	for(i=0;i<num_pictures;i++) {
   101 		textures[i] = SDL_CreateTextureFromSurface(0,pictures[i]);
   102 		if(textures[i] == NULL) {
   103 			int j = 0;
   104 			for(j=0;j<num_pictures;i++)
   105 				if(textures[i] != NULL)
   106 					SDL_DestroyTexture(textures[i]);
   107 			free(textures);
   108 			for(i=0;i<num_pictures;i++)
   109 				SDL_FreeSurface(pictures[i]);
   110 			free(pictures);
   111 			SDL_DestroyRenderer(window);
   112 			SDL_DestroyWindow(window);
   113 			SDL_VideoQuit();
   114 			printf("Could not create texture for SDL_shape.\n");
   115 			exit(-6);
   116 		}
   117 	}
   118 	
   119 	SDL_Event event;
   120 	int event_pending = 0;
   121 	event_pending = SDL_PollEvent(&event);
   122 	unsigned int current_picture = 0;
   123 	SDL_WindowShapeMode mode = {ShapeModeDefault,1};
   124 	SDL_SetWindowShape(window,pictures[current_picture],&mode);
   125 	int mouse_down = 0;
   126 	Uint32 format,access;
   127 	SDL_Rect texture_dimensions = {0,0,0,0};
   128 	SDL_QueryTexture(textures[current_picture],&format,&access,&texture_dimensions.w,&texture_dimensions.h);
   129 	SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
   130 	while(event.type != SDL_QUIT) {
   131 		if(event.type == SDL_MOUSEBUTTONDOWN)
   132 			mouse_down = 1;
   133 		if(mouse_down && event.type == SDL_MOUSEBUTTONUP) {
   134 			mouse_down = 0;
   135 			current_picture += 1;
   136 			if(current_picture >= num_pictures)
   137 				current_picture = 0;
   138 			SDL_QueryTexture(textures[current_picture],&format,&access,&texture_dimensions.w,&texture_dimensions.h);
   139 			SDL_SetWindowSize(window,texture_dimensions.w,texture_dimensions.h);
   140 			SDL_SetWindowShape(window,pictures[current_picture],&mode);
   141 		}
   142 		
   143 		SDL_SelectRenderer(window);
   144 	
   145 		//Clear render-target to blue.
   146 		SDL_SetRenderDrawColor(0x00,0x00,0xff,0xff);
   147 		SDL_RenderClear();
   148 		
   149 		//Render the texture.
   150 		SDL_RenderCopy(textures[current_picture],&texture_dimensions,&texture_dimensions);
   151 		
   152 		SDL_RenderPresent();
   153 		event_pending = SDL_PollEvent(&event);
   154 	}
   155 	
   156 	//Free the textures.
   157 	for(i=0;i<num_pictures;i++)
   158 		SDL_DestroyTexture(textures[i]);
   159 	free(textures);
   160 	//Destroy the window.
   161 	SDL_DestroyWindow(window);
   162 	//Free the original surfaces backing the textures.
   163 	for(i=0;i<num_pictures;i++)
   164 		SDL_FreeSurface(pictures[i]);
   165 	free(pictures);
   166 	//Call SDL_VideoQuit() before quitting.
   167 	SDL_VideoQuit();
   168 }