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