comparison test/testsprite.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 4d241ea8a1cd
children 06c27a737b7a
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
1 /* Simple program: Move N sprites around on the screen as fast as possible */ 1 /* Simple program: Move N sprites around on the screen as fast as possible */
2 2
3 #include <stdio.h>
4 #include <stdlib.h> 3 #include <stdlib.h>
5 #include <string.h>
6 #include <ctype.h>
7 #include <math.h>
8 #include <time.h> 4 #include <time.h>
9 5
10 #include "SDL.h" 6 #include "SDL.h"
11 7
12 #define NUM_SPRITES 100 8 #define NUM_SPRITES 100
20 int sprites_visible; 16 int sprites_visible;
21 int debug_flip; 17 int debug_flip;
22 Uint16 sprite_w, sprite_h; 18 Uint16 sprite_w, sprite_h;
23 19
24 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ 20 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
25 static void quit(int rc) 21 static void
26 { 22 quit(int rc)
27 SDL_Quit(); 23 {
28 exit(rc); 24 SDL_Quit();
29 } 25 exit(rc);
30 26 }
31 int LoadSprite(char *file) 27
32 { 28 int
33 SDL_Surface *temp; 29 LoadSprite(char *file)
34 30 {
35 /* Load the sprite image */ 31 SDL_Surface *temp;
36 sprite = SDL_LoadBMP(file); 32
37 if ( sprite == NULL ) { 33 /* Load the sprite image */
38 fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError()); 34 sprite = SDL_LoadBMP(file);
39 return(-1); 35 if (sprite == NULL) {
40 } 36 fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
41 37 return (-1);
42 /* Set transparent pixel as the pixel at (0,0) */ 38 }
43 if ( sprite->format->palette ) { 39
44 SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL), 40 /* Set transparent pixel as the pixel at (0,0) */
45 *(Uint8 *)sprite->pixels); 41 if (sprite->format->palette) {
46 } 42 SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY | SDL_RLEACCEL),
47 43 *(Uint8 *) sprite->pixels);
48 /* Convert sprite to video format */ 44 }
49 temp = SDL_DisplayFormat(sprite); 45
50 SDL_FreeSurface(sprite); 46 /* Convert sprite to video format */
51 if ( temp == NULL ) { 47 temp = SDL_DisplayFormat(sprite);
52 fprintf(stderr, "Couldn't convert background: %s\n", 48 SDL_FreeSurface(sprite);
53 SDL_GetError()); 49 if (temp == NULL) {
54 return(-1); 50 fprintf(stderr, "Couldn't convert background: %s\n", SDL_GetError());
55 } 51 return (-1);
56 sprite = temp; 52 }
57 53 sprite = temp;
58 /* We're ready to roll. :) */ 54
59 return(0); 55 /* We're ready to roll. :) */
60 } 56 return (0);
61 57 }
62 void MoveSprites(SDL_Surface *screen, Uint32 background) 58
63 { 59 void
64 int i, nupdates; 60 MoveSprites(SDL_Surface * screen, Uint32 background)
65 SDL_Rect area, *position, *velocity; 61 {
66 62 int i, nupdates;
67 nupdates = 0; 63 SDL_Rect area, *position, *velocity;
68 /* Erase all the sprites if necessary */ 64
69 if ( sprites_visible ) { 65 nupdates = 0;
70 SDL_FillRect(screen, NULL, background); 66 /* Erase all the sprites if necessary */
71 } 67 if (sprites_visible) {
72 68 SDL_FillRect(screen, NULL, background);
73 /* Move the sprite, bounce at the wall, and draw */ 69 }
74 for ( i=0; i<numsprites; ++i ) { 70
75 position = &positions[i]; 71 /* Move the sprite, bounce at the wall, and draw */
76 velocity = &velocities[i]; 72 for (i = 0; i < numsprites; ++i) {
77 position->x += velocity->x; 73 position = &positions[i];
78 if ( (position->x < 0) || (position->x >= (screen->w - sprite_w)) ) { 74 velocity = &velocities[i];
79 velocity->x = -velocity->x; 75 position->x += velocity->x;
80 position->x += velocity->x; 76 if ((position->x < 0) || (position->x >= (screen->w - sprite_w))) {
81 } 77 velocity->x = -velocity->x;
82 position->y += velocity->y; 78 position->x += velocity->x;
83 if ( (position->y < 0) || (position->y >= (screen->h - sprite_w)) ) { 79 }
84 velocity->y = -velocity->y; 80 position->y += velocity->y;
85 position->y += velocity->y; 81 if ((position->y < 0) || (position->y >= (screen->h - sprite_w))) {
86 } 82 velocity->y = -velocity->y;
87 83 position->y += velocity->y;
88 /* Blit the sprite onto the screen */ 84 }
89 area = *position; 85
90 SDL_BlitSurface(sprite, NULL, screen, &area); 86 /* Blit the sprite onto the screen */
91 sprite_rects[nupdates++] = area; 87 area = *position;
92 } 88 SDL_BlitSurface(sprite, NULL, screen, &area);
93 89 sprite_rects[nupdates++] = area;
94 if (debug_flip) { 90 }
95 if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { 91
96 static int t = 0; 92 if (debug_flip) {
97 93 if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
98 Uint32 color = SDL_MapRGB (screen->format, 255, 0, 0); 94 static int t = 0;
99 SDL_Rect r; 95
100 r.x = (sin((float)t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w-20); 96 Uint32 color = SDL_MapRGB(screen->format, 255, 0, 0);
101 r.y = 0; 97 SDL_Rect r;
102 r.w = 20; 98 r.x =
103 r.h = screen->h; 99 (sin((float) t * 2 * 3.1459) + 1.0) / 2.0 * (screen->w - 20);
104 100 r.y = 0;
105 SDL_FillRect (screen, &r, color); 101 r.w = 20;
106 t+=2; 102 r.h = screen->h;
107 } 103
108 } 104 SDL_FillRect(screen, &r, color);
109 105 t += 2;
110 /* Update the screen! */ 106 }
111 if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { 107 }
112 SDL_Flip(screen); 108
113 } else { 109 /* Update the screen! */
114 SDL_UpdateRects(screen, nupdates, sprite_rects); 110 if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
115 } 111 SDL_Flip(screen);
116 sprites_visible = 1; 112 } else {
113 SDL_UpdateRects(screen, nupdates, sprite_rects);
114 }
115 sprites_visible = 1;
117 } 116 }
118 117
119 /* This is a way of telling whether or not to use hardware surfaces */ 118 /* This is a way of telling whether or not to use hardware surfaces */
120 Uint32 FastestFlags(Uint32 flags, int width, int height, int bpp) 119 Uint32
121 { 120 FastestFlags(Uint32 flags, int width, int height, int bpp)
122 const SDL_VideoInfo *info; 121 {
123 122 const SDL_VideoInfo *info;
124 /* Hardware acceleration is only used in fullscreen mode */ 123
125 flags |= SDL_FULLSCREEN; 124 /* Hardware acceleration is only used in fullscreen mode */
126 125 flags |= SDL_FULLSCREEN;
127 /* Check for various video capabilities */ 126
128 info = SDL_GetVideoInfo(); 127 /* Check for various video capabilities */
129 if ( info->blit_hw_CC && info->blit_fill ) { 128 info = SDL_GetVideoInfo();
130 /* We use accelerated colorkeying and color filling */ 129 if (info->blit_hw_CC && info->blit_fill) {
131 flags |= SDL_HWSURFACE; 130 /* We use accelerated colorkeying and color filling */
132 } 131 flags |= SDL_HWSURFACE;
133 /* If we have enough video memory, and will use accelerated 132 }
134 blits directly to it, then use page flipping. 133 /* If we have enough video memory, and will use accelerated
135 */ 134 blits directly to it, then use page flipping.
136 if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { 135 */
137 /* Direct hardware blitting without double-buffering 136 if ((flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
138 causes really bad flickering. 137 /* Direct hardware blitting without double-buffering
139 */ 138 causes really bad flickering.
140 if ( info->video_mem*1024 > (height*width*bpp/8) ) { 139 */
141 flags |= SDL_DOUBLEBUF; 140 if (info->video_mem * 1024 > (height * width * bpp / 8)) {
142 } else { 141 flags |= SDL_DOUBLEBUF;
143 flags &= ~SDL_HWSURFACE; 142 } else {
144 } 143 flags &= ~SDL_HWSURFACE;
145 } 144 }
146 145 }
147 /* Return the flags */ 146
148 return(flags); 147 /* Return the flags */
149 } 148 return (flags);
150 149 }
151 int main(int argc, char *argv[]) 150
152 { 151 int
153 SDL_Surface *screen; 152 main(int argc, char *argv[])
154 Uint8 *mem; 153 {
155 int width, height; 154 SDL_Surface *screen;
156 Uint8 video_bpp; 155 Uint8 *mem;
157 Uint32 videoflags; 156 int width, height;
158 Uint32 background; 157 Uint8 video_bpp;
159 int i, done; 158 Uint32 videoflags;
160 SDL_Event event; 159 Uint32 background;
161 Uint32 then, now, frames; 160 int i, done;
162 161 SDL_Event event;
163 /* Initialize SDL */ 162 Uint32 then, now, frames;
164 if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { 163
165 fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); 164 /* Initialize SDL */
166 return(1); 165 if (SDL_Init(SDL_INIT_VIDEO) < 0) {
167 } 166 fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
168 167 return (1);
169 numsprites = NUM_SPRITES; 168 }
170 videoflags = SDL_SWSURFACE|SDL_ANYFORMAT; 169
171 width = 640; 170 numsprites = NUM_SPRITES;
172 height = 480; 171 videoflags = SDL_SWSURFACE | SDL_ANYFORMAT;
173 video_bpp = 8; 172 width = 640;
174 debug_flip = 0; 173 height = 480;
175 while ( argc > 1 ) { 174 video_bpp = 8;
176 --argc; 175 debug_flip = 0;
177 if ( strcmp(argv[argc-1], "-width") == 0 ) { 176 while (argc > 1) {
178 width = atoi(argv[argc]); 177 --argc;
179 --argc; 178 if (strcmp(argv[argc - 1], "-width") == 0) {
180 } else 179 width = atoi(argv[argc]);
181 if ( strcmp(argv[argc-1], "-height") == 0 ) { 180 --argc;
182 height = atoi(argv[argc]); 181 } else if (strcmp(argv[argc - 1], "-height") == 0) {
183 --argc; 182 height = atoi(argv[argc]);
184 } else 183 --argc;
185 if ( strcmp(argv[argc-1], "-bpp") == 0 ) { 184 } else if (strcmp(argv[argc - 1], "-bpp") == 0) {
186 video_bpp = atoi(argv[argc]); 185 video_bpp = atoi(argv[argc]);
187 videoflags &= ~SDL_ANYFORMAT; 186 videoflags &= ~SDL_ANYFORMAT;
188 --argc; 187 --argc;
189 } else 188 } else if (strcmp(argv[argc], "-fast") == 0) {
190 if ( strcmp(argv[argc], "-fast") == 0 ) { 189 videoflags = FastestFlags(videoflags, width, height, video_bpp);
191 videoflags = FastestFlags(videoflags, width, height, video_bpp); 190 } else if (strcmp(argv[argc], "-hw") == 0) {
192 } else 191 videoflags ^= SDL_HWSURFACE;
193 if ( strcmp(argv[argc], "-hw") == 0 ) { 192 } else if (strcmp(argv[argc], "-flip") == 0) {
194 videoflags ^= SDL_HWSURFACE; 193 videoflags ^= SDL_DOUBLEBUF;
195 } else 194 } else if (strcmp(argv[argc], "-debugflip") == 0) {
196 if ( strcmp(argv[argc], "-flip") == 0 ) { 195 debug_flip ^= 1;
197 videoflags ^= SDL_DOUBLEBUF; 196 } else if (strcmp(argv[argc], "-fullscreen") == 0) {
198 } else 197 videoflags ^= SDL_FULLSCREEN;
199 if ( strcmp(argv[argc], "-debugflip") == 0 ) { 198 } else if (isdigit(argv[argc][0])) {
200 debug_flip ^= 1; 199 numsprites = atoi(argv[argc]);
201 } else 200 } else {
202 if ( strcmp(argv[argc], "-fullscreen") == 0 ) { 201 fprintf(stderr,
203 videoflags ^= SDL_FULLSCREEN; 202 "Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n",
204 } else 203 argv[0]);
205 if ( isdigit(argv[argc][0]) ) { 204 quit(1);
206 numsprites = atoi(argv[argc]); 205 }
207 } else { 206 }
208 fprintf(stderr, 207
209 "Usage: %s [-bpp N] [-hw] [-flip] [-fast] [-fullscreen] [numsprites]\n", 208 /* Set video mode */
210 argv[0]); 209 screen = SDL_SetVideoMode(width, height, video_bpp, videoflags);
211 quit(1); 210 if (!screen) {
212 } 211 fprintf(stderr, "Couldn't set %dx%d video mode: %s\n",
213 } 212 width, height, SDL_GetError());
214 213 quit(2);
215 /* Set video mode */ 214 }
216 screen = SDL_SetVideoMode(width, height, video_bpp, videoflags); 215
217 if ( ! screen ) { 216 /* Load the sprite */
218 fprintf(stderr, "Couldn't set %dx%d video mode: %s\n", 217 if (LoadSprite("icon.bmp") < 0) {
219 width, height, SDL_GetError()); 218 quit(1);
220 quit(2); 219 }
221 } 220
222 221 /* Allocate memory for the sprite info */
223 /* Load the sprite */ 222 mem = (Uint8 *) malloc(4 * sizeof(SDL_Rect) * numsprites);
224 if ( LoadSprite("icon.bmp") < 0 ) { 223 if (mem == NULL) {
225 quit(1); 224 SDL_FreeSurface(sprite);
226 } 225 fprintf(stderr, "Out of memory!\n");
227 226 quit(2);
228 /* Allocate memory for the sprite info */ 227 }
229 mem = (Uint8 *)malloc(4*sizeof(SDL_Rect)*numsprites); 228 sprite_rects = (SDL_Rect *) mem;
230 if ( mem == NULL ) { 229 positions = sprite_rects;
231 SDL_FreeSurface(sprite); 230 sprite_rects += numsprites;
232 fprintf(stderr, "Out of memory!\n"); 231 velocities = sprite_rects;
233 quit(2); 232 sprite_rects += numsprites;
234 } 233 sprite_w = sprite->w;
235 sprite_rects = (SDL_Rect *)mem; 234 sprite_h = sprite->h;
236 positions = sprite_rects; 235 srand(time(NULL));
237 sprite_rects += numsprites; 236 for (i = 0; i < numsprites; ++i) {
238 velocities = sprite_rects; 237 positions[i].x = rand() % (screen->w - sprite_w);
239 sprite_rects += numsprites; 238 positions[i].y = rand() % (screen->h - sprite_h);
240 sprite_w = sprite->w; 239 positions[i].w = sprite->w;
241 sprite_h = sprite->h; 240 positions[i].h = sprite->h;
242 srand(time(NULL)); 241 velocities[i].x = 0;
243 for ( i=0; i<numsprites; ++i ) { 242 velocities[i].y = 0;
244 positions[i].x = rand()%(screen->w - sprite_w); 243 while (!velocities[i].x && !velocities[i].y) {
245 positions[i].y = rand()%(screen->h - sprite_h); 244 velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
246 positions[i].w = sprite->w; 245 velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
247 positions[i].h = sprite->h; 246 }
248 velocities[i].x = 0; 247 }
249 velocities[i].y = 0; 248 background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
250 while ( ! velocities[i].x && ! velocities[i].y ) { 249
251 velocities[i].x = (rand()%(MAX_SPEED*2+1))-MAX_SPEED; 250 /* Print out information about our surfaces */
252 velocities[i].y = (rand()%(MAX_SPEED*2+1))-MAX_SPEED; 251 printf("Screen is at %d bits per pixel\n", screen->format->BitsPerPixel);
253 } 252 if ((screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
254 } 253 printf("Screen is in video memory\n");
255 background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); 254 } else {
256 255 printf("Screen is in system memory\n");
257 /* Print out information about our surfaces */ 256 }
258 printf("Screen is at %d bits per pixel\n",screen->format->BitsPerPixel); 257 if ((screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
259 if ( (screen->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { 258 printf("Screen has double-buffering enabled\n");
260 printf("Screen is in video memory\n"); 259 }
261 } else { 260 if ((sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {
262 printf("Screen is in system memory\n"); 261 printf("Sprite is in video memory\n");
263 } 262 } else {
264 if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { 263 printf("Sprite is in system memory\n");
265 printf("Screen has double-buffering enabled\n"); 264 }
266 } 265 /* Run a sample blit to trigger blit acceleration */
267 if ( (sprite->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { 266 {
268 printf("Sprite is in video memory\n"); 267 SDL_Rect dst;
269 } else { 268 dst.x = 0;
270 printf("Sprite is in system memory\n"); 269 dst.y = 0;
271 } 270 dst.w = sprite->w;
272 /* Run a sample blit to trigger blit acceleration */ 271 dst.h = sprite->h;
273 { SDL_Rect dst; 272 SDL_BlitSurface(sprite, NULL, screen, &dst);
274 dst.x = 0; 273 SDL_FillRect(screen, &dst, background);
275 dst.y = 0; 274 }
276 dst.w = sprite->w; 275 if ((sprite->flags & SDL_HWACCEL) == SDL_HWACCEL) {
277 dst.h = sprite->h; 276 printf("Sprite blit uses hardware acceleration\n");
278 SDL_BlitSurface(sprite, NULL, screen, &dst); 277 }
279 SDL_FillRect(screen, &dst, background); 278 if ((sprite->flags & SDL_RLEACCEL) == SDL_RLEACCEL) {
280 } 279 printf("Sprite blit uses RLE acceleration\n");
281 if ( (sprite->flags & SDL_HWACCEL) == SDL_HWACCEL ) { 280 }
282 printf("Sprite blit uses hardware acceleration\n"); 281
283 } 282 /* Loop, blitting sprites and waiting for a keystroke */
284 if ( (sprite->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { 283 frames = 0;
285 printf("Sprite blit uses RLE acceleration\n"); 284 then = SDL_GetTicks();
286 } 285 done = 0;
287 286 sprites_visible = 0;
288 /* Loop, blitting sprites and waiting for a keystroke */ 287 while (!done) {
289 frames = 0; 288 /* Check for events */
290 then = SDL_GetTicks(); 289 ++frames;
291 done = 0; 290 while (SDL_PollEvent(&event)) {
292 sprites_visible = 0; 291 switch (event.type) {
293 while ( !done ) { 292 case SDL_MOUSEBUTTONDOWN:
294 /* Check for events */ 293 SDL_WarpMouse(screen->w / 2, screen->h / 2);
295 ++frames; 294 break;
296 while ( SDL_PollEvent(&event) ) { 295 case SDL_KEYDOWN:
297 switch (event.type) { 296 /* Any keypress quits the app... */
298 case SDL_MOUSEBUTTONDOWN: 297 case SDL_QUIT:
299 SDL_WarpMouse(screen->w/2, screen->h/2); 298 done = 1;
300 break; 299 break;
301 case SDL_KEYDOWN: 300 default:
302 /* Any keypress quits the app... */ 301 break;
303 case SDL_QUIT: 302 }
304 done = 1; 303 }
305 break; 304 MoveSprites(screen, background);
306 default: 305 }
307 break; 306 SDL_FreeSurface(sprite);
308 } 307 free(mem);
309 } 308
310 MoveSprites(screen, background); 309 /* Print out some timing information */
311 } 310 now = SDL_GetTicks();
312 SDL_FreeSurface(sprite); 311 if (now > then) {
313 free(mem); 312 printf("%2.2f frames per second\n",
314 313 ((double) frames * 1000) / (now - then));
315 /* Print out some timing information */ 314 }
316 now = SDL_GetTicks(); 315 SDL_Quit();
317 if ( now > then ) { 316 return (0);
318 printf("%2.2f frames per second\n", 317 }
319 ((double)frames*1000)/(now-then));
320 }
321 SDL_Quit();
322 return(0);
323 }