test/testsprite2.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 07 Jul 2006 08:05:39 +0000
branchSDL-1.3
changeset 1725 98a3207ddde8
parent 1724 6c63fc2bd986
child 1733 0b1070f2f94d
permissions -rw-r--r--
Implemented Win32 video mode support
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@1724
     8
#define NUM_WINDOWS 4
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@1724
    13
#define BACKGROUND  0x00FFFFFF
slouken@1706
    14
slouken@1706
    15
static int num_windows;
slouken@1706
    16
static int num_sprites;
slouken@1706
    17
static SDL_WindowID *windows;
slouken@1706
    18
static SDL_TextureID *sprites;
slouken@1706
    19
static SDL_Rect *positions;
slouken@1706
    20
static SDL_Rect *velocities;
slouken@1706
    21
static int sprite_w, sprite_h;
slouken@1706
    22
slouken@1706
    23
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@1706
    24
static void
slouken@1706
    25
quit(int rc)
slouken@1706
    26
{
slouken@1706
    27
    if (windows) {
slouken@1706
    28
        SDL_free(windows);
slouken@1706
    29
    }
slouken@1706
    30
    if (sprites) {
slouken@1706
    31
        SDL_free(sprites);
slouken@1706
    32
    }
slouken@1706
    33
    if (positions) {
slouken@1706
    34
        SDL_free(positions);
slouken@1706
    35
    }
slouken@1706
    36
    if (velocities) {
slouken@1706
    37
        SDL_free(velocities);
slouken@1706
    38
    }
slouken@1706
    39
    SDL_Quit();
slouken@1706
    40
    exit(rc);
slouken@1706
    41
}
slouken@1706
    42
slouken@1706
    43
int
slouken@1706
    44
LoadSprite(char *file)
slouken@1706
    45
{
slouken@1706
    46
    int i;
slouken@1706
    47
    SDL_Surface *temp;
slouken@1706
    48
slouken@1706
    49
    /* Load the sprite image */
slouken@1706
    50
    temp = SDL_LoadBMP(file);
slouken@1706
    51
    if (temp == NULL) {
slouken@1706
    52
        fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());
slouken@1706
    53
        return (-1);
slouken@1706
    54
    }
slouken@1706
    55
    sprite_w = temp->w;
slouken@1706
    56
    sprite_h = temp->h;
slouken@1706
    57
slouken@1706
    58
    /* Set transparent pixel as the pixel at (0,0) */
slouken@1706
    59
    if (temp->format->palette) {
slouken@1706
    60
        SDL_SetColorKey(temp, SDL_SRCCOLORKEY, *(Uint8 *) temp->pixels);
slouken@1706
    61
    }
slouken@1706
    62
slouken@1706
    63
    /* Create textures from the image */
slouken@1706
    64
    for (i = 0; i < num_windows; ++i) {
slouken@1706
    65
        SDL_SelectRenderer(windows[i]);
slouken@1706
    66
        sprites[i] =
slouken@1706
    67
            SDL_CreateTextureFromSurface(0, SDL_TextureAccess_Remote, temp);
slouken@1706
    68
        if (!sprites[i]) {
slouken@1706
    69
            fprintf(stderr, "Couldn't create texture: %s\n", SDL_GetError());
slouken@1706
    70
            SDL_FreeSurface(temp);
slouken@1706
    71
            return (-1);
slouken@1706
    72
        }
slouken@1706
    73
    }
slouken@1706
    74
    SDL_FreeSurface(temp);
slouken@1706
    75
slouken@1706
    76
    /* We're ready to roll. :) */
slouken@1706
    77
    return (0);
slouken@1706
    78
}
slouken@1706
    79
slouken@1706
    80
void
slouken@1706
    81
MoveSprites(SDL_WindowID window, SDL_TextureID sprite)
slouken@1706
    82
{
slouken@1706
    83
    int i, n;
slouken@1706
    84
    int window_w, window_h;
slouken@1706
    85
    SDL_Rect area, *position, *velocity;
slouken@1706
    86
slouken@1706
    87
    SDL_SelectRenderer(window);
slouken@1706
    88
slouken@1706
    89
    /* Query the sizes */
slouken@1706
    90
    SDL_GetWindowSize(window, &window_w, &window_h);
slouken@1706
    91
slouken@1706
    92
    /* Move the sprite, bounce at the wall, and draw */
slouken@1706
    93
    n = 0;
slouken@1706
    94
    for (i = 0; i < num_sprites; ++i) {
slouken@1706
    95
        position = &positions[i];
slouken@1724
    96
        SDL_RenderFill(position, BACKGROUND);
slouken@1724
    97
    }
slouken@1724
    98
    for (i = 0; i < num_sprites; ++i) {
slouken@1724
    99
        position = &positions[i];
slouken@1706
   100
        velocity = &velocities[i];
slouken@1706
   101
        position->x += velocity->x;
slouken@1706
   102
        if ((position->x < 0) || (position->x >= (window_w - sprite_w))) {
slouken@1706
   103
            velocity->x = -velocity->x;
slouken@1706
   104
            position->x += velocity->x;
slouken@1706
   105
        }
slouken@1706
   106
        position->y += velocity->y;
slouken@1706
   107
        if ((position->y < 0) || (position->y >= (window_h - sprite_w))) {
slouken@1706
   108
            velocity->y = -velocity->y;
slouken@1706
   109
            position->y += velocity->y;
slouken@1706
   110
        }
slouken@1706
   111
slouken@1706
   112
        /* Blit the sprite onto the screen */
slouken@1706
   113
        SDL_RenderCopy(sprite, NULL, position, SDL_TextureBlendMode_Mask,
slouken@1706
   114
                       SDL_TextureScaleMode_None);
slouken@1706
   115
    }
slouken@1706
   116
slouken@1706
   117
    /* Update the screen! */
slouken@1706
   118
    SDL_RenderPresent();
slouken@1706
   119
}
slouken@1706
   120
slouken@1706
   121
int
slouken@1706
   122
main(int argc, char *argv[])
slouken@1706
   123
{
slouken@1706
   124
    int window_w, window_h;
slouken@1725
   125
    Uint32 window_flags = SDL_WINDOW_SHOWN;
slouken@1725
   126
    SDL_DisplayMode *mode, fullscreen_mode;
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
        if (strcmp(argv[argc - 1], "-width") == 0) {
slouken@1706
   143
            window_w = atoi(argv[argc]);
slouken@1706
   144
            --argc;
slouken@1706
   145
        } else if (strcmp(argv[argc - 1], "-height") == 0) {
slouken@1706
   146
            window_h = atoi(argv[argc]);
slouken@1706
   147
            --argc;
slouken@1725
   148
        } else if (strcmp(argv[argc - 1], "-fullscreen") == 0) {
slouken@1725
   149
            num_windows = 1;
slouken@1725
   150
            window_flags |= SDL_WINDOW_FULLSCREEN;
slouken@1725
   151
            --argc;
slouken@1706
   152
        } else if (isdigit(argv[argc][0])) {
slouken@1706
   153
            num_sprites = atoi(argv[argc]);
slouken@1706
   154
        } else {
slouken@1706
   155
            fprintf(stderr,
slouken@1706
   156
                    "Usage: %s [-width] [-height] [numsprites]\n", argv[0]);
slouken@1706
   157
            quit(1);
slouken@1706
   158
        }
slouken@1706
   159
    }
slouken@1706
   160
slouken@1725
   161
    if (window_flags & SDL_WINDOW_FULLSCREEN) {
slouken@1725
   162
        SDL_zero(fullscreen_mode);
slouken@1725
   163
        fullscreen_mode.w = window_w;
slouken@1725
   164
        fullscreen_mode.h = window_h;
slouken@1725
   165
        mode = &fullscreen_mode;
slouken@1725
   166
    } else {
slouken@1725
   167
        /* Set the desktop mode, we don't care what it is */
slouken@1725
   168
        mode = NULL;
slouken@1725
   169
    }
slouken@1725
   170
    if (SDL_SetDisplayMode(mode) < 0) {
slouken@1707
   171
        fprintf(stderr, "Couldn't set display mode: %s\n", SDL_GetError());
slouken@1707
   172
        quit(2);
slouken@1706
   173
    }
slouken@1706
   174
slouken@1706
   175
    /* Create the windows, initialize the renderers, and load the textures */
slouken@1706
   176
    windows = (SDL_WindowID *) SDL_malloc(num_windows * sizeof(*windows));
slouken@1706
   177
    sprites = (SDL_TextureID *) SDL_malloc(num_windows * sizeof(*sprites));
slouken@1706
   178
    if (!windows || !sprites) {
slouken@1706
   179
        fprintf(stderr, "Out of memory!\n");
slouken@1706
   180
        quit(2);
slouken@1706
   181
    }
slouken@1706
   182
    for (i = 0; i < num_windows; ++i) {
slouken@1706
   183
        char title[32];
slouken@1706
   184
slouken@1706
   185
        SDL_snprintf(title, sizeof(title), "testsprite %d", i + 1);
slouken@1706
   186
        windows[i] =
slouken@1724
   187
            SDL_CreateWindow(title, SDL_WINDOWPOS_UNDEFINED,
slouken@1724
   188
                             SDL_WINDOWPOS_UNDEFINED, window_w, window_h,
slouken@1725
   189
                             window_flags);
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@1724
   199
        SDL_RenderFill(NULL, BACKGROUND);
slouken@1706
   200
    }
slouken@1706
   201
    if (LoadSprite("icon.bmp") < 0) {
slouken@1706
   202
        quit(2);
slouken@1706
   203
    }
slouken@1706
   204
slouken@1706
   205
    /* Allocate memory for the sprite info */
slouken@1706
   206
    positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
slouken@1706
   207
    velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
slouken@1706
   208
    if (!positions || !velocities) {
slouken@1706
   209
        fprintf(stderr, "Out of memory!\n");
slouken@1706
   210
        quit(2);
slouken@1706
   211
    }
slouken@1706
   212
    srand(time(NULL));
slouken@1706
   213
    for (i = 0; i < num_sprites; ++i) {
slouken@1706
   214
        positions[i].x = rand() % (window_w - sprite_w);
slouken@1706
   215
        positions[i].y = rand() % (window_h - sprite_h);
slouken@1706
   216
        positions[i].w = sprite_w;
slouken@1706
   217
        positions[i].h = sprite_h;
slouken@1706
   218
        velocities[i].x = 0;
slouken@1706
   219
        velocities[i].y = 0;
slouken@1706
   220
        while (!velocities[i].x && !velocities[i].y) {
slouken@1706
   221
            velocities[i].x = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
slouken@1706
   222
            velocities[i].y = (rand() % (MAX_SPEED * 2 + 1)) - MAX_SPEED;
slouken@1706
   223
        }
slouken@1706
   224
    }
slouken@1706
   225
slouken@1706
   226
    /* Loop, blitting sprites and waiting for a keystroke */
slouken@1706
   227
    frames = 0;
slouken@1706
   228
    then = SDL_GetTicks();
slouken@1706
   229
    done = 0;
slouken@1706
   230
    while (!done) {
slouken@1706
   231
        /* Check for events */
slouken@1706
   232
        ++frames;
slouken@1706
   233
        while (SDL_PollEvent(&event)) {
slouken@1706
   234
            switch (event.type) {
slouken@1724
   235
            case SDL_WINDOWEVENT:
slouken@1724
   236
                switch (event.window.event) {
slouken@1724
   237
                case SDL_WINDOWEVENT_EXPOSED:
slouken@1724
   238
                    SDL_SelectRenderer(event.window.windowID);
slouken@1724
   239
                    SDL_RenderFill(NULL, BACKGROUND);
slouken@1724
   240
                    break;
slouken@1724
   241
                case SDL_WINDOWEVENT_CLOSE:
slouken@1724
   242
                    done = 1;
slouken@1724
   243
                    break;
slouken@1724
   244
                }
slouken@1724
   245
                break;
slouken@1706
   246
            case SDL_KEYDOWN:
slouken@1706
   247
                /* Any keypress quits the app... */
slouken@1706
   248
            case SDL_QUIT:
slouken@1706
   249
                done = 1;
slouken@1706
   250
                break;
slouken@1706
   251
            default:
slouken@1706
   252
                break;
slouken@1706
   253
            }
slouken@1706
   254
        }
slouken@1706
   255
        for (i = 0; i < num_windows; ++i) {
slouken@1706
   256
            MoveSprites(windows[i], sprites[i]);
slouken@1706
   257
        }
slouken@1706
   258
    }
slouken@1706
   259
slouken@1706
   260
    /* Print out some timing information */
slouken@1706
   261
    now = SDL_GetTicks();
slouken@1706
   262
    if (now > then) {
slouken@1706
   263
        printf("%2.2f frames per second\n",
slouken@1706
   264
               ((double) frames * 1000) / (now - then));
slouken@1706
   265
    }
slouken@1706
   266
    quit(0);
slouken@1706
   267
}
slouken@1706
   268
slouken@1706
   269
/* vi: set ts=4 sw=4 expandtab: */