test/testsprite2.c
author Holmes Futrell <hfutrell@umail.ucsb.edu>
Fri, 18 Jul 2008 19:23:13 +0000
branchgsoc2008_iphone
changeset 2377 e9a0bad0ea07
parent 2222 926294b2bb4e
child 2783 e33ad7ebb7eb
permissions -rw-r--r--
Just renamed it...
     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_TextureID *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_TextureBlendMode blendMode = SDL_TEXTUREBLENDMODE_MASK;
    24 static SDL_TextureScaleMode scaleMode = SDL_TEXTURESCALEMODE_NONE;
    25 
    26 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    27 static void
    28 quit(int rc)
    29 {
    30     if (sprites) {
    31         SDL_free(sprites);
    32     }
    33     if (positions) {
    34         SDL_free(positions);
    35     }
    36     if (velocities) {
    37         SDL_free(velocities);
    38     }
    39     CommonQuit(state);
    40     exit(rc);
    41 }
    42 
    43 int
    44 LoadSprite(char *file)
    45 {
    46     int i;
    47     SDL_Surface *temp;
    48 
    49     /* Load the sprite image */
    50     temp = SDL_LoadBMP(file);
    51     if (temp == NULL) {
    52         fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
    53         return (-1);
    54     }
    55     sprite_w = temp->w;
    56     sprite_h = temp->h;
    57 
    58     /* Set transparent pixel as the pixel at (0,0) */
    59     if (temp->format->palette) {
    60         SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
    61     }
    62 
    63     /* Create textures from the image */
    64     for (i = 0; i < state->num_windows; ++i) {
    65         SDL_SelectRenderer(state->windows[i]);
    66         sprites[i] = SDL_CreateTextureFromSurface(0, temp);
    67         if (!sprites[i]) {
    68             fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
    69             SDL_FreeSurface(temp);
    70             return (-1);
    71         }
    72         SDL_SetTextureBlendMode(sprites[i], blendMode);
    73         SDL_SetTextureScaleMode(sprites[i], scaleMode);
    74     }
    75     SDL_FreeSurface(temp);
    76 
    77     /* We're ready to roll. :) */
    78     return (0);
    79 }
    80 
    81 void
    82 MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
    83 {
    84     int i, n;
    85     int window_w, window_h;
    86     SDL_Rect area, *position, *velocity;
    87 
    88     SDL_SelectRenderer(window);
    89 
    90     /* Query the sizes */
    91     SDL_GetWindowSize(window, &window_w, &window_h);
    92 
    93     /* Cycle the color and alpha, if desired */
    94     if (cycle_color) {
    95         current_color += cycle_direction;
    96         if (current_color < 0) {
    97             current_color = 0;
    98             cycle_direction = -cycle_direction;
    99         }
   100         if (current_color > 255) {
   101             current_color = 255;
   102             cycle_direction = -cycle_direction;
   103         }
   104         SDL_SetTextureColorMod(sprite, 255, (Uint8) current_color,
   105                                (Uint8) current_color);
   106     }
   107     if (cycle_alpha) {
   108         current_alpha += cycle_direction;
   109         if (current_alpha < 0) {
   110             current_alpha = 0;
   111             cycle_direction = -cycle_direction;
   112         }
   113         if (current_alpha > 255) {
   114             current_alpha = 255;
   115             cycle_direction = -cycle_direction;
   116         }
   117         SDL_SetTextureAlphaMod(sprite, (Uint8) current_alpha);
   118     }
   119 
   120     /* Move the sprite, bounce at the wall, and draw */
   121     n = 0;
   122     SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
   123     for (i = 0; i < num_sprites; ++i) {
   124         position = &positions[i];
   125         velocity = &velocities[i];
   126         position->x += velocity->x;
   127         if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
   128             velocity->x = -velocity->x;
   129             position->x += velocity->x;
   130         }
   131         position->y += velocity->y;
   132         if ((position->y < 0) || (position->y >= (window_h - sprite_w))) {
   133             velocity->y = -velocity->y;
   134             position->y += velocity->y;
   135         }
   136 
   137         /* Blit the sprite onto the screen */
   138         SDL_RenderCopy(sprite, NULL, position);
   139     }
   140 
   141     /* Update the screen! */
   142     SDL_RenderPresent();
   143 }
   144 
   145 int
   146 main(int argc, char *argv[])
   147 {
   148     int i, done;
   149     SDL_Event event;
   150     Uint32 then, now, frames;
   151 
   152     /* Initialize parameters */
   153     num_sprites = NUM_SPRITES;
   154 
   155     /* Initialize test framework */
   156     state = CommonCreateState(argv, SDL_INIT_VIDEO);
   157     if (!state) {
   158         return 1;
   159     }
   160     for (i = 1; i < argc;) {
   161         int consumed;
   162 
   163         consumed = CommonArg(state, i);
   164         if (consumed == 0) {
   165             consumed = -1;
   166             if (SDL_strcasecmp(argv[i], "--blend") == 0) {
   167                 if (argv[i + 1]) {
   168                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   169                         blendMode = SDL_TEXTUREBLENDMODE_NONE;
   170                         consumed = 2;
   171                     } else if (SDL_strcasecmp(argv[i + 1], "mask") == 0) {
   172                         blendMode = SDL_TEXTUREBLENDMODE_MASK;
   173                         consumed = 2;
   174                     } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
   175                         blendMode = SDL_TEXTUREBLENDMODE_BLEND;
   176                         consumed = 2;
   177                     } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
   178                         blendMode = SDL_TEXTUREBLENDMODE_ADD;
   179                         consumed = 2;
   180                     } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
   181                         blendMode = SDL_TEXTUREBLENDMODE_MOD;
   182                         consumed = 2;
   183                     }
   184                 }
   185             } else if (SDL_strcasecmp(argv[i], "--scale") == 0) {
   186                 if (argv[i + 1]) {
   187                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   188                         scaleMode = SDL_TEXTURESCALEMODE_NONE;
   189                         consumed = 2;
   190                     } else if (SDL_strcasecmp(argv[i + 1], "fast") == 0) {
   191                         scaleMode = SDL_TEXTURESCALEMODE_FAST;
   192                         consumed = 2;
   193                     } else if (SDL_strcasecmp(argv[i + 1], "slow") == 0) {
   194                         scaleMode = SDL_TEXTURESCALEMODE_SLOW;
   195                         consumed = 2;
   196                     } else if (SDL_strcasecmp(argv[i + 1], "best") == 0) {
   197                         scaleMode = SDL_TEXTURESCALEMODE_BEST;
   198                         consumed = 2;
   199                     }
   200                 }
   201             } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
   202                 cycle_color = SDL_TRUE;
   203                 consumed = 1;
   204             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
   205                 cycle_alpha = SDL_TRUE;
   206                 consumed = 1;
   207             } else if (SDL_isdigit(*argv[i])) {
   208                 num_sprites = SDL_atoi(argv[i]);
   209                 consumed = 1;
   210             }
   211         }
   212         if (consumed < 0) {
   213             fprintf(stderr,
   214                     "Usage: %s %s [--blend none|mask|blend|add|mod] [--scale none|fast|slow|best] [--cyclecolor] [--cyclealpha]\n",
   215                     argv[0], CommonUsage(state));
   216             quit(1);
   217         }
   218         i += consumed;
   219     }
   220     if (!CommonInit(state)) {
   221         quit(2);
   222     }
   223 
   224     /* Create the windows, initialize the renderers, and load the textures */
   225     sprites =
   226         (SDL_TextureID *) SDL_malloc(state->num_windows * sizeof(*sprites));
   227     if (!sprites) {
   228         fprintf(stderr, "Out of memory!\n");
   229         quit(2);
   230     }
   231     for (i = 0; i < state->num_windows; ++i) {
   232         SDL_SelectRenderer(state->windows[i]);
   233         SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
   234     }
   235     if (LoadSprite("icon.bmp") < 0) {
   236         quit(2);
   237     }
   238 
   239     /* Allocate memory for the sprite info */
   240     positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   241     velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   242     if (!positions || !velocities) {
   243         fprintf(stderr, "Out of memory!\n");
   244         quit(2);
   245     }
   246     srand(time(NULL));
   247     if (scaleMode != SDL_TEXTURESCALEMODE_NONE) {
   248         sprite_w += sprite_w / 2;
   249         sprite_h += sprite_h / 2;
   250     }
   251     for (i = 0; i < num_sprites; ++i) {
   252         positions[i].x = rand() % (state->window_w - sprite_w);
   253         positions[i].y = rand() % (state->window_h - sprite_h);
   254         positions[i].w = sprite_w;
   255         positions[i].h = sprite_h;
   256         velocities[i].x = 0;
   257         velocities[i].y = 0;
   258         while (!velocities[i].x && !velocities[i].y) {
   259             velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   260             velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   261         }
   262     }
   263 
   264     /* Main render loop */
   265     frames = 0;
   266     then = SDL_GetTicks();
   267     done = 0;
   268     while (!done) {
   269         /* Check for events */
   270         ++frames;
   271         while (SDL_PollEvent(&event)) {
   272             CommonEvent(state, &event, &done);
   273             switch (event.type) {
   274             case SDL_WINDOWEVENT:
   275                 switch (event.window.event) {
   276                 case SDL_WINDOWEVENT_EXPOSED:
   277                     SDL_SelectRenderer(event.window.windowID);
   278                     SDL_RenderFill(0xA0, 0xA0, 0xA0, 0xFF, NULL);
   279                     break;
   280                 }
   281                 break;
   282             default:
   283                 break;
   284             }
   285         }
   286         for (i = 0; i < state->num_windows; ++i) {
   287             MoveSprites(state->windows[i], sprites[i]);
   288         }
   289     }
   290 
   291     /* Print out some timing information */
   292     now = SDL_GetTicks();
   293     if (now > then) {
   294         printf("%2.2f frames per second\n",
   295                ((double) frames * 1000) / (now - then));
   296     }
   297     quit(0);
   298 }
   299 
   300 /* vi: set ts=4 sw=4 expandtab: */