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