/[pcsx2_0.9.7]/trunk/3rdparty/SDL-1.3.0-5387/test/testalpha.c
ViewVC logotype

Contents of /trunk/3rdparty/SDL-1.3.0-5387/test/testalpha.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.22