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