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