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: */