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