OSDN Git Service

remove ffmpeg from this project. i will put the ffmpeg to "external/ffmpeg" path
[android-x86/external-stagefright-plugins.git] / SDL-1.3 / android-project / jni / SDL / test / testalpha.c
1 /*
2   Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
3
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely.
11 */
12
13 /* Simple program:  Fill a colormap with gray and stripe it down the screen,
14                     Then move an alpha valued sprite around the screen.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <math.h>
21
22 #include "SDL.h"
23
24 #define FRAME_TICKS     (1000/30)       /* 30 frames/second */
25
26 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
27 static void
28 quit(int rc)
29 {
30     SDL_Quit();
31     exit(rc);
32 }
33
34 /* Fill the screen with a gradient */
35 static void
36 FillBackground(SDL_Surface * screen)
37 {
38     Uint8 *buffer;
39     Uint8 gradient;
40     int i, k;
41
42     /* Set the surface pixels and refresh! */
43     if (SDL_LockSurface(screen) < 0) {
44         fprintf(stderr, "Couldn't lock the display surface: %s\n",
45                 SDL_GetError());
46         quit(2);
47     }
48     buffer = (Uint8 *) screen->pixels;
49     switch (screen->format->BytesPerPixel) {
50     case 1:
51     case 3:
52         for (i = 0; i < screen->h; ++i) {
53             memset(buffer, (i * 255) / screen->h,
54                    screen->w * screen->format->BytesPerPixel);
55             buffer += screen->pitch;
56         }
57         break;
58     case 2:
59         for (i = 0; i < screen->h; ++i) {
60             Uint16 *buffer16;
61             Uint16 color;
62
63             gradient = ((i * 255) / screen->h);
64             color = (Uint16) SDL_MapRGB(screen->format,
65                                         gradient, gradient, gradient);
66             buffer16 = (Uint16 *) buffer;
67             for (k = 0; k < screen->w; k++) {
68                 *buffer16++ = color;
69             }
70             buffer += screen->pitch;
71         }
72         break;
73     case 4:
74         for (i = 0; i < screen->h; ++i) {
75             Uint32 *buffer32;
76             Uint32 color;
77
78             gradient = ((i * 255) / screen->h);
79             color = SDL_MapRGB(screen->format, gradient, gradient, gradient);
80             buffer32 = (Uint32 *) buffer;
81             for (k = 0; k < screen->w; k++) {
82                 *buffer32++ = color;
83             }
84             buffer += screen->pitch;
85         }
86         break;
87     }
88
89     SDL_UnlockSurface(screen);
90     SDL_UpdateRect(screen, 0, 0, 0, 0);
91 }
92
93 /* Create a "light" -- a yellowish surface with variable alpha */
94 SDL_Surface *
95 CreateLight(int radius)
96 {
97     Uint8 trans, alphamask;
98     int range, addition;
99     int xdist, ydist;
100     Uint16 x, y;
101     Uint16 skip;
102     Uint32 pixel;
103     SDL_Surface *light;
104
105 #ifdef LIGHT_16BIT
106     Uint16 *buf;
107
108     /* Create a 16 (4/4/4/4) bpp square with a full 4-bit alpha channel */
109     /* Note: this isn't any faster than a 32 bit alpha surface */
110     alphamask = 0x0000000F;
111     light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2 * radius, 2 * radius, 16,
112                                  0x0000F000, 0x00000F00, 0x000000F0,
113                                  alphamask);
114 #else
115     Uint32 *buf;
116
117     /* Create a 32 (8/8/8/8) bpp square with a full 8-bit alpha channel */
118     alphamask = 0x000000FF;
119     light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2 * radius, 2 * radius, 32,
120                                  0xFF000000, 0x00FF0000, 0x0000FF00,
121                                  alphamask);
122     if (light == NULL) {
123         fprintf(stderr, "Couldn't create light: %s\n", SDL_GetError());
124         return (NULL);
125     }
126 #endif
127
128     /* Fill with a light yellow-orange color */
129     skip = light->pitch - (light->w * light->format->BytesPerPixel);
130 #ifdef LIGHT_16BIT
131     buf = (Uint16 *) light->pixels;
132 #else
133     buf = (Uint32 *) light->pixels;
134 #endif
135     /* Get a tranparent pixel value - we'll add alpha later */
136     pixel = SDL_MapRGBA(light->format, 0xFF, 0xDD, 0x88, 0);
137     for (y = 0; y < light->h; ++y) {
138         for (x = 0; x < light->w; ++x) {
139             *buf++ = pixel;
140         }
141         buf += skip;            /* Almost always 0, but just in case... */
142     }
143
144     /* Calculate alpha values for the surface. */
145 #ifdef LIGHT_16BIT
146     buf = (Uint16 *) light->pixels;
147 #else
148     buf = (Uint32 *) light->pixels;
149 #endif
150     for (y = 0; y < light->h; ++y) {
151         for (x = 0; x < light->w; ++x) {
152             /* Slow distance formula (from center of light) */
153             xdist = x - (light->w / 2);
154             ydist = y - (light->h / 2);
155             range = (int) sqrt(xdist * xdist + ydist * ydist);
156
157             /* Scale distance to range of transparency (0-255) */
158             if (range > radius) {
159                 trans = alphamask;
160             } else {
161                 /* Increasing transparency with distance */
162                 trans = (Uint8) ((range * alphamask) / radius);
163
164                 /* Lights are very transparent */
165                 addition = (alphamask + 1) / 8;
166                 if ((int) trans + addition > alphamask) {
167                     trans = alphamask;
168                 } else {
169                     trans += addition;
170                 }
171             }
172             /* We set the alpha component as the right N bits */
173             *buf++ |= (255 - trans);
174         }
175         buf += skip;            /* Almost always 0, but just in case... */
176     }
177     /* Enable RLE acceleration of this alpha surface */
178     SDL_SetAlpha(light, SDL_SRCALPHA | SDL_RLEACCEL, 0);
179
180     /* We're done! */
181     return (light);
182 }
183
184 static Uint32 flashes = 0;
185 static Uint32 flashtime = 0;
186
187 void
188 FlashLight(SDL_Surface * screen, SDL_Surface * light, int x, int y)
189 {
190     SDL_Rect position;
191     Uint32 ticks1;
192     Uint32 ticks2;
193
194     /* Easy, center light */
195     position.x = x - (light->w / 2);
196     position.y = y - (light->h / 2);
197     position.w = light->w;
198     position.h = light->h;
199     ticks1 = SDL_GetTicks();
200     SDL_BlitSurface(light, NULL, screen, &position);
201     ticks2 = SDL_GetTicks();
202     SDL_UpdateRects(screen, 1, &position);
203     ++flashes;
204
205     /* Update time spend doing alpha blitting */
206     flashtime += (ticks2 - ticks1);
207 }
208
209 static int sprite_visible = 0;
210 static SDL_Surface *sprite;
211 static SDL_Surface *backing;
212 static SDL_Rect position;
213 static int x_vel, y_vel;
214 static int alpha_vel;
215
216 int
217 LoadSprite(SDL_Surface * screen, char *file)
218 {
219     SDL_Surface *converted;
220
221     /* Load the sprite image */
222     sprite = SDL_LoadBMP(file);
223     if (sprite == NULL) {
224         fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
225         return (-1);
226     }
227
228     /* Set transparent pixel as the pixel at (0,0) */
229     if (sprite->format->palette) {
230         SDL_SetColorKey(sprite, SDL_SRCCOLORKEY, *(Uint8 *) sprite->pixels);
231     }
232
233     /* Convert sprite to video format */
234     converted = SDL_DisplayFormat(sprite);
235     SDL_FreeSurface(sprite);
236     if (converted == NULL) {
237         fprintf(stderr, "Couldn't convert background: %s\n", SDL_GetError());
238         return (-1);
239     }
240     sprite = converted;
241
242     /* Create the background */
243     backing = SDL_CreateRGBSurface(SDL_SWSURFACE, sprite->w, sprite->h, 8,
244                                    0, 0, 0, 0);
245     if (backing == NULL) {
246         fprintf(stderr, "Couldn't create background: %s\n", SDL_GetError());
247         SDL_FreeSurface(sprite);
248         return (-1);
249     }
250
251     /* Convert background to video format */
252     converted = SDL_DisplayFormat(backing);
253     SDL_FreeSurface(backing);
254     if (converted == NULL) {
255         fprintf(stderr, "Couldn't convert background: %s\n", SDL_GetError());
256         SDL_FreeSurface(sprite);
257         return (-1);
258     }
259     backing = converted;
260
261     /* Set the initial position of the sprite */
262     position.x = (screen->w - sprite->w) / 2;
263     position.y = (screen->h - sprite->h) / 2;
264     position.w = sprite->w;
265     position.h = sprite->h;
266     x_vel = 0;
267     y_vel = 0;
268     alpha_vel = 1;
269
270     /* We're ready to roll. :) */
271     return (0);
272 }
273
274 void
275 AttractSprite(Uint16 x, Uint16 y)
276 {
277     x_vel = ((int) x - position.x) / 10;
278     y_vel = ((int) y - position.y) / 10;
279 }
280
281 void
282 MoveSprite(SDL_Surface * screen, SDL_Surface * light)
283 {
284     SDL_Rect updates[2];
285     Uint8 alpha;
286
287     /* Erase the sprite if it was visible */
288     if (sprite_visible) {
289         updates[0] = position;
290         SDL_BlitSurface(backing, NULL, screen, &updates[0]);
291     } else {
292         updates[0].x = 0;
293         updates[0].y = 0;
294         updates[0].w = 0;
295         updates[0].h = 0;
296         sprite_visible = 1;
297     }
298
299     /* Since the sprite is off the screen, we can do other drawing
300        without being overwritten by the saved area behind the sprite.
301      */
302     if (light != NULL) {
303         int x, y;
304
305         SDL_GetMouseState(&x, &y);
306         FlashLight(screen, light, x, y);
307     }
308
309     /* Move the sprite, bounce at the wall */
310     position.x += x_vel;
311     if ((position.x < 0) || (position.x >= screen->w)) {
312         x_vel = -x_vel;
313         position.x += x_vel;
314     }
315     position.y += y_vel;
316     if ((position.y < 0) || (position.y >= screen->h)) {
317         y_vel = -y_vel;
318         position.y += y_vel;
319     }
320
321     /* Update transparency (fade in and out) */
322     SDL_GetSurfaceAlphaMod(sprite, &alpha);
323     if (((int) alpha + alpha_vel) < 0) {
324         alpha_vel = -alpha_vel;
325     } else if (((int) alpha + alpha_vel) > 255) {
326         alpha_vel = -alpha_vel;
327     }
328     SDL_SetAlpha(sprite, SDL_SRCALPHA, (Uint8) (alpha + alpha_vel));
329
330     /* Save the area behind the sprite */
331     updates[1] = position;
332     SDL_BlitSurface(screen, &updates[1], backing, NULL);
333
334     /* Blit the sprite onto the screen */
335     updates[1] = position;
336     SDL_BlitSurface(sprite, NULL, screen, &updates[1]);
337
338     /* Make it so! */
339     SDL_UpdateRects(screen, 2, updates);
340 }
341
342 int
343 main(int argc, char *argv[])
344 {
345     const SDL_VideoInfo *info;
346     SDL_Surface *screen;
347     int w, h;
348     Uint8 video_bpp;
349     Uint32 videoflags;
350     int i, done;
351     SDL_Event event;
352     SDL_Surface *light;
353     int mouse_pressed;
354     Uint32 ticks, lastticks;
355
356
357     /* Initialize SDL */
358     if (SDL_Init(SDL_INIT_VIDEO) < 0) {
359         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
360         return (1);
361     }
362
363     /* Alpha blending doesn't work well at 8-bit color */
364 #ifdef _WIN32_WCE
365     /* Pocket PC */
366     w = 240;
367     h = 320;
368 #else
369     w = 640;
370     h = 480;
371 #endif
372     info = SDL_GetVideoInfo();
373     if (info->vfmt->BitsPerPixel > 8) {
374         video_bpp = info->vfmt->BitsPerPixel;
375     } else {
376         video_bpp = 16;
377         fprintf(stderr, "forced 16 bpp mode\n");
378     }
379     videoflags = SDL_SWSURFACE;
380     for (i = 1; argv[i]; ++i) {
381         if (strcmp(argv[i], "-bpp") == 0) {
382             video_bpp = atoi(argv[++i]);
383             if (video_bpp <= 8) {
384                 video_bpp = 16;
385                 fprintf(stderr, "forced 16 bpp mode\n");
386             }
387         } else if (strcmp(argv[i], "-hw") == 0) {
388             videoflags |= SDL_HWSURFACE;
389         } else if (strcmp(argv[i], "-warp") == 0) {
390             videoflags |= SDL_HWPALETTE;
391         } else if (strcmp(argv[i], "-width") == 0 && argv[i + 1]) {
392             w = atoi(argv[++i]);
393         } else if (strcmp(argv[i], "-height") == 0 && argv[i + 1]) {
394             h = atoi(argv[++i]);
395         } else if (strcmp(argv[i], "-resize") == 0) {
396             videoflags |= SDL_RESIZABLE;
397         } else if (strcmp(argv[i], "-noframe") == 0) {
398             videoflags |= SDL_NOFRAME;
399         } else if (strcmp(argv[i], "-fullscreen") == 0) {
400             videoflags |= SDL_FULLSCREEN;
401         } else {
402             fprintf(stderr,
403                     "Usage: %s [-width N] [-height N] [-bpp N] [-warp] [-hw] [-fullscreen]\n",
404                     argv[0]);
405             quit(1);
406         }
407     }
408
409     /* Set video mode */
410     if ((screen = SDL_SetVideoMode(w, h, video_bpp, videoflags)) == NULL) {
411         fprintf(stderr, "Couldn't set %dx%dx%d video mode: %s\n",
412                 w, h, video_bpp, SDL_GetError());
413         quit(2);
414     }
415     FillBackground(screen);
416
417     /* Create the light */
418     light = CreateLight(82);
419     if (light == NULL) {
420         quit(1);
421     }
422
423     /* Load the sprite */
424     if (LoadSprite(screen, "icon.bmp") < 0) {
425         SDL_FreeSurface(light);
426         quit(1);
427     }
428
429     /* Print out information about our surfaces */
430     printf("Screen is at %d bits per pixel\n", screen->format->BitsPerPixel);
431     if ((screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
432         printf("Screen is in video memory\n");
433     } else {
434         printf("Screen is in system memory\n");
435     }
436     if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
437         printf("Screen has double-buffering enabled\n");
438     }
439     if ((sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
440         printf("Sprite is in video memory\n");
441     } else {
442         printf("Sprite is in system memory\n");
443     }
444
445     /* Run a sample blit to trigger blit acceleration */
446     MoveSprite(screen, NULL);
447     if ((sprite->flags & SDL_HWACCEL) == SDL_HWACCEL) {
448         printf("Sprite blit uses hardware alpha acceleration\n");
449     } else {
450         printf("Sprite blit dosn't uses hardware alpha acceleration\n");
451     }
452
453     /* Set a clipping rectangle to clip the outside edge of the screen */
454     {
455         SDL_Rect clip;
456         clip.x = 32;
457         clip.y = 32;
458         clip.w = screen->w - (2 * 32);
459         clip.h = screen->h - (2 * 32);
460         SDL_SetClipRect(screen, &clip);
461     }
462
463     /* Wait for a keystroke */
464     lastticks = SDL_GetTicks();
465     done = 0;
466     mouse_pressed = 0;
467     while (!done) {
468         /* Update the frame -- move the sprite */
469         if (mouse_pressed) {
470             MoveSprite(screen, light);
471             mouse_pressed = 0;
472         } else {
473             MoveSprite(screen, NULL);
474         }
475
476         /* Slow down the loop to 30 frames/second */
477         ticks = SDL_GetTicks();
478         if ((ticks - lastticks) < FRAME_TICKS) {
479 #ifdef CHECK_SLEEP_GRANULARITY
480             fprintf(stderr, "Sleeping %d ticks\n",
481                     FRAME_TICKS - (ticks - lastticks));
482 #endif
483             SDL_Delay(FRAME_TICKS - (ticks - lastticks));
484 #ifdef CHECK_SLEEP_GRANULARITY
485             fprintf(stderr, "Slept %d ticks\n", (SDL_GetTicks() - ticks));
486 #endif
487         }
488         lastticks = ticks;
489
490         /* Check for events */
491         while (SDL_PollEvent(&event)) {
492             switch (event.type) {
493             case SDL_VIDEORESIZE:
494                 screen =
495                     SDL_SetVideoMode(event.resize.w, event.resize.h,
496                                      video_bpp, videoflags);
497                 if (screen) {
498                     FillBackground(screen);
499                 }
500                 break;
501                 /* Attract sprite while mouse is held down */
502             case SDL_MOUSEMOTION:
503                 if (event.motion.state != 0) {
504                     AttractSprite(event.motion.x, event.motion.y);
505                     mouse_pressed = 1;
506                 }
507                 break;
508             case SDL_MOUSEBUTTONDOWN:
509                 if (event.button.button == 1) {
510                     AttractSprite(event.button.x, event.button.y);
511                     mouse_pressed = 1;
512                 } else {
513                     SDL_Rect area;
514
515                     area.x = event.button.x - 16;
516                     area.y = event.button.y - 16;
517                     area.w = 32;
518                     area.h = 32;
519                     SDL_FillRect(screen, &area,
520                                  SDL_MapRGB(screen->format, 0, 0, 0));
521                     SDL_UpdateRects(screen, 1, &area);
522                 }
523                 break;
524             case SDL_KEYDOWN:
525                 if (event.key.keysym.sym == SDLK_ESCAPE) {
526                     done = 1;
527                 }
528                 if (event.key.keysym.sym == SDLK_RETURN) {
529                     SDL_WM_ToggleFullScreen(screen);
530                 }
531                 break;
532             case SDL_QUIT:
533                 done = 1;
534                 break;
535             default:
536                 break;
537             }
538         }
539     }
540     SDL_FreeSurface(light);
541     SDL_FreeSurface(sprite);
542     SDL_FreeSurface(backing);
543
544     /* Print out some timing information */
545     if (flashes > 0) {
546         printf("%d alpha blits, ~%4.4f ms per blit\n",
547                flashes, (float) flashtime / flashes);
548     }
549
550     SDL_Quit();
551     return (0);
552 }