e14743d1 |
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. */ |
15 | static void quit(int rc) |
16 | { |
17 | SDL_Quit(); |
18 | exit(rc); |
19 | } |
20 | |
21 | void 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 | } |
34 | fprintf(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 | } |
69 | NOTICE("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 | |
98 | fprintf(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; |
117 | NOTICE("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 | |
150 | NOTICE("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); |
204 | NOTICE("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 | } |
224 | NOTICE("testwin: fading over\n"); |
225 | } |
226 | |
227 | done: |
228 | /* Free the picture and return */ |
229 | SDL_FreeSurface(picture); |
230 | free(colors); free(cmap); |
231 | return; |
232 | } |
233 | |
234 | int 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 | } |