test/testsprite2.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 11 Jan 2009 04:05:28 +0000
changeset 3017 3272431eeee2
parent 2884 9dde605c7540
child 3183 d1436442215f
permissions -rw-r--r--
Added testresample.c
     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     }
    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 *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_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   123     SDL_RenderFill(NULL);
   124     for (i = 0; i < num_sprites; ++i) {
   125         position = &positions[i];
   126         velocity = &velocities[i];
   127         position->x += velocity->x;
   128         if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
   129             velocity->x = -velocity->x;
   130             position->x += velocity->x;
   131         }
   132         position->y += velocity->y;
   133         if ((position->y < 0) || (position->y >= (window_h - sprite_h))) {
   134             velocity->y = -velocity->y;
   135             position->y += velocity->y;
   136         }
   137 
   138         /* Blit the sprite onto the screen */
   139         SDL_RenderCopy(sprite, NULL, position);
   140     }
   141 
   142     /* Update the screen! */
   143     SDL_RenderPresent();
   144 }
   145 
   146 int
   147 main(int argc, char *argv[])
   148 {
   149     int i, done;
   150     SDL_Event event;
   151     Uint32 then, now, frames;
   152 
   153     /* Initialize parameters */
   154     num_sprites = NUM_SPRITES;
   155 
   156     /* Initialize test framework */
   157     state = CommonCreateState(argv, SDL_INIT_VIDEO);
   158     if (!state) {
   159         return 1;
   160     }
   161     for (i = 1; i < argc;) {
   162         int consumed;
   163 
   164         consumed = CommonArg(state, i);
   165         if (consumed == 0) {
   166             consumed = -1;
   167             if (SDL_strcasecmp(argv[i], "--blend") == 0) {
   168                 if (argv[i + 1]) {
   169                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   170                         blendMode = SDL_BLENDMODE_NONE;
   171                         consumed = 2;
   172                     } else if (SDL_strcasecmp(argv[i + 1], "mask") == 0) {
   173                         blendMode = SDL_BLENDMODE_MASK;
   174                         consumed = 2;
   175                     } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
   176                         blendMode = SDL_BLENDMODE_BLEND;
   177                         consumed = 2;
   178                     } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
   179                         blendMode = SDL_BLENDMODE_ADD;
   180                         consumed = 2;
   181                     } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
   182                         blendMode = SDL_BLENDMODE_MOD;
   183                         consumed = 2;
   184                     }
   185                 }
   186             } else if (SDL_strcasecmp(argv[i], "--scale") == 0) {
   187                 if (argv[i + 1]) {
   188                     if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
   189                         scaleMode = SDL_TEXTURESCALEMODE_NONE;
   190                         consumed = 2;
   191                     } else if (SDL_strcasecmp(argv[i + 1], "fast") == 0) {
   192                         scaleMode = SDL_TEXTURESCALEMODE_FAST;
   193                         consumed = 2;
   194                     } else if (SDL_strcasecmp(argv[i + 1], "slow") == 0) {
   195                         scaleMode = SDL_TEXTURESCALEMODE_SLOW;
   196                         consumed = 2;
   197                     } else if (SDL_strcasecmp(argv[i + 1], "best") == 0) {
   198                         scaleMode = SDL_TEXTURESCALEMODE_BEST;
   199                         consumed = 2;
   200                     }
   201                 }
   202             } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
   203                 cycle_color = SDL_TRUE;
   204                 consumed = 1;
   205             } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
   206                 cycle_alpha = SDL_TRUE;
   207                 consumed = 1;
   208             } else if (SDL_isdigit(*argv[i])) {
   209                 num_sprites = SDL_atoi(argv[i]);
   210                 consumed = 1;
   211             }
   212         }
   213         if (consumed < 0) {
   214             fprintf(stderr,
   215                     "Usage: %s %s [--blend none|mask|blend|add|mod] [--scale none|fast|slow|best] [--cyclecolor] [--cyclealpha]\n",
   216                     argv[0], CommonUsage(state));
   217             quit(1);
   218         }
   219         i += consumed;
   220     }
   221     if (!CommonInit(state)) {
   222         quit(2);
   223     }
   224 
   225     /* Create the windows, initialize the renderers, and load the textures */
   226     sprites =
   227         (SDL_TextureID *) SDL_malloc(state->num_windows * sizeof(*sprites));
   228     if (!sprites) {
   229         fprintf(stderr, "Out of memory!\n");
   230         quit(2);
   231     }
   232     for (i = 0; i < state->num_windows; ++i) {
   233         SDL_SelectRenderer(state->windows[i]);
   234         SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   235         SDL_RenderFill(NULL);
   236     }
   237     if (LoadSprite("icon.bmp") < 0) {
   238         quit(2);
   239     }
   240 
   241     /* Allocate memory for the sprite info */
   242     positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   243     velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
   244     if (!positions || !velocities) {
   245         fprintf(stderr, "Out of memory!\n");
   246         quit(2);
   247     }
   248     srand(time(NULL));
   249     if (scaleMode != SDL_TEXTURESCALEMODE_NONE) {
   250         sprite_w += sprite_w / 2;
   251         sprite_h += sprite_h / 2;
   252     }
   253     for (i = 0; i < num_sprites; ++i) {
   254         positions[i].x = rand() % (state->window_w - sprite_w);
   255         positions[i].y = rand() % (state->window_h - sprite_h);
   256         positions[i].w = sprite_w;
   257         positions[i].h = sprite_h;
   258         velocities[i].x = 0;
   259         velocities[i].y = 0;
   260         while (!velocities[i].x && !velocities[i].y) {
   261             velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   262             velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
   263         }
   264     }
   265 
   266     /* Main render loop */
   267     frames = 0;
   268     then = SDL_GetTicks();
   269     done = 0;
   270     while (!done) {
   271         /* Check for events */
   272         ++frames;
   273         while (SDL_PollEvent(&event)) {
   274             CommonEvent(state, &event, &done);
   275             switch (event.type) {
   276             case SDL_WINDOWEVENT:
   277                 switch (event.window.event) {
   278                 case SDL_WINDOWEVENT_EXPOSED:
   279                     SDL_SelectRenderer(event.window.windowID);
   280                     SDL_SetRenderDrawColor(0xA0, 0xA0, 0xA0, 0xFF);
   281                     SDL_RenderFill(NULL);
   282                     break;
   283                 }
   284                 break;
   285             default:
   286                 break;
   287             }
   288         }
   289         for (i = 0; i < state->num_windows; ++i) {
   290             MoveSprites(state->windows[i], sprites[i]);
   291         }
   292     }
   293 
   294     /* Print out some timing information */
   295     now = SDL_GetTicks();
   296     if (now > then) {
   297         double fps = ((double) frames * 1000) / (now - then);
   298         printf("%2.2f frames per second\n", fps);
   299     }
   300     quit(0);
   301 }
   302 
   303 /* vi: set ts=4 sw=4 expandtab: */