test/nds-test-progs/sprite2/source/testsprite2.c
author Darren Alton <dalton@stevens.edu>
Sat, 06 Sep 2008 04:31:34 +0000
changeset 2750 e3affc66d963
parent 2735 204be4fc2726
child 2884 9dde605c7540
permissions -rwxr-xr-x
Fixes to the NDS sprite2 test. Illustrates partially working texture-as-sprite functionality.
     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 #define NUM_SPRITES	10
    11 #define MAX_SPEED 	1
    12 
    13 static CommonState *state;
    14 static int num_sprites;
    15 static SDL_TextureID *sprites;
    16 static SDL_bool cycle_color;
    17 static SDL_bool cycle_alpha;
    18 static int cycle_direction = 1;
    19 static int current_alpha = 0;
    20 static int current_color = 0;
    21 static SDL_Rect *positions;
    22 static SDL_Rect *velocities;
    23 static int sprite_w, sprite_h;
    24 static SDL_TextureBlendMode blendMode = SDL_TEXTUREBLENDMODE_MASK;
    25 static SDL_TextureScaleMode scaleMode = SDL_TEXTURESCALEMODE_NONE;
    26 
    27 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    28 static void
    29 quit(int rc)
    30 {
    31     if (sprites) {
    32         SDL_free(sprites);
    33     }
    34     if (positions) {
    35         SDL_free(positions);
    36     }
    37     if (velocities) {
    38         SDL_free(velocities);
    39     }
    40     CommonQuit(state);
    41     exit(rc);
    42 }
    43 
    44 int
    45 LoadSprite(char *file)
    46 {
    47     int i;
    48     SDL_Surface *temp;
    49 
    50     /* Load the sprite image */
    51     temp = SDL_LoadBMP(file);
    52     if (temp == NULL) {
    53         fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
    54         return (-1);
    55     }
    56     sprite_w = temp->w;
    57     sprite_h = temp->h;
    58 
    59     /* Set transparent pixel as the pixel at (0,0) */
    60     if (temp->format->palette) {
    61         SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
    62     }
    63 
    64     /* Create textures from the image */
    65     for (i = 0; i < state->num_windows; ++i) {
    66         SDL_SelectRenderer(state->windows[i]);
    67         sprites[i] = SDL_CreateTextureFromSurface(0, temp);
    68         if (!sprites[i]) {
    69             fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
    70             SDL_FreeSurface(temp);
    71             return (-1);
    72         }
    73         SDL_SetTextureBlendMode(sprites[i], blendMode);
    74         SDL_SetTextureScaleMode(sprites[i], scaleMode);
    75     }
    76     SDL_FreeSurface(temp);
    77 
    78     /* We're ready to roll. :) */
    79     return (0);
    80 }
    81 
    82 int
    83 LoadSprite2(const u8 * ptr, int size)
    84 {
    85     int i;
    86     SDL_Rect r = { 0, 0, 32, 32 };
    87     for (i = 0; i < state->num_windows; ++i) {
    88         SDL_SelectRenderer(state->windows[i]);
    89         sprites[i] = SDL_CreateTexture(SDL_PIXELFORMAT_ABGR1555,
    90                                        SDL_TEXTUREACCESS_STATIC, r.w, r.h);
    91         if (!sprites[i]) {
    92             fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
    93             return -1;
    94         }
    95         SDL_UpdateTexture(sprites[i], &r, ptr, r.w * 2);
    96         SDL_SetTextureBlendMode(sprites[i], blendMode);
    97         SDL_SetTextureScaleMode(sprites[i], scaleMode);
    98     }
    99     return 0;
   100 }
   101 
   102 void
   103 MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
   104 {
   105     int i, n;
   106     int window_w, window_h;
   107     SDL_Rect area, *position, *velocity;
   108 
   109     SDL_SelectRenderer(window);
   110 
   111     /* Query the sizes */
   112     SDL_GetWindowSize(window, &window_w, &window_h);
   113 
   114     /* Cycle the color and alpha, if desired */
   115     if (cycle_color) {
   116         current_color += cycle_direction;
   117         if (current_color < 0) {
   118             current_color = 0;
   119             cycle_direction = -cycle_direction;
   120         }
   121         if (current_color > 255) {
   122             current_color = 255;
   123             cycle_direction = -cycle_direction;
   124         }
   125         SDL_SetTextureColorMod(sprite, 255, (Uint8) current_color,
   126                                (Uint8) current_color);
   127     }
   128     if (cycle_alpha) {
   129         current_alpha += cycle_direction;
   130         if (current_alpha < 0) {
   131             current_alpha = 0;
   132             cycle_direction = -cycle_direction;
   133         }
   134         if (current_alpha > 255) {
   135             current_alpha = 255;
   136             cycle_direction = -cycle_direction;
   137         }
   138         SDL_SetTextureAlphaMod(sprite, (Uint8) current_alpha);
   139     }
   140 
   141     /* Move the sprite, bounce at the wall, and draw */
   142     n = 0;
   143     SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
   144     for (i = 0; i < num_sprites; ++i) {
   145         position = &positions[i];
   146         velocity = &velocities[i];
   147         position->x += velocity->x;
   148         if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
   149             velocity->x = -velocity->x;
   150             position->x += velocity->x;
   151         }
   152         position->y += velocity->y;
   153         if ((position->y < 0) || (position->y >= (window_h - sprite_w))) {
   154             velocity->y = -velocity->y;
   155             position->y += velocity->y;
   156         }
   157 
   158         /* Blit the sprite onto the screen */
   159         SDL_RenderCopy(sprite, NULL, position);
   160     }
   161 
   162     /* Update the screen! */
   163     SDL_RenderPresent();
   164 }
   165 
   166 int
   167 main(int argc, char *argv[])
   168 {
   169     int i, done;
   170     SDL_Event event;
   171     Uint32 then, now, frames;
   172 
   173     consoleDemoInit();
   174     puts("Hello world!  Initializing FAT...");
   175     fatInitDefault();
   176 
   177     /* Initialize parameters */
   178     num_sprites = NUM_SPRITES;
   179 
   180     /* Initialize test framework */
   181     state = CommonCreateState(argv, SDL_INIT_VIDEO);
   182     if (!state) {
   183         return 1;
   184     }
   185 
   186     if (!CommonInit(state)) {
   187         quit(2);
   188     }
   189 
   190     /* Create the windows, initialize the renderers, and load the textures */
   191     sprites =
   192         (SDL_TextureID *) SDL_malloc(state->num_windows * sizeof(*sprites));
   193     if (!sprites) {
   194         fprintf(stderr, "Out of memory!\n");
   195         quit(2);
   196     }
   197     for (i = 0; i < state->num_windows; ++i) {
   198         SDL_SelectRenderer(state->windows[i]);
   199         SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
   200     }
   201     if (LoadSprite("icon.bmp") < 0) {
   202         printf("\nerrored.\n");
   203         while (1);
   204         quit(2);
   205     }
   206 
   207     /* Allocate memory for the sprite info */
   208     positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   209     velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   210     if (!positions || !velocities) {
   211         fprintf(stderr, "Out of memory!\n");
   212         quit(2);
   213     }
   214     srand(time(NULL));
   215     if (scaleMode != SDL_TEXTURESCALEMODE_NONE) {
   216         sprite_w += sprite_w / 2;
   217         sprite_h += sprite_h / 2;
   218     }
   219     for (i = 0; i < num_sprites; ++i) {
   220         positions[i].x = rand() % (state->window_w - sprite_w);
   221         positions[i].y = rand() % (state->window_h - sprite_h);
   222         positions[i].w = sprite_w;
   223         positions[i].h = sprite_h;
   224         velocities[i].x = 0;
   225         velocities[i].y = 0;
   226         while (!velocities[i].x && !velocities[i].y) {
   227             velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   228             velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   229         }
   230     }
   231 
   232     /* Main render loop */
   233     frames = 0;
   234     then = SDL_GetTicks();
   235     done = 0;
   236     while (!done) {
   237         /* Check for events */
   238         ++frames;
   239         while (SDL_PollEvent(&event)) {
   240             CommonEvent(state, &event, &done);
   241             switch (event.type) {
   242             case SDL_WINDOWEVENT:
   243                 switch (event.window.event) {
   244                 case SDL_WINDOWEVENT_EXPOSED:
   245                     SDL_SelectRenderer(event.window.windowID);
   246                     SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
   247                     break;
   248                 }
   249                 break;
   250             default:
   251                 break;
   252             }
   253         }
   254         for (i = 0; i < state->num_windows; ++i) {
   255             MoveSprites(state->windows[i], sprites[i]);
   256         }
   257     }
   258 
   259     /* Print out some timing information */
   260     now = SDL_GetTicks();
   261     if (now > then) {
   262         printf("%2.2f frames per second\n",
   263                ((double) frames * 1000) / (now - then));
   264     }
   265 
   266     quit(0);
   267     return 0;
   268 }
   269 
   270 /* vi: set ts=4 sw=4 expandtab: */