test/nds-test-progs/sprite2/source/testsprite2.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 27 Aug 2008 15:10:03 +0000
changeset 2735 204be4fc2726
child 2750 e3affc66d963
permissions -rwxr-xr-x
Final merge of Google Summer of Code 2008 work...

Port SDL 1.3 to the Nintendo DS
by Darren Alton, mentored by Sam Lantinga
     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: */