test/testsprite2.c
author Sam Lantinga <slouken@libsdl.org>
Sat, 24 Jun 2006 16:51:01 +0000
branchSDL-1.3
changeset 1706 1577404809f0
child 1707 57ce47f033a5
permissions -rw-r--r--
Added a multi-window version of testsprite using the new API.
slouken@1706
     1
/* Simple program:  Move N sprites around on the screen as fast as possible */
slouken@1706
     2
slouken@1706
     3
#include <stdio.h>
slouken@1706
     4
#include <stdlib.h>
slouken@1706
     5
#include <string.h>
slouken@1706
     6
#include <ctype.h>
slouken@1706
     7
#include <math.h>
slouken@1706
     8
#include <time.h>
slouken@1706
     9
slouken@1706
    10
#include "SDL.h"
slouken@1706
    11
slouken@1706
    12
#define NUM_WINDOWS 2
slouken@1706
    13
#define WINDOW_W    640
slouken@1706
    14
#define WINDOW_H    480
slouken@1706
    15
#define NUM_SPRITES	100
slouken@1706
    16
#define MAX_SPEED 	1
slouken@1706
    17
slouken@1706
    18
static int num_windows;
slouken@1706
    19
static int num_sprites;
slouken@1706
    20
static SDL_WindowID *windows;
slouken@1706
    21
static SDL_TextureID *sprites;
slouken@1706
    22
static SDL_Rect *positions;
slouken@1706
    23
static SDL_Rect *velocities;
slouken@1706
    24
static int sprite_w, sprite_h;
slouken@1706
    25
slouken@1706
    26
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@1706
    27
static void
slouken@1706
    28
quit(int rc)
slouken@1706
    29
{
slouken@1706
    30
    if (windows) {
slouken@1706
    31
        SDL_free(windows);
slouken@1706
    32
    }
slouken@1706
    33
    if (sprites) {
slouken@1706
    34
        SDL_free(sprites);
slouken@1706
    35
    }
slouken@1706
    36
    if (positions) {
slouken@1706
    37
        SDL_free(positions);
slouken@1706
    38
    }
slouken@1706
    39
    if (velocities) {
slouken@1706
    40
        SDL_free(velocities);
slouken@1706
    41
    }
slouken@1706
    42
    SDL_Quit();
slouken@1706
    43
    exit(rc);
slouken@1706
    44
}
slouken@1706
    45
slouken@1706
    46
int
slouken@1706
    47
LoadSprite(char *file)
slouken@1706
    48
{
slouken@1706
    49
    int i;
slouken@1706
    50
    SDL_Surface *temp;
slouken@1706
    51
slouken@1706
    52
    /* Load the sprite image */
slouken@1706
    53
    temp = SDL_LoadBMP(file);
slouken@1706
    54
    if (temp == NULL) {
slouken@1706
    55
        fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
slouken@1706
    56
        return (-1);
slouken@1706
    57
    }
slouken@1706
    58
    sprite_w = temp->w;
slouken@1706
    59
    sprite_h = temp->h;
slouken@1706
    60
slouken@1706
    61
    /* Set transparent pixel as the pixel at (0,0) */
slouken@1706
    62
    if (temp->format->palette) {
slouken@1706
    63
        SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
slouken@1706
    64
    }
slouken@1706
    65
slouken@1706
    66
    /* Create textures from the image */
slouken@1706
    67
    for (i = 0; i < num_windows; ++i) {
slouken@1706
    68
        SDL_SelectRenderer(windows[i]);
slouken@1706
    69
        sprites[i] =
slouken@1706
    70
            SDL_CreateTextureFromSurface(0, SDL_TextureAccess_Remote, temp);
slouken@1706
    71
        if (!sprites[i]) {
slouken@1706
    72
            fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
slouken@1706
    73
            SDL_FreeSurface(temp);
slouken@1706
    74
            return (-1);
slouken@1706
    75
        }
slouken@1706
    76
    }
slouken@1706
    77
    SDL_FreeSurface(temp);
slouken@1706
    78
slouken@1706
    79
    /* We're ready to roll. :) */
slouken@1706
    80
    return (0);
slouken@1706
    81
}
slouken@1706
    82
slouken@1706
    83
void
slouken@1706
    84
MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
slouken@1706
    85
{
slouken@1706
    86
    int i, n;
slouken@1706
    87
    int window_w, window_h;
slouken@1706
    88
    SDL_Rect area, *position, *velocity;
slouken@1706
    89
slouken@1706
    90
    SDL_SelectRenderer(window);
slouken@1706
    91
slouken@1706
    92
    SDL_RenderFill(NULL, 0);
slouken@1706
    93
slouken@1706
    94
    /* Query the sizes */
slouken@1706
    95
    SDL_GetWindowSize(window, &window_w, &window_h);
slouken@1706
    96
slouken@1706
    97
    /* Move the sprite, bounce at the wall, and draw */
slouken@1706
    98
    n = 0;
slouken@1706
    99
    for (i = 0; i < num_sprites; ++i) {
slouken@1706
   100
        position = &positions[i];
slouken@1706
   101
        velocity = &velocities[i];
slouken@1706
   102
        position->x += velocity->x;
slouken@1706
   103
        if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
slouken@1706
   104
            velocity->x = -velocity->x;
slouken@1706
   105
            position->x += velocity->x;
slouken@1706
   106
        }
slouken@1706
   107
        position->y += velocity->y;
slouken@1706
   108
        if ((position->y < 0) || (position->y >= (window_h - sprite_w))) {
slouken@1706
   109
            velocity->y = -velocity->y;
slouken@1706
   110
            position->y += velocity->y;
slouken@1706
   111
        }
slouken@1706
   112
slouken@1706
   113
        /* Blit the sprite onto the screen */
slouken@1706
   114
        SDL_RenderCopy(sprite, NULL, position, SDL_TextureBlendMode_Mask,
slouken@1706
   115
                       SDL_TextureScaleMode_None);
slouken@1706
   116
    }
slouken@1706
   117
slouken@1706
   118
    /* Update the screen! */
slouken@1706
   119
    SDL_RenderPresent();
slouken@1706
   120
}
slouken@1706
   121
slouken@1706
   122
int
slouken@1706
   123
main(int argc, char *argv[])
slouken@1706
   124
{
slouken@1706
   125
    const SDL_DisplayMode *current_mode;
slouken@1706
   126
    int window_w, window_h;
slouken@1706
   127
    int i, done;
slouken@1706
   128
    SDL_Event event;
slouken@1706
   129
    Uint32 then, now, frames;
slouken@1706
   130
slouken@1706
   131
    /* Initialize SDL */
slouken@1706
   132
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
slouken@1706
   133
        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
slouken@1706
   134
        return (1);
slouken@1706
   135
    }
slouken@1706
   136
slouken@1706
   137
    num_windows = NUM_WINDOWS;
slouken@1706
   138
    num_sprites = NUM_SPRITES;
slouken@1706
   139
    window_w = WINDOW_W;
slouken@1706
   140
    window_h = WINDOW_H;
slouken@1706
   141
    while (argc > 1) {
slouken@1706
   142
        --argc;
slouken@1706
   143
        if (strcmp(argv[argc - 1], "-width") == 0) {
slouken@1706
   144
            window_w = atoi(argv[argc]);
slouken@1706
   145
            --argc;
slouken@1706
   146
        } else if (strcmp(argv[argc - 1], "-height") == 0) {
slouken@1706
   147
            window_h = atoi(argv[argc]);
slouken@1706
   148
            --argc;
slouken@1706
   149
        } else if (isdigit(argv[argc][0])) {
slouken@1706
   150
            num_sprites = atoi(argv[argc]);
slouken@1706
   151
        } else {
slouken@1706
   152
            fprintf(stderr,
slouken@1706
   153
                    "Usage: %s [-width] [-height] [numsprites]\n", argv[0]);
slouken@1706
   154
            quit(1);
slouken@1706
   155
        }
slouken@1706
   156
    }
slouken@1706
   157
slouken@1706
   158
    /* Initialize the video mode, if necessary */
slouken@1706
   159
    current_mode = SDL_GetCurrentDisplayMode();
slouken@1706
   160
    if (!current_mode->w || !current_mode->h) {
slouken@1706
   161
        SDL_DisplayMode mode;
slouken@1706
   162
slouken@1706
   163
        /* Let the driver pick something it likes, we don't care */
slouken@1706
   164
        mode.format = 0;
slouken@1706
   165
        mode.w = 0;
slouken@1706
   166
        mode.h = 0;
slouken@1706
   167
        mode.refresh_rate = 0;
slouken@1706
   168
slouken@1706
   169
        if (SDL_SetDisplayMode(&mode) < 0) {
slouken@1706
   170
            fprintf(stderr, "Couldn't set display mode: %s\n",
slouken@1706
   171
                    SDL_GetError());
slouken@1706
   172
            quit(2);
slouken@1706
   173
        }
slouken@1706
   174
    }
slouken@1706
   175
slouken@1706
   176
    /* Create the windows, initialize the renderers, and load the textures */
slouken@1706
   177
    windows = (SDL_WindowID *) SDL_malloc(num_windows * sizeof(*windows));
slouken@1706
   178
    sprites = (SDL_TextureID *) SDL_malloc(num_windows * sizeof(*sprites));
slouken@1706
   179
    if (!windows || !sprites) {
slouken@1706
   180
        fprintf(stderr, "Out of memory!\n");
slouken@1706
   181
        quit(2);
slouken@1706
   182
    }
slouken@1706
   183
    for (i = 0; i < num_windows; ++i) {
slouken@1706
   184
        char title[32];
slouken@1706
   185
slouken@1706
   186
        SDL_snprintf(title, sizeof(title), "testsprite %d", i + 1);
slouken@1706
   187
        windows[i] =
slouken@1706
   188
            SDL_CreateWindow(title, -1, -1, window_w, window_h,
slouken@1706
   189
                             SDL_WINDOW_SHOWN);
slouken@1706
   190
        if (!windows[i]) {
slouken@1706
   191
            fprintf(stderr, "Couldn't create window: %s\n", SDL_GetError());
slouken@1706
   192
            quit(2);
slouken@1706
   193
        }
slouken@1706
   194
slouken@1706
   195
        if (SDL_CreateRenderer(windows[i], -1, 0) < 0) {
slouken@1706
   196
            fprintf(stderr, "Couldn't create renderer: %s\n", SDL_GetError());
slouken@1706
   197
            quit(2);
slouken@1706
   198
        }
slouken@1706
   199
    }
slouken@1706
   200
    if (LoadSprite("icon.bmp") < 0) {
slouken@1706
   201
        quit(2);
slouken@1706
   202
    }
slouken@1706
   203
slouken@1706
   204
    /* Allocate memory for the sprite info */
slouken@1706
   205
    positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
slouken@1706
   206
    velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
slouken@1706
   207
    if (!positions || !velocities) {
slouken@1706
   208
        fprintf(stderr, "Out of memory!\n");
slouken@1706
   209
        quit(2);
slouken@1706
   210
    }
slouken@1706
   211
    srand(time(NULL));
slouken@1706
   212
    for (i = 0; i < num_sprites; ++i) {
slouken@1706
   213
        positions[i].x = rand() % (window_w - sprite_w);
slouken@1706
   214
        positions[i].y = rand() % (window_h - sprite_h);
slouken@1706
   215
        positions[i].w = sprite_w;
slouken@1706
   216
        positions[i].h = sprite_h;
slouken@1706
   217
        velocities[i].x = 0;
slouken@1706
   218
        velocities[i].y = 0;
slouken@1706
   219
        while (!velocities[i].x && !velocities[i].y) {
slouken@1706
   220
            velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
slouken@1706
   221
            velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
slouken@1706
   222
        }
slouken@1706
   223
    }
slouken@1706
   224
slouken@1706
   225
    /* Loop, blitting sprites and waiting for a keystroke */
slouken@1706
   226
    frames = 0;
slouken@1706
   227
    then = SDL_GetTicks();
slouken@1706
   228
    done = 0;
slouken@1706
   229
    while (!done) {
slouken@1706
   230
        /* Check for events */
slouken@1706
   231
        ++frames;
slouken@1706
   232
        while (SDL_PollEvent(&event)) {
slouken@1706
   233
            switch (event.type) {
slouken@1706
   234
            case SDL_KEYDOWN:
slouken@1706
   235
                /* Any keypress quits the app... */
slouken@1706
   236
            case SDL_QUIT:
slouken@1706
   237
                done = 1;
slouken@1706
   238
                break;
slouken@1706
   239
            default:
slouken@1706
   240
                break;
slouken@1706
   241
            }
slouken@1706
   242
        }
slouken@1706
   243
        for (i = 0; i < num_windows; ++i) {
slouken@1706
   244
            MoveSprites(windows[i], sprites[i]);
slouken@1706
   245
        }
slouken@1706
   246
    }
slouken@1706
   247
slouken@1706
   248
    /* Print out some timing information */
slouken@1706
   249
    now = SDL_GetTicks();
slouken@1706
   250
    if (now > then) {
slouken@1706
   251
        printf("%2.2f frames per second\n",
slouken@1706
   252
               ((double) frames * 1000) / (now - then));
slouken@1706
   253
    }
slouken@1706
   254
    quit(0);
slouken@1706
   255
}
slouken@1706
   256
slouken@1706
   257
/* vi: set ts=4 sw=4 expandtab: */