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 } 378