test/testwin.c
author Ryan C. Gordon <icculus@icculus.org>
Fri, 13 Jan 2006 02:32:07 +0000
changeset 1246 ca51a76a7328
parent 1152 51a8702d8ecd
child 1659 14717b52abc0
permissions -rw-r--r--
Make error message meaningful if dlopen() fails on libX11.
slouken@0
     1
slouken@0
     2
/* Bring up a window and play with it */
slouken@0
     3
slouken@0
     4
#include <stdlib.h>
slouken@0
     5
#include <stdio.h>
slouken@0
     6
#include <string.h>
slouken@0
     7
slouken@0
     8
#define BENCHMARK_SDL
slouken@0
     9
slouken@0
    10
#define NOTICE(X)	printf("%s", X);
slouken@0
    11
slouken@0
    12
#include "SDL.h"
slouken@0
    13
icculus@1151
    14
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
icculus@1151
    15
static void quit(int rc)
icculus@1151
    16
{
icculus@1151
    17
	SDL_Quit();
icculus@1151
    18
	exit(rc);
icculus@1151
    19
}
icculus@1151
    20
slouken@0
    21
void DrawPict(SDL_Surface *screen, char *bmpfile,
slouken@0
    22
					int speedy, int flip, int nofade)
slouken@0
    23
{
slouken@0
    24
	SDL_Surface *picture;
slouken@0
    25
	SDL_Rect dest, update;
slouken@0
    26
	int i, centered;
slouken@0
    27
	int ncolors;
slouken@0
    28
	SDL_Color *colors, *cmap;
slouken@0
    29
slouken@0
    30
	/* Load the image into a surface */
slouken@0
    31
	if ( bmpfile == NULL ) {
slouken@0
    32
		bmpfile = "sample.bmp";		/* Sample image */
slouken@0
    33
	}
slouken@0
    34
fprintf(stderr, "Loading picture: %s\n", bmpfile);
slouken@0
    35
	picture = SDL_LoadBMP(bmpfile);
slouken@0
    36
	if ( picture == NULL ) {
slouken@0
    37
		fprintf(stderr, "Couldn't load %s: %s\n", bmpfile,
slouken@0
    38
							SDL_GetError());
slouken@0
    39
		return;
slouken@0
    40
	}
slouken@0
    41
slouken@0
    42
	/* Set the display colors -- on a hicolor display this is a no-op */
slouken@0
    43
	if ( picture->format->palette ) {
slouken@0
    44
		ncolors = picture->format->palette->ncolors;
slouken@0
    45
		colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
slouken@0
    46
		cmap    = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
slouken@0
    47
		memcpy(colors, picture->format->palette->colors,
slouken@0
    48
						ncolors*sizeof(SDL_Color));
slouken@0
    49
	} else {
slouken@0
    50
		int       r, g, b;
slouken@0
    51
slouken@0
    52
		/* Allocate 256 color palette */
slouken@0
    53
		ncolors = 256;
slouken@0
    54
		colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
slouken@0
    55
		cmap    = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
slouken@0
    56
slouken@0
    57
		/* Set a 3,3,2 color cube */
slouken@0
    58
		for ( r=0; r<8; ++r ) {
slouken@0
    59
			for ( g=0; g<8; ++g ) {
slouken@0
    60
				for ( b=0; b<4; ++b ) {
slouken@0
    61
					i = ((r<<5)|(g<<2)|b);
slouken@0
    62
					colors[i].r = r<<5;
slouken@0
    63
					colors[i].g = g<<5;
slouken@0
    64
					colors[i].b = b<<6;
slouken@0
    65
				}
slouken@0
    66
			}
slouken@0
    67
		}
slouken@0
    68
	}
slouken@0
    69
NOTICE("testwin: setting colors\n");
slouken@0
    70
	if ( ! SDL_SetColors(screen, colors, 0, ncolors) &&
slouken@0
    71
				(screen->format->palette != NULL) ) {
slouken@0
    72
		fprintf(stderr,
slouken@0
    73
"Warning: Couldn't set all of the colors, but SDL will map the image\n"
slouken@0
    74
"         (colormap fading will suffer - try the -warp option)\n"
slouken@0
    75
		);
slouken@0
    76
	}
slouken@0
    77
slouken@0
    78
	/* Set the screen to black (not really necessary) */
slouken@0
    79
	if ( SDL_LockSurface(screen) == 0 ) {
slouken@0
    80
		Uint32 black;
slouken@0
    81
		Uint8 *pixels;
slouken@0
    82
slouken@0
    83
		black = SDL_MapRGB(screen->format, 0, 0, 0);
slouken@0
    84
		pixels = (Uint8 *)screen->pixels;
slouken@0
    85
		for ( i=0; i<screen->h; ++i ) {
slouken@0
    86
			memset(pixels, black,
slouken@0
    87
				screen->w*screen->format->BytesPerPixel);
slouken@0
    88
			pixels += screen->pitch;
slouken@0
    89
		}
slouken@0
    90
		SDL_UnlockSurface(screen);
slouken@0
    91
		SDL_UpdateRect(screen, 0, 0, 0, 0);
slouken@0
    92
	}
slouken@0
    93
	
slouken@0
    94
	/* Display the picture */
slouken@0
    95
	if ( speedy ) {
slouken@0
    96
		SDL_Surface *displayfmt;
slouken@0
    97
slouken@0
    98
fprintf(stderr, "Converting picture\n");
slouken@0
    99
		displayfmt = SDL_DisplayFormat(picture);
slouken@0
   100
		if ( displayfmt == NULL ) {
slouken@0
   101
			fprintf(stderr,
slouken@0
   102
				"Couldn't convert image: %s\n", SDL_GetError());
slouken@0
   103
			goto done;
slouken@0
   104
		}
slouken@0
   105
		SDL_FreeSurface(picture);
slouken@0
   106
		picture = displayfmt;
slouken@0
   107
	}
slouken@0
   108
	printf("(image surface located in %s memory)\n", 
slouken@0
   109
			(picture->flags&SDL_HWSURFACE) ? "video" : "system");
slouken@0
   110
	centered = (screen->w - picture->w)/2;
slouken@0
   111
	if ( centered < 0 ) {
slouken@0
   112
		centered = 0;
slouken@0
   113
	}
slouken@0
   114
	dest.y = (screen->h - picture->h)/2;
slouken@0
   115
	dest.w = picture->w;
slouken@0
   116
	dest.h = picture->h;
slouken@0
   117
NOTICE("testwin: moving image\n");
slouken@0
   118
	for ( i=0; i<=centered; ++i ) {
slouken@0
   119
		dest.x = i;
slouken@0
   120
		update = dest;
slouken@0
   121
		if ( SDL_BlitSurface(picture, NULL, screen, &update) < 0 ) {
slouken@0
   122
			fprintf(stderr, "Blit failed: %s\n", SDL_GetError());
slouken@0
   123
			break;
slouken@0
   124
		}
slouken@0
   125
		if ( flip ) {
slouken@0
   126
			SDL_Flip(screen);
slouken@0
   127
		} else {
slouken@0
   128
			SDL_UpdateRects(screen, 1, &update);
slouken@0
   129
		}
slouken@0
   130
	}
slouken@0
   131
slouken@0
   132
#ifdef SCREENSHOT
slouken@0
   133
	if ( SDL_SaveBMP(screen, "screen.bmp") < 0 )
slouken@0
   134
		printf("Couldn't save screen: %s\n", SDL_GetError());
slouken@0
   135
#endif
slouken@0
   136
slouken@0
   137
#ifndef BENCHMARK_SDL
slouken@0
   138
	/* Let it sit there for a while */
slouken@0
   139
	SDL_Delay(5*1000);
slouken@0
   140
#endif
slouken@0
   141
	/* Fade the colormap */
slouken@0
   142
	if ( ! nofade ) {
slouken@0
   143
		int maxstep;
slouken@0
   144
		SDL_Color final;
slouken@0
   145
		SDL_Color palcolors[256];
slouken@0
   146
		struct {
slouken@0
   147
			Sint16 r, g, b;
slouken@0
   148
		} cdist[256];
slouken@0
   149
slouken@0
   150
NOTICE("testwin: fading out...\n");
slouken@0
   151
		memcpy(cmap, colors, ncolors*sizeof(SDL_Color));
slouken@0
   152
		maxstep = 32-1;
slouken@0
   153
		final.r = 0xFF;
slouken@0
   154
		final.g = 0x00;
slouken@0
   155
		final.b = 0x00;
slouken@0
   156
		memcpy(palcolors, colors, ncolors*sizeof(SDL_Color));
slouken@0
   157
		for ( i=0; i<ncolors; ++i ) {
slouken@0
   158
			cdist[i].r = final.r-palcolors[i].r;
slouken@0
   159
			cdist[i].g = final.g-palcolors[i].g;
slouken@0
   160
			cdist[i].b = final.b-palcolors[i].b;
slouken@0
   161
		}
slouken@0
   162
		for ( i=0; i<=maxstep/2; ++i ) {	/* halfway fade */
slouken@0
   163
			int c;
slouken@0
   164
			for ( c=0; c<ncolors; ++c ) {
slouken@0
   165
				colors[c].r =
slouken@0
   166
					palcolors[c].r+((cdist[c].r*i))/maxstep;
slouken@0
   167
				colors[c].g =
slouken@0
   168
					palcolors[c].g+((cdist[c].g*i))/maxstep;
slouken@0
   169
				colors[c].b =
slouken@0
   170
					palcolors[c].b+((cdist[c].b*i))/maxstep;
slouken@0
   171
			}
slouken@0
   172
			SDL_SetColors(screen, colors, 0, ncolors);
slouken@0
   173
			SDL_Delay(1);
slouken@0
   174
		}
slouken@0
   175
		final.r = 0x00;
slouken@0
   176
		final.g = 0x00;
slouken@0
   177
		final.b = 0x00;
slouken@0
   178
		memcpy(palcolors, colors, ncolors*sizeof(SDL_Color));
slouken@0
   179
		for ( i=0; i<ncolors; ++i ) {
slouken@0
   180
			cdist[i].r = final.r-palcolors[i].r;
slouken@0
   181
			cdist[i].g = final.g-palcolors[i].g;
slouken@0
   182
			cdist[i].b = final.b-palcolors[i].b;
slouken@0
   183
		}
slouken@0
   184
		maxstep /= 2;
slouken@0
   185
		for ( i=0; i<=maxstep; ++i ) {		/* finish fade out */
slouken@0
   186
			int c;
slouken@0
   187
			for ( c=0; c<ncolors; ++c ) {
slouken@0
   188
				colors[c].r =
slouken@0
   189
					palcolors[c].r+((cdist[c].r*i))/maxstep;
slouken@0
   190
				colors[c].g =
slouken@0
   191
					palcolors[c].g+((cdist[c].g*i))/maxstep;
slouken@0
   192
				colors[c].b =
slouken@0
   193
					palcolors[c].b+((cdist[c].b*i))/maxstep;
slouken@0
   194
			}
slouken@0
   195
			SDL_SetColors(screen, colors, 0, ncolors);
slouken@0
   196
			SDL_Delay(1);
slouken@0
   197
		}
slouken@0
   198
		for ( i=0; i<ncolors; ++i ) {
slouken@0
   199
			colors[i].r = final.r;
slouken@0
   200
			colors[i].g = final.g;
slouken@0
   201
			colors[i].b = final.b;
slouken@0
   202
		}
slouken@0
   203
		SDL_SetColors(screen, colors, 0, ncolors);
slouken@0
   204
NOTICE("testwin: fading in...\n");
slouken@0
   205
		memcpy(palcolors, colors, ncolors*sizeof(SDL_Color));
slouken@0
   206
		for ( i=0; i<ncolors; ++i ) {
slouken@0
   207
			cdist[i].r = cmap[i].r-palcolors[i].r;
slouken@0
   208
			cdist[i].g = cmap[i].g-palcolors[i].g;
slouken@0
   209
			cdist[i].b = cmap[i].b-palcolors[i].b;
slouken@0
   210
		}
slouken@0
   211
		for ( i=0; i<=maxstep; ++i ) {	/* 32 step fade in */
slouken@0
   212
			int c;
slouken@0
   213
			for ( c=0; c<ncolors; ++c ) {
slouken@0
   214
				colors[c].r =
slouken@0
   215
					palcolors[c].r+((cdist[c].r*i))/maxstep;
slouken@0
   216
				colors[c].g =
slouken@0
   217
					palcolors[c].g+((cdist[c].g*i))/maxstep;
slouken@0
   218
				colors[c].b =
slouken@0
   219
					palcolors[c].b+((cdist[c].b*i))/maxstep;
slouken@0
   220
			}
slouken@0
   221
			SDL_SetColors(screen, colors, 0, ncolors);
slouken@0
   222
			SDL_Delay(1);
slouken@0
   223
		}
slouken@0
   224
NOTICE("testwin: fading over\n");
slouken@0
   225
	}
slouken@0
   226
	
slouken@0
   227
done:
slouken@0
   228
	/* Free the picture and return */
slouken@0
   229
	SDL_FreeSurface(picture);
slouken@0
   230
	free(colors); free(cmap);
slouken@0
   231
	return;
slouken@0
   232
}
slouken@0
   233
slouken@0
   234
int main(int argc, char *argv[])
slouken@0
   235
{
slouken@0
   236
	SDL_Surface *screen;
slouken@0
   237
	/* Options */
slouken@0
   238
	int speedy, flip, nofade;
slouken@0
   239
	int delay;
slouken@0
   240
	int w, h;
slouken@0
   241
	int desired_bpp;
slouken@0
   242
	Uint32 video_flags;
slouken@0
   243
#ifdef BENCHMARK_SDL
slouken@0
   244
	Uint32 then, now;
slouken@0
   245
#endif
slouken@0
   246
	/* Set default options and check command-line */
slouken@0
   247
	speedy = 0;
slouken@0
   248
	flip = 0;
slouken@0
   249
	nofade = 0;
slouken@0
   250
	delay = 1;
icculus@1152
   251
icculus@1152
   252
#ifdef _WIN32_WCE
icculus@1152
   253
	w = 640;
icculus@1152
   254
	h = 320;
icculus@1152
   255
	desired_bpp = 0;
icculus@1152
   256
	video_flags = SDL_FULLSCREEN;
icculus@1152
   257
#else
slouken@0
   258
	w = 640;
slouken@0
   259
	h = 480;
slouken@0
   260
	desired_bpp = 0;
slouken@0
   261
	video_flags = 0;
icculus@1152
   262
#endif
icculus@1151
   263
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
icculus@1151
   264
		fprintf(stderr,
icculus@1151
   265
			"Couldn't initialize SDL: %s\n", SDL_GetError());
icculus@1151
   266
		return(1);
icculus@1151
   267
	}
icculus@1151
   268
slouken@0
   269
	while ( argc > 1 ) {
slouken@0
   270
		if ( strcmp(argv[1], "-speedy") == 0 ) {
slouken@0
   271
			speedy = 1;
slouken@0
   272
			argv += 1;
slouken@0
   273
			argc -= 1;
slouken@0
   274
		} else
slouken@0
   275
		if ( strcmp(argv[1], "-nofade") == 0 ) {
slouken@0
   276
			nofade = 1;
slouken@0
   277
			argv += 1;
slouken@0
   278
			argc -= 1;
slouken@0
   279
		} else
slouken@0
   280
		if ( strcmp(argv[1], "-delay") == 0 ) {
slouken@0
   281
			if ( argv[2] ) {
slouken@0
   282
				delay = atoi(argv[2]);
slouken@0
   283
				argv += 2;
slouken@0
   284
				argc -= 2;
slouken@0
   285
			} else {
slouken@0
   286
				fprintf(stderr,
slouken@0
   287
				"The -delay option requires an argument\n");
icculus@1151
   288
				quit(1);
slouken@0
   289
			}
slouken@0
   290
		} else
slouken@0
   291
		if ( strcmp(argv[1], "-width") == 0 ) {
slouken@0
   292
			if ( argv[2] && ((w = atoi(argv[2])) > 0) ) {
slouken@0
   293
				argv += 2;
slouken@0
   294
				argc -= 2;
slouken@0
   295
			} else {
slouken@0
   296
				fprintf(stderr,
slouken@0
   297
				"The -width option requires an argument\n");
icculus@1151
   298
				quit(1);
slouken@0
   299
			}
slouken@0
   300
		} else
slouken@0
   301
		if ( strcmp(argv[1], "-height") == 0 ) {
slouken@0
   302
			if ( argv[2] && ((h = atoi(argv[2])) > 0) ) {
slouken@0
   303
				argv += 2;
slouken@0
   304
				argc -= 2;
slouken@0
   305
			} else {
slouken@0
   306
				fprintf(stderr,
slouken@0
   307
				"The -height option requires an argument\n");
icculus@1151
   308
				quit(1);
slouken@0
   309
			}
slouken@0
   310
		} else
slouken@0
   311
		if ( strcmp(argv[1], "-bpp") == 0 ) {
slouken@0
   312
			if ( argv[2] ) {
slouken@0
   313
				desired_bpp = atoi(argv[2]);
slouken@0
   314
				argv += 2;
slouken@0
   315
				argc -= 2;
slouken@0
   316
			} else {
slouken@0
   317
				fprintf(stderr,
slouken@0
   318
				"The -bpp option requires an argument\n");
icculus@1151
   319
				quit(1);
slouken@0
   320
			}
slouken@0
   321
		} else
slouken@0
   322
		if ( strcmp(argv[1], "-warp") == 0 ) {
slouken@0
   323
			video_flags |= SDL_HWPALETTE;
slouken@0
   324
			argv += 1;
slouken@0
   325
			argc -= 1;
slouken@0
   326
		} else
slouken@0
   327
		if ( strcmp(argv[1], "-hw") == 0 ) {
slouken@0
   328
			video_flags |= SDL_HWSURFACE;
slouken@0
   329
			argv += 1;
slouken@0
   330
			argc -= 1;
slouken@0
   331
		} else
slouken@0
   332
		if ( strcmp(argv[1], "-flip") == 0 ) {
slouken@0
   333
			video_flags |= SDL_DOUBLEBUF;
slouken@0
   334
			argv += 1;
slouken@0
   335
			argc -= 1;
slouken@0
   336
		} else
slouken@0
   337
		if ( strcmp(argv[1], "-fullscreen") == 0 ) {
slouken@0
   338
			video_flags |= SDL_FULLSCREEN;
slouken@0
   339
			argv += 1;
slouken@0
   340
			argc -= 1;
slouken@0
   341
		} else
slouken@0
   342
			break;
slouken@0
   343
	}
slouken@0
   344
slouken@0
   345
	/* Initialize the display */
slouken@0
   346
	screen = SDL_SetVideoMode(w, h, desired_bpp, video_flags);
slouken@0
   347
	if ( screen == NULL ) {
slouken@0
   348
		fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
slouken@0
   349
					w, h, desired_bpp, SDL_GetError());
icculus@1151
   350
		quit(1);
slouken@0
   351
	}
slouken@228
   352
	printf("Set%s %dx%dx%d mode\n",
slouken@228
   353
			screen->flags & SDL_FULLSCREEN ? " fullscreen" : "",
slouken@0
   354
			screen->w, screen->h, screen->format->BitsPerPixel);
slouken@0
   355
	printf("(video surface located in %s memory)\n",
slouken@0
   356
			(screen->flags&SDL_HWSURFACE) ? "video" : "system");
slouken@0
   357
	if ( screen->flags & SDL_DOUBLEBUF ) {
slouken@0
   358
		printf("Double-buffering enabled\n");
slouken@0
   359
		flip = 1;
slouken@0
   360
	}
slouken@0
   361
slouken@0
   362
	/* Set the window manager title bar */
slouken@0
   363
	SDL_WM_SetCaption("SDL test window", "testwin");
slouken@0
   364
slouken@0
   365
	/* Do all the drawing work */
slouken@0
   366
#ifdef BENCHMARK_SDL
slouken@0
   367
	then = SDL_GetTicks();
slouken@0
   368
	DrawPict(screen, argv[1], speedy, flip, nofade);
slouken@0
   369
	now = SDL_GetTicks();
slouken@0
   370
	printf("Time: %d milliseconds\n", now-then);
slouken@0
   371
#else
slouken@0
   372
	DrawPict(screen, argv[1], speedy, flip, nofade);
slouken@0
   373
#endif
slouken@0
   374
	SDL_Delay(delay*1000);
icculus@1151
   375
	SDL_Quit();
slouken@0
   376
	return(0);
slouken@0
   377
}