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