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