test/testsprite2.c
author Mike Gorchak <lestat@i.com.ua>
Wed, 10 Jun 2009 05:54:19 +0000
changeset 3183 d1436442215f
parent 2884 9dde605c7540
child 3186 51750b7a966f
permissions -rw-r--r--
Support for 15/16/24/32 bpps of icon.bmp has been added, in case if not an original icon.bmp (8bpp with palette) is used for tests.
     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_BlendMode blendMode = SDL_BLENDMODE_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     } else {
    62         switch (temp->format->BitsPerPixel) {
    63         case 15:
    64             SDL_SetColorKey(temp, SDL_SRCCOLORKEY, (*(Uint16 *) temp->pixels) & 0x00007FFF);
    65             break;
    66         case 16:
    67             SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint16 *) temp->pixels);
    68             break;
    69         case 24:
    70             SDL_SetColorKey(temp, SDL_SRCCOLORKEY, (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
    71             break;
    72         case 32:
    73             SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint32 *) temp->pixels);
    74             break;
    75         }
    76     }
    77 
    78     /* Create textures from the image */
    79     for (i = 0; i < state->num_windows; ++i) {
    80         SDL_SelectRenderer(state->windows[i]);
    81         sprites[i] = SDL_CreateTextureFromSurface(0, temp);
    82         if (!sprites[i]) {
    83             fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
    84             SDL_FreeSurface(temp);
    85             return (-1);
    86         }
    87         SDL_SetTextureBlendMode(sprites[i], blendMode);
    88         SDL_SetTextureScaleMode(sprites[i], scaleMode);
    89     }
    90     SDL_FreeSurface(temp);
    91 
    92     /* We're ready to roll. :) */
    93     return (0);
    94 }
    95 
    96 void
    97 MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
    98 {
    99     int i, n;
   100     int window_w, window_h;
   101     SDL_Rect *position, *velocity;
   102 
   103     SDL_SelectRenderer(window);
   104 
   105     /* Query the sizes */
   106     SDL_GetWindowSize(window, &window_w, &window_h);
   107 
   108     /* Cycle the color and alpha, if desired */
   109     if (cycle_color) {
   110         current_color += cycle_direction;
   111         if (current_color < 0) {
   112             current_color = 0;
   113             cycle_direction = -cycle_direction;
   114         }
   115         if (current_color > 255) {
   116             current_color = 255;
   117             cycle_direction = -cycle_direction;
   118         }
   119         SDL_SetTextureColorMod(sprite, 255, (Uint8) current_color,
   120                                (Uint8) current_color);
   121     }
   122     if (cycle_alpha) {
   123         current_alpha += cycle_direction;
   124         if (current_alpha < 0) {
   125             current_alpha = 0;
   126             cycle_direction = -cycle_direction;
   127         }
   128         if (current_alpha > 255) {
   129             current_alpha = 255;
   130             cycle_direction = -cycle_direction;
   131         }
   132         SDL_SetTextureAlphaMod(sprite, (Uint8) current_alpha);
   133     }
   134 
   135     /* Move the sprite, bounce at the wall, and draw */
   136     n = 0;
   137     SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   138     SDL_RenderFill(NULL);
   139     for (i = 0; i < num_sprites; ++i) {
   140         position = &positions[i];
   141         velocity = &velocities[i];
   142         position->x += velocity->x;
   143         if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
   144             velocity->x = -velocity->x;
   145             position->x += velocity->x;
   146         }
   147         position->y += velocity->y;
   148         if ((position->y < 0) || (position->y >= (window_h - sprite_h))) {
   149             velocity->y = -velocity->y;
   150             position->y += velocity->y;
   151         }
   152 
   153         /* Blit the sprite onto the screen */
   154         SDL_RenderCopy(sprite, NULL, position);
   155     }
   156 
   157     /* Update the screen! */
   158     SDL_RenderPresent();
   159 }
   160 
   161 int
   162 main(int argc, char *argv[])
   163 {
   164     int i, done;
   165     SDL_Event event;
   166     Uint32 then, now, frames;
   167 
   168     /* Initialize parameters */
   169     num_sprites = NUM_SPRITES;
   170 
   171     /* Initialize test framework */
   172     state = CommonCreateState(argv, SDL_INIT_VIDEO);
   173     if (!state) {
   174         return 1;
   175     }
   176     for (i = 1; i < argc;) {
   177         int consumed;
   178 
   179         consumed = CommonArg(state, i);
   180         if (consumed == 0) {
   181             consumed = -1;
   182             if (SDL_strcasecmp(argv[i], "--blend") == 0) {
   183                 if (argv[i + 1]) {
   184                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   185                         blendMode = SDL_BLENDMODE_NONE;
   186                         consumed = 2;
   187                     } else if (SDL_strcasecmp(argv[i + 1], "mask") == 0) {
   188                         blendMode = SDL_BLENDMODE_MASK;
   189                         consumed = 2;
   190                     } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
   191                         blendMode = SDL_BLENDMODE_BLEND;
   192                         consumed = 2;
   193                     } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
   194                         blendMode = SDL_BLENDMODE_ADD;
   195                         consumed = 2;
   196                     } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
   197                         blendMode = SDL_BLENDMODE_MOD;
   198                         consumed = 2;
   199                     }
   200                 }
   201             } else if (SDL_strcasecmp(argv[i], "--scale") == 0) {
   202                 if (argv[i + 1]) {
   203                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   204                         scaleMode = SDL_TEXTURESCALEMODE_NONE;
   205                         consumed = 2;
   206                     } else if (SDL_strcasecmp(argv[i + 1], "fast") == 0) {
   207                         scaleMode = SDL_TEXTURESCALEMODE_FAST;
   208                         consumed = 2;
   209                     } else if (SDL_strcasecmp(argv[i + 1], "slow") == 0) {
   210                         scaleMode = SDL_TEXTURESCALEMODE_SLOW;
   211                         consumed = 2;
   212                     } else if (SDL_strcasecmp(argv[i + 1], "best") == 0) {
   213                         scaleMode = SDL_TEXTURESCALEMODE_BEST;
   214                         consumed = 2;
   215                     }
   216                 }
   217             } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
   218                 cycle_color = SDL_TRUE;
   219                 consumed = 1;
   220             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
   221                 cycle_alpha = SDL_TRUE;
   222                 consumed = 1;
   223             } else if (SDL_isdigit(*argv[i])) {
   224                 num_sprites = SDL_atoi(argv[i]);
   225                 consumed = 1;
   226             }
   227         }
   228         if (consumed < 0) {
   229             fprintf(stderr,
   230                     "Usage: %s %s [--blend none|mask|blend|add|mod] [--scale none|fast|slow|best] [--cyclecolor] [--cyclealpha]\n",
   231                     argv[0], CommonUsage(state));
   232             quit(1);
   233         }
   234         i += consumed;
   235     }
   236     if (!CommonInit(state)) {
   237         quit(2);
   238     }
   239 
   240     /* Create the windows, initialize the renderers, and load the textures */
   241     sprites =
   242         (SDL_TextureID *) SDL_malloc(state->num_windows * sizeof(*sprites));
   243     if (!sprites) {
   244         fprintf(stderr, "Out of memory!\n");
   245         quit(2);
   246     }
   247     for (i = 0; i < state->num_windows; ++i) {
   248         SDL_SelectRenderer(state->windows[i]);
   249         SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   250         SDL_RenderFill(NULL);
   251     }
   252     if (LoadSprite("icon.bmp") < 0) {
   253         quit(2);
   254     }
   255 
   256     /* Allocate memory for the sprite info */
   257     positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   258     velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   259     if (!positions || !velocities) {
   260         fprintf(stderr, "Out of memory!\n");
   261         quit(2);
   262     }
   263     srand(time(NULL));
   264     if (scaleMode != SDL_TEXTURESCALEMODE_NONE) {
   265         sprite_w += sprite_w / 2;
   266         sprite_h += sprite_h / 2;
   267     }
   268     for (i = 0; i < num_sprites; ++i) {
   269         positions[i].x = rand() % (state->window_w - sprite_w);
   270         positions[i].y = rand() % (state->window_h - sprite_h);
   271         positions[i].w = sprite_w;
   272         positions[i].h = sprite_h;
   273         velocities[i].x = 0;
   274         velocities[i].y = 0;
   275         while (!velocities[i].x && !velocities[i].y) {
   276             velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   277             velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   278         }
   279     }
   280 
   281     /* Main render loop */
   282     frames = 0;
   283     then = SDL_GetTicks();
   284     done = 0;
   285     while (!done) {
   286         /* Check for events */
   287         ++frames;
   288         while (SDL_PollEvent(&event)) {
   289             CommonEvent(state, &event, &done);
   290             switch (event.type) {
   291             case SDL_WINDOWEVENT:
   292                 switch (event.window.event) {
   293                 case SDL_WINDOWEVENT_EXPOSED:
   294                     SDL_SelectRenderer(event.window.windowID);
   295                     SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   296                     SDL_RenderFill(NULL);
   297                     break;
   298                 }
   299                 break;
   300             default:
   301                 break;
   302             }
   303         }
   304         for (i = 0; i < state->num_windows; ++i) {
   305             MoveSprites(state->windows[i], sprites[i]);
   306         }
   307     }
   308 
   309     /* Print out some timing information */
   310     now = SDL_GetTicks();
   311     if (now > then) {
   312         double fps = ((double) frames * 1000) / (now - then);
   313         printf("%2.2f frames per second\n", fps);
   314     }
   315     quit(0);
   316 }
   317 
   318 /* vi: set ts=4 sw=4 expandtab: */