Mercurial > sdl-ios-xcode
comparison test/nds-test-progs/sprite2/source/testsprite2.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 | cd8978f47849 |
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 <nds.h> | |
7 #include "common.h" | |
8 | |
9 #define NUM_SPRITES 100 | |
10 #define MAX_SPEED 1 | |
11 | |
12 static CommonState *state; | |
13 static int num_sprites; | |
14 static SDL_TextureID *sprites; | |
15 static SDL_bool cycle_color; | |
16 static SDL_bool cycle_alpha; | |
17 static int cycle_direction = 1; | |
18 static int current_alpha = 0; | |
19 static int current_color = 0; | |
20 static SDL_Rect *positions; | |
21 static SDL_Rect *velocities; | |
22 static int sprite_w, sprite_h; | |
23 static SDL_TextureBlendMode blendMode = SDL_TEXTUREBLENDMODE_MASK; | |
24 static SDL_TextureScaleMode scaleMode = SDL_TEXTURESCALEMODE_NONE; | |
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 if (sprites) { | |
31 SDL_free(sprites); | |
32 } | |
33 if (positions) { | |
34 SDL_free(positions); | |
35 } | |
36 if (velocities) { | |
37 SDL_free(velocities); | |
38 } | |
39 CommonQuit(state); | |
40 exit(rc); | |
41 } | |
42 | |
43 int | |
44 LoadSprite(char *file) | |
45 { | |
46 int i; | |
47 SDL_Surface *temp; | |
48 | |
49 /* Load the sprite image */ | |
50 temp = SDL_LoadBMP(file); | |
51 if (temp == NULL) { | |
52 fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError()); | |
53 return (-1); | |
54 } | |
55 sprite_w = temp->w; | |
56 sprite_h = temp->h; | |
57 | |
58 /* Set transparent pixel as the pixel at (0,0) */ | |
59 if (temp->format->palette) { | |
60 SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels); | |
61 } | |
62 | |
63 /* Create textures from the image */ | |
64 for (i = 0; i < state->num_windows; ++i) { | |
65 SDL_SelectRenderer(state->windows[i]); | |
66 sprites[i] = SDL_CreateTextureFromSurface(0, temp); | |
67 if (!sprites[i]) { | |
68 fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError()); | |
69 SDL_FreeSurface(temp); | |
70 return (-1); | |
71 } | |
72 SDL_SetTextureBlendMode(sprites[i], blendMode); | |
73 SDL_SetTextureScaleMode(sprites[i], scaleMode); | |
74 } | |
75 SDL_FreeSurface(temp); | |
76 | |
77 /* We're ready to roll. :) */ | |
78 return (0); | |
79 } | |
80 | |
81 void | |
82 MoveSprites(SDL_WindowID window, SDL_TextureID sprite) | |
83 { | |
84 int i, n; | |
85 int window_w, window_h; | |
86 SDL_Rect area, *position, *velocity; | |
87 | |
88 SDL_SelectRenderer(window); | |
89 | |
90 /* Query the sizes */ | |
91 SDL_GetWindowSize(window, &window_w, &window_h); | |
92 | |
93 /* Cycle the color and alpha, if desired */ | |
94 if (cycle_color) { | |
95 current_color += cycle_direction; | |
96 if (current_color < 0) { | |
97 current_color = 0; | |
98 cycle_direction = -cycle_direction; | |
99 } | |
100 if (current_color > 255) { | |
101 current_color = 255; | |
102 cycle_direction = -cycle_direction; | |
103 } | |
104 SDL_SetTextureColorMod(sprite, 255, (Uint8) current_color, | |
105 (Uint8) current_color); | |
106 } | |
107 if (cycle_alpha) { | |
108 current_alpha += cycle_direction; | |
109 if (current_alpha < 0) { | |
110 current_alpha = 0; | |
111 cycle_direction = -cycle_direction; | |
112 } | |
113 if (current_alpha > 255) { | |
114 current_alpha = 255; | |
115 cycle_direction = -cycle_direction; | |
116 } | |
117 SDL_SetTextureAlphaMod(sprite, (Uint8) current_alpha); | |
118 } | |
119 | |
120 /* Move the sprite, bounce at the wall, and draw */ | |
121 n = 0; | |
122 SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL); | |
123 for (i = 0; i < num_sprites; ++i) { | |
124 position = &positions[i]; | |
125 velocity = &velocities[i]; | |
126 position->x += velocity->x; | |
127 if ((position->x < 0) || (position->x >= (window_w - sprite_w))) { | |
128 velocity->x = -velocity->x; | |
129 position->x += velocity->x; | |
130 } | |
131 position->y += velocity->y; | |
132 if ((position->y < 0) || (position->y >= (window_h - sprite_w))) { | |
133 velocity->y = -velocity->y; | |
134 position->y += velocity->y; | |
135 } | |
136 | |
137 /* Blit the sprite onto the screen */ | |
138 SDL_RenderCopy(sprite, NULL, position); | |
139 } | |
140 | |
141 /* Update the screen! */ | |
142 SDL_RenderPresent(); | |
143 } | |
144 | |
145 int | |
146 main(int argc, char *argv[]) | |
147 { | |
148 int i, done; | |
149 SDL_Event event; | |
150 Uint32 then, now, frames; | |
151 | |
152 /* Initialize parameters */ | |
153 num_sprites = NUM_SPRITES; | |
154 | |
155 /* Initialize test framework */ | |
156 state = CommonCreateState(argv, SDL_INIT_VIDEO); | |
157 if (!state) { | |
158 return 1; | |
159 } | |
160 for (i = 1; i < argc;) { | |
161 int consumed; | |
162 | |
163 consumed = CommonArg(state, i); | |
164 if (consumed == 0) { | |
165 consumed = -1; | |
166 if (SDL_strcasecmp(argv[i], "--blend") == 0) { | |
167 if (argv[i + 1]) { | |
168 if (SDL_strcasecmp(argv[i + 1], "none") == 0) { | |
169 blendMode = SDL_TEXTUREBLENDMODE_NONE; | |
170 consumed = 2; | |
171 } else if (SDL_strcasecmp(argv[i + 1], "mask") == 0) { | |
172 blendMode = SDL_TEXTUREBLENDMODE_MASK; | |
173 consumed = 2; | |
174 } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) { | |
175 blendMode = SDL_TEXTUREBLENDMODE_BLEND; | |
176 consumed = 2; | |
177 } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) { | |
178 blendMode = SDL_TEXTUREBLENDMODE_ADD; | |
179 consumed = 2; | |
180 } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) { | |
181 blendMode = SDL_TEXTUREBLENDMODE_MOD; | |
182 consumed = 2; | |
183 } | |
184 } | |
185 } else if (SDL_strcasecmp(argv[i], "--scale") == 0) { | |
186 if (argv[i + 1]) { | |
187 if (SDL_strcasecmp(argv[i + 1], "none") == 0) { | |
188 scaleMode = SDL_TEXTURESCALEMODE_NONE; | |
189 consumed = 2; | |
190 } else if (SDL_strcasecmp(argv[i + 1], "fast") == 0) { | |
191 scaleMode = SDL_TEXTURESCALEMODE_FAST; | |
192 consumed = 2; | |
193 } else if (SDL_strcasecmp(argv[i + 1], "slow") == 0) { | |
194 scaleMode = SDL_TEXTURESCALEMODE_SLOW; | |
195 consumed = 2; | |
196 } else if (SDL_strcasecmp(argv[i + 1], "best") == 0) { | |
197 scaleMode = SDL_TEXTURESCALEMODE_BEST; | |
198 consumed = 2; | |
199 } | |
200 } | |
201 } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) { | |
202 cycle_color = SDL_TRUE; | |
203 consumed = 1; | |
204 } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) { | |
205 cycle_alpha = SDL_TRUE; | |
206 consumed = 1; | |
207 } else if (SDL_isdigit(*argv[i])) { | |
208 num_sprites = SDL_atoi(argv[i]); | |
209 consumed = 1; | |
210 } | |
211 } | |
212 if (consumed < 0) { | |
213 fprintf(stderr, | |
214 "Usage: %s %s [--blend none|mask|blend|add|mod] [--scale none|fast|slow|best] [--cyclecolor] [--cyclealpha]\n", | |
215 argv[0], CommonUsage(state)); | |
216 quit(1); | |
217 } | |
218 i += consumed; | |
219 } | |
220 if (!CommonInit(state)) { | |
221 quit(2); | |
222 } | |
223 | |
224 /* Create the windows, initialize the renderers, and load the textures */ | |
225 sprites = | |
226 (SDL_TextureID *) SDL_malloc(state->num_windows * sizeof(*sprites)); | |
227 if (!sprites) { | |
228 fprintf(stderr, "Out of memory!\n"); | |
229 quit(2); | |
230 } | |
231 for (i = 0; i < state->num_windows; ++i) { | |
232 SDL_SelectRenderer(state->windows[i]); | |
233 SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL); | |
234 } | |
235 if (LoadSprite("icon.bmp") < 0) { | |
236 quit(2); | |
237 } | |
238 | |
239 /* Allocate memory for the sprite info */ | |
240 positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect)); | |
241 velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect)); | |
242 if (!positions || !velocities) { | |
243 fprintf(stderr, "Out of memory!\n"); | |
244 quit(2); | |
245 } | |
246 srand(time(NULL)); | |
247 if (scaleMode != SDL_TEXTURESCALEMODE_NONE) { | |
248 sprite_w += sprite_w / 2; | |
249 sprite_h += sprite_h / 2; | |
250 } | |
251 for (i = 0; i < num_sprites; ++i) { | |
252 positions[i].x = rand() % (state->window_w - sprite_w); | |
253 positions[i].y = rand() % (state->window_h - sprite_h); | |
254 positions[i].w = sprite_w; | |
255 positions[i].h = sprite_h; | |
256 velocities[i].x = 0; | |
257 velocities[i].y = 0; | |
258 while (!velocities[i].x && !velocities[i].y) { | |
259 velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; | |
260 velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED; | |
261 } | |
262 } | |
263 | |
264 /* Main render loop */ | |
265 frames = 0; | |
266 then = SDL_GetTicks(); | |
267 done = 0; | |
268 while (!done) { | |
269 /* Check for events */ | |
270 ++frames; | |
271 while (SDL_PollEvent(&event)) { | |
272 CommonEvent(state, &event, &done); | |
273 switch (event.type) { | |
274 case SDL_WINDOWEVENT: | |
275 switch (event.window.event) { | |
276 case SDL_WINDOWEVENT_EXPOSED: | |
277 SDL_SelectRenderer(event.window.windowID); | |
278 SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL); | |
279 break; | |
280 } | |
281 break; | |
282 default: | |
283 break; | |
284 } | |
285 } | |
286 for (i = 0; i < state->num_windows; ++i) { | |
287 MoveSprites(state->windows[i], sprites[i]); | |
288 } | |
289 } | |
290 | |
291 /* Print out some timing information */ | |
292 now = SDL_GetTicks(); | |
293 if (now > then) { | |
294 printf("%2.2f frames per second\n", | |
295 ((double) frames * 1000) / (now - then)); | |
296 } | |
297 | |
298 quit(0); | |
299 return 0; | |
300 } | |
301 | |
302 /* vi: set ts=4 sw=4 expandtab: */ |