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