test/testsprite2.c
author Ryan C. Gordon <icculus@icculus.org>
Mon, 28 Mar 2011 23:21:22 -0400
changeset 5520 09b500e0656d
parent 5297 1800dc39b74c
child 5535 96594ac5fd1a
permissions -rw-r--r--
Added orientation rotation for iOS.
     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 
     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_Texture **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_BlendMode blendMode = SDL_BLENDMODE_BLEND;
    24 
    25 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    26 static void
    27 quit(int rc)
    28 {
    29     if (sprites) {
    30         SDL_free(sprites);
    31     }
    32     if (positions) {
    33         SDL_free(positions);
    34     }
    35     if (velocities) {
    36         SDL_free(velocities);
    37     }
    38     CommonQuit(state);
    39     exit(rc);
    40 }
    41 
    42 int
    43 LoadSprite(char *file)
    44 {
    45     int i;
    46     SDL_Surface *temp;
    47 
    48     /* Load the sprite image */
    49     temp = SDL_LoadBMP(file);
    50     if (temp == NULL) {
    51         fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
    52         return (-1);
    53     }
    54     sprite_w = temp->w;
    55     sprite_h = temp->h;
    56 
    57     /* Set transparent pixel as the pixel at (0,0) */
    58     if (temp->format->palette) {
    59         SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels);
    60     } else {
    61         switch (temp->format->BitsPerPixel) {
    62         case 15:
    63             SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF);
    64             break;
    65         case 16:
    66             SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels);
    67             break;
    68         case 24:
    69             SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
    70             break;
    71         case 32:
    72             SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels);
    73             break;
    74         }
    75     }
    76 
    77     /* Create textures from the image */
    78     for (i = 0; i < state->num_windows; ++i) {
    79         SDL_Renderer *renderer = state->renderers[i];
    80         sprites[i] = SDL_CreateTextureFromSurface(renderer, temp);
    81         if (!sprites[i]) {
    82             fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
    83             SDL_FreeSurface(temp);
    84             return (-1);
    85         }
    86         SDL_SetTextureBlendMode(sprites[i], blendMode);
    87     }
    88     SDL_FreeSurface(temp);
    89 
    90     /* We're ready to roll. :) */
    91     return (0);
    92 }
    93 
    94 void
    95 MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
    96 {
    97     int i, n;
    98     SDL_Rect viewport, temp;
    99     SDL_Rect *position, *velocity;
   100 
   101     /* Query the sizes */
   102     SDL_RenderGetViewport(renderer, &viewport);
   103 
   104     /* Cycle the color and alpha, if desired */
   105     if (cycle_color) {
   106         current_color += cycle_direction;
   107         if (current_color < 0) {
   108             current_color = 0;
   109             cycle_direction = -cycle_direction;
   110         }
   111         if (current_color > 255) {
   112             current_color = 255;
   113             cycle_direction = -cycle_direction;
   114         }
   115         SDL_SetTextureColorMod(sprite, 255, (Uint8) current_color,
   116                                (Uint8) current_color);
   117     }
   118     if (cycle_alpha) {
   119         current_alpha += cycle_direction;
   120         if (current_alpha < 0) {
   121             current_alpha = 0;
   122             cycle_direction = -cycle_direction;
   123         }
   124         if (current_alpha > 255) {
   125             current_alpha = 255;
   126             cycle_direction = -cycle_direction;
   127         }
   128         SDL_SetTextureAlphaMod(sprite, (Uint8) current_alpha);
   129     }
   130 
   131     /* Draw a gray background */
   132     SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
   133     SDL_RenderClear(renderer);
   134 
   135     /* Test points */
   136     SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
   137     SDL_RenderDrawPoint(renderer, 0, 0);
   138     SDL_RenderDrawPoint(renderer, viewport.w-1, 0);
   139     SDL_RenderDrawPoint(renderer, 0, viewport.h-1);
   140     SDL_RenderDrawPoint(renderer, viewport.w-1, viewport.h-1);
   141 
   142     /* Test horizontal and vertical lines */
   143     SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
   144     SDL_RenderDrawLine(renderer, 1, 0, viewport.w-2, 0);
   145     SDL_RenderDrawLine(renderer, 1, viewport.h-1, viewport.w-2, viewport.h-1);
   146     SDL_RenderDrawLine(renderer, 0, 1, 0, viewport.h-2);
   147     SDL_RenderDrawLine(renderer, viewport.w-1, 1, viewport.w-1, viewport.h-2);
   148 
   149     /* Test fill and copy */
   150     SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
   151     temp.x = 1;
   152     temp.y = 1;
   153     temp.w = sprite_w;
   154     temp.h = sprite_h;
   155     SDL_RenderFillRect(renderer, &temp);
   156     SDL_RenderCopy(renderer, sprite, NULL, &temp);
   157     temp.x = viewport.w-sprite_w-1;
   158     temp.y = 1;
   159     temp.w = sprite_w;
   160     temp.h = sprite_h;
   161     SDL_RenderFillRect(renderer, &temp);
   162     SDL_RenderCopy(renderer, sprite, NULL, &temp);
   163     temp.x = 1;
   164     temp.y = viewport.h-sprite_h-1;
   165     temp.w = sprite_w;
   166     temp.h = sprite_h;
   167     SDL_RenderFillRect(renderer, &temp);
   168     SDL_RenderCopy(renderer, sprite, NULL, &temp);
   169     temp.x = viewport.w-sprite_w-1;
   170     temp.y = viewport.h-sprite_h-1;
   171     temp.w = sprite_w;
   172     temp.h = sprite_h;
   173     SDL_RenderFillRect(renderer, &temp);
   174     SDL_RenderCopy(renderer, sprite, NULL, &temp);
   175 
   176     /* Test diagonal lines */
   177     SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
   178     SDL_RenderDrawLine(renderer, sprite_w, sprite_h,
   179                        viewport.w-sprite_w-2, viewport.h-sprite_h-2);
   180     SDL_RenderDrawLine(renderer, viewport.w-sprite_w-2, sprite_h,
   181                        sprite_w, viewport.h-sprite_h-2);
   182 
   183     /* Move the sprite, bounce at the wall, and draw */
   184     n = 0;
   185     for (i = 0; i < num_sprites; ++i) {
   186         position = &positions[i];
   187         velocity = &velocities[i];
   188         position->x += velocity->x;
   189         if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) {
   190             velocity->x = -velocity->x;
   191             position->x += velocity->x;
   192         }
   193         position->y += velocity->y;
   194         if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) {
   195             velocity->y = -velocity->y;
   196             position->y += velocity->y;
   197         }
   198 
   199         /* Blit the sprite onto the screen */
   200         SDL_RenderCopy(renderer, sprite, NULL, position);
   201     }
   202 
   203     /* Update the screen! */
   204     SDL_RenderPresent(renderer);
   205 }
   206 
   207 int
   208 main(int argc, char *argv[])
   209 {
   210     int i, done;
   211     SDL_Event event;
   212     Uint32 then, now, frames;
   213 
   214     /* Initialize parameters */
   215     num_sprites = NUM_SPRITES;
   216 
   217     /* Initialize test framework */
   218     state = CommonCreateState(argv, SDL_INIT_VIDEO);
   219     if (!state) {
   220         return 1;
   221     }
   222 
   223     state->window_flags |= SDL_WINDOW_RESIZABLE;
   224 
   225     for (i = 1; i < argc;) {
   226         int consumed;
   227 
   228         consumed = CommonArg(state, i);
   229         if (consumed == 0) {
   230             consumed = -1;
   231             if (SDL_strcasecmp(argv[i], "--blend") == 0) {
   232                 if (argv[i + 1]) {
   233                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   234                         blendMode = SDL_BLENDMODE_NONE;
   235                         consumed = 2;
   236                     } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
   237                         blendMode = SDL_BLENDMODE_BLEND;
   238                         consumed = 2;
   239                     } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
   240                         blendMode = SDL_BLENDMODE_ADD;
   241                         consumed = 2;
   242                     } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
   243                         blendMode = SDL_BLENDMODE_MOD;
   244                         consumed = 2;
   245                     }
   246                 }
   247             } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
   248                 cycle_color = SDL_TRUE;
   249                 consumed = 1;
   250             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
   251                 cycle_alpha = SDL_TRUE;
   252                 consumed = 1;
   253             } else if (SDL_isdigit(*argv[i])) {
   254                 num_sprites = SDL_atoi(argv[i]);
   255                 consumed = 1;
   256             }
   257         }
   258         if (consumed < 0) {
   259             fprintf(stderr,
   260                     "Usage: %s %s [--blend none|blend|add|mod] [--cyclecolor] [--cyclealpha]\n",
   261                     argv[0], CommonUsage(state));
   262             quit(1);
   263         }
   264         i += consumed;
   265     }
   266     if (!CommonInit(state)) {
   267         quit(2);
   268     }
   269 
   270     /* Create the windows, initialize the renderers, and load the textures */
   271     sprites =
   272         (SDL_Texture **) SDL_malloc(state->num_windows * sizeof(*sprites));
   273     if (!sprites) {
   274         fprintf(stderr, "Out of memory!\n");
   275         quit(2);
   276     }
   277     for (i = 0; i < state->num_windows; ++i) {
   278         SDL_Renderer *renderer = state->renderers[i];
   279         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
   280         SDL_RenderClear(renderer);
   281     }
   282     if (LoadSprite("icon.bmp") < 0) {
   283         quit(2);
   284     }
   285 
   286     /* Allocate memory for the sprite info */
   287     positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   288     velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   289     if (!positions || !velocities) {
   290         fprintf(stderr, "Out of memory!\n");
   291         quit(2);
   292     }
   293     srand((unsigned int)time(NULL));
   294     for (i = 0; i < num_sprites; ++i) {
   295         positions[i].x = rand() % (state->window_w - sprite_w);
   296         positions[i].y = rand() % (state->window_h - sprite_h);
   297         positions[i].w = sprite_w;
   298         positions[i].h = sprite_h;
   299         velocities[i].x = 0;
   300         velocities[i].y = 0;
   301         while (!velocities[i].x && !velocities[i].y) {
   302             velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   303             velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   304         }
   305     }
   306 
   307     /* Main render loop */
   308     frames = 0;
   309     then = SDL_GetTicks();
   310     done = 0;
   311     while (!done) {
   312         /* Check for events */
   313         ++frames;
   314         while (SDL_PollEvent(&event)) {
   315             CommonEvent(state, &event, &done);
   316         }
   317         for (i = 0; i < state->num_windows; ++i) {
   318             MoveSprites(state->renderers[i], sprites[i]);
   319         }
   320     }
   321 
   322     /* Print out some timing information */
   323     now = SDL_GetTicks();
   324     if (now > then) {
   325         double fps = ((double) frames * 1000) / (now - then);
   326         printf("%2.2f frames per second\n", fps);
   327     }
   328     quit(0);
   329     return 0;
   330 }
   331 
   332 /* vi: set ts=4 sw=4 expandtab: */