test/testsprite2.c
author Alex Baines <alex@abaines.me.uk>
Tue, 19 Aug 2014 23:31:50 +0100
changeset 9097 56d712662a82
parent 8149 681eb46b8ac4
child 9278 8900afb78a19
permissions -rw-r--r--
Add a SDL_IM_INTERNAL_EDITING event to make IMs like iBus render editing text in its own UI instead of sending TEXTEDITING events.
This is useful for applications that handle TEXTINPUT events but not TEXTEDITING events.
slouken@5535
     1
/*
slouken@8149
     2
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@1895
    12
/* Simple program:  Move N sprites around on the screen as fast as possible */
slouken@1895
    13
slouken@1895
    14
#include <stdlib.h>
slouken@1907
    15
#include <stdio.h>
slouken@1895
    16
#include <time.h>
slouken@1895
    17
aschiffler@7315
    18
#include "SDL_test.h"
slouken@6785
    19
#include "SDL_test_common.h"
slouken@1895
    20
slouken@5147
    21
#define NUM_SPRITES    100
slouken@5147
    22
#define MAX_SPEED     1
slouken@1895
    23
slouken@6785
    24
static SDLTest_CommonState *state;
slouken@1895
    25
static int num_sprites;
slouken@3685
    26
static SDL_Texture **sprites;
slouken@1985
    27
static SDL_bool cycle_color;
slouken@1985
    28
static SDL_bool cycle_alpha;
slouken@1985
    29
static int cycle_direction = 1;
slouken@1985
    30
static int current_alpha = 0;
slouken@1985
    31
static int current_color = 0;
slouken@1895
    32
static SDL_Rect *positions;
slouken@1895
    33
static SDL_Rect *velocities;
slouken@1895
    34
static int sprite_w, sprite_h;
slouken@5140
    35
static SDL_BlendMode blendMode = SDL_BLENDMODE_BLEND;
slouken@1895
    36
aschiffler@7315
    37
/* Number of iterations to move sprites - used for visual tests. */
aschiffler@7315
    38
/* -1: infinite random moves (default); >=0: enables N deterministic moves */
aschiffler@7315
    39
static int iterations = -1;
aschiffler@7315
    40
slouken@1895
    41
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@1895
    42
static void
slouken@1895
    43
quit(int rc)
slouken@1895
    44
{
slouken@7719
    45
    SDL_free(sprites);
slouken@7719
    46
    SDL_free(positions);
slouken@7719
    47
    SDL_free(velocities);
slouken@6785
    48
    SDLTest_CommonQuit(state);
slouken@1895
    49
    exit(rc);
slouken@1895
    50
}
slouken@1895
    51
slouken@1895
    52
int
slouken@7502
    53
LoadSprite(const char *file)
slouken@1895
    54
{
slouken@1895
    55
    int i;
slouken@1895
    56
    SDL_Surface *temp;
slouken@1895
    57
slouken@1895
    58
    /* Load the sprite image */
slouken@1895
    59
    temp = SDL_LoadBMP(file);
slouken@1895
    60
    if (temp == NULL) {
aschiffler@7639
    61
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
slouken@1895
    62
        return (-1);
slouken@1895
    63
    }
slouken@1895
    64
    sprite_w = temp->w;
slouken@1895
    65
    sprite_h = temp->h;
slouken@1895
    66
slouken@1895
    67
    /* Set transparent pixel as the pixel at (0,0) */
slouken@1895
    68
    if (temp->format->palette) {
slouken@3560
    69
        SDL_SetColorKey(temp, 1, *(Uint8 *) temp->pixels);
lestat@3183
    70
    } else {
lestat@3183
    71
        switch (temp->format->BitsPerPixel) {
lestat@3183
    72
        case 15:
slouken@3560
    73
            SDL_SetColorKey(temp, 1, (*(Uint16 *) temp->pixels) & 0x00007FFF);
lestat@3183
    74
            break;
lestat@3183
    75
        case 16:
slouken@3560
    76
            SDL_SetColorKey(temp, 1, *(Uint16 *) temp->pixels);
lestat@3183
    77
            break;
lestat@3183
    78
        case 24:
slouken@3560
    79
            SDL_SetColorKey(temp, 1, (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
lestat@3183
    80
            break;
lestat@3183
    81
        case 32:
slouken@3560
    82
            SDL_SetColorKey(temp, 1, *(Uint32 *) temp->pixels);
lestat@3183
    83
            break;
lestat@3183
    84
        }
slouken@1895
    85
    }
slouken@1895
    86
slouken@1895
    87
    /* Create textures from the image */
slouken@1914
    88
    for (i = 0; i < state->num_windows; ++i) {
slouken@5147
    89
        SDL_Renderer *renderer = state->renderers[i];
slouken@5158
    90
        sprites[i] = SDL_CreateTextureFromSurface(renderer, temp);
slouken@3285
    91
        if (!sprites[i]) {
aschiffler@7639
    92
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
slouken@1895
    93
            SDL_FreeSurface(temp);
slouken@1895
    94
            return (-1);
slouken@1895
    95
        }
slouken@1985
    96
        SDL_SetTextureBlendMode(sprites[i], blendMode);
slouken@1895
    97
    }
slouken@1895
    98
    SDL_FreeSurface(temp);
slouken@1895
    99
slouken@1895
   100
    /* We're ready to roll. :) */
slouken@1895
   101
    return (0);
slouken@1895
   102
}
slouken@1895
   103
slouken@1895
   104
void
slouken@5297
   105
MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
slouken@1895
   106
{
aschiffler@7315
   107
    int i;
slouken@5297
   108
    SDL_Rect viewport, temp;
slouken@2783
   109
    SDL_Rect *position, *velocity;
slouken@1895
   110
slouken@1895
   111
    /* Query the sizes */
slouken@5297
   112
    SDL_RenderGetViewport(renderer, &viewport);
slouken@1895
   113
slouken@1985
   114
    /* Cycle the color and alpha, if desired */
slouken@1985
   115
    if (cycle_color) {
slouken@1985
   116
        current_color += cycle_direction;
slouken@1985
   117
        if (current_color < 0) {
slouken@1985
   118
            current_color = 0;
slouken@1985
   119
            cycle_direction = -cycle_direction;
slouken@1985
   120
        }
slouken@1985
   121
        if (current_color > 255) {
slouken@1985
   122
            current_color = 255;
slouken@1985
   123
            cycle_direction = -cycle_direction;
slouken@1985
   124
        }
slouken@1985
   125
        SDL_SetTextureColorMod(sprite, 255, (Uint8) current_color,
slouken@1985
   126
                               (Uint8) current_color);
slouken@1985
   127
    }
slouken@1985
   128
    if (cycle_alpha) {
slouken@1985
   129
        current_alpha += cycle_direction;
slouken@1985
   130
        if (current_alpha < 0) {
slouken@1985
   131
            current_alpha = 0;
slouken@1985
   132
            cycle_direction = -cycle_direction;
slouken@1985
   133
        }
slouken@1985
   134
        if (current_alpha > 255) {
slouken@1985
   135
            current_alpha = 255;
slouken@1985
   136
            cycle_direction = -cycle_direction;
slouken@1985
   137
        }
slouken@1985
   138
        SDL_SetTextureAlphaMod(sprite, (Uint8) current_alpha);
slouken@1985
   139
    }
slouken@1985
   140
slouken@3264
   141
    /* Draw a gray background */
slouken@5147
   142
    SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
slouken@5147
   143
    SDL_RenderClear(renderer);
slouken@3264
   144
slouken@3265
   145
    /* Test points */
slouken@5147
   146
    SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
slouken@5147
   147
    SDL_RenderDrawPoint(renderer, 0, 0);
slouken@5297
   148
    SDL_RenderDrawPoint(renderer, viewport.w-1, 0);
slouken@5297
   149
    SDL_RenderDrawPoint(renderer, 0, viewport.h-1);
slouken@5297
   150
    SDL_RenderDrawPoint(renderer, viewport.w-1, viewport.h-1);
slouken@3264
   151
slouken@3265
   152
    /* Test horizontal and vertical lines */
slouken@5147
   153
    SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
slouken@5297
   154
    SDL_RenderDrawLine(renderer, 1, 0, viewport.w-2, 0);
slouken@5297
   155
    SDL_RenderDrawLine(renderer, 1, viewport.h-1, viewport.w-2, viewport.h-1);
slouken@5297
   156
    SDL_RenderDrawLine(renderer, 0, 1, 0, viewport.h-2);
slouken@5297
   157
    SDL_RenderDrawLine(renderer, viewport.w-1, 1, viewport.w-1, viewport.h-2);
slouken@3265
   158
slouken@3266
   159
    /* Test fill and copy */
slouken@5147
   160
    SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
slouken@3266
   161
    temp.x = 1;
slouken@3266
   162
    temp.y = 1;
slouken@3266
   163
    temp.w = sprite_w;
slouken@3266
   164
    temp.h = sprite_h;
slouken@5147
   165
    SDL_RenderFillRect(renderer, &temp);
slouken@5147
   166
    SDL_RenderCopy(renderer, sprite, NULL, &temp);
slouken@5297
   167
    temp.x = viewport.w-sprite_w-1;
slouken@3265
   168
    temp.y = 1;
slouken@3265
   169
    temp.w = sprite_w;
slouken@3265
   170
    temp.h = sprite_h;
slouken@5147
   171
    SDL_RenderFillRect(renderer, &temp);
slouken@5147
   172
    SDL_RenderCopy(renderer, sprite, NULL, &temp);
slouken@3265
   173
    temp.x = 1;
slouken@5297
   174
    temp.y = viewport.h-sprite_h-1;
slouken@3265
   175
    temp.w = sprite_w;
slouken@3265
   176
    temp.h = sprite_h;
slouken@5147
   177
    SDL_RenderFillRect(renderer, &temp);
slouken@5147
   178
    SDL_RenderCopy(renderer, sprite, NULL, &temp);
slouken@5297
   179
    temp.x = viewport.w-sprite_w-1;
slouken@5297
   180
    temp.y = viewport.h-sprite_h-1;
slouken@3265
   181
    temp.w = sprite_w;
slouken@3265
   182
    temp.h = sprite_h;
slouken@5147
   183
    SDL_RenderFillRect(renderer, &temp);
slouken@5147
   184
    SDL_RenderCopy(renderer, sprite, NULL, &temp);
slouken@3265
   185
slouken@3265
   186
    /* Test diagonal lines */
slouken@5147
   187
    SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
slouken@5147
   188
    SDL_RenderDrawLine(renderer, sprite_w, sprite_h,
slouken@5297
   189
                       viewport.w-sprite_w-2, viewport.h-sprite_h-2);
slouken@5297
   190
    SDL_RenderDrawLine(renderer, viewport.w-sprite_w-2, sprite_h,
slouken@5297
   191
                       sprite_w, viewport.h-sprite_h-2);
slouken@3265
   192
aschiffler@7315
   193
    /* Conditionally move the sprites, bounce at the wall */
aschiffler@7315
   194
    if (iterations == -1 || iterations > 0) {
aschiffler@7315
   195
        for (i = 0; i < num_sprites; ++i) {
aschiffler@7315
   196
            position = &positions[i];
aschiffler@7315
   197
            velocity = &velocities[i];
aschiffler@7315
   198
            position->x += velocity->x;
aschiffler@7315
   199
            if ((position->x < 0) || (position->x >= (viewport.w - sprite_w))) {
aschiffler@7315
   200
            	velocity->x = -velocity->x;
aschiffler@7315
   201
            	position->x += velocity->x;
aschiffler@7315
   202
            }
aschiffler@7315
   203
            position->y += velocity->y;
aschiffler@7315
   204
            if ((position->y < 0) || (position->y >= (viewport.h - sprite_h))) {
aschiffler@7315
   205
            	velocity->y = -velocity->y;
aschiffler@7315
   206
            	position->y += velocity->y;
aschiffler@7315
   207
            }
aschiffler@7315
   208
aschiffler@7315
   209
        }
aschiffler@7315
   210
        
aschiffler@7315
   211
        /* Countdown sprite-move iterations and disable color changes at iteration end - used for visual tests. */
aschiffler@7315
   212
        if (iterations > 0) {
aschiffler@7315
   213
            iterations--;
aschiffler@7315
   214
            if (iterations == 0) {
aschiffler@7315
   215
                cycle_alpha = SDL_FALSE;
aschiffler@7315
   216
                cycle_color = SDL_FALSE;
aschiffler@7315
   217
            }
aschiffler@7315
   218
        }
aschiffler@7315
   219
    }
aschiffler@7315
   220
aschiffler@7315
   221
    /* Draw sprites */
slouken@1895
   222
    for (i = 0; i < num_sprites; ++i) {
slouken@1895
   223
        position = &positions[i];
aschiffler@7315
   224
		
slouken@1895
   225
        /* Blit the sprite onto the screen */
slouken@5147
   226
        SDL_RenderCopy(renderer, sprite, NULL, position);
slouken@1895
   227
    }
slouken@1895
   228
slouken@1895
   229
    /* Update the screen! */
slouken@5147
   230
    SDL_RenderPresent(renderer);
slouken@1895
   231
}
slouken@1895
   232
slouken@1895
   233
int
slouken@1895
   234
main(int argc, char *argv[])
slouken@1895
   235
{
slouken@1895
   236
    int i, done;
slouken@1895
   237
    SDL_Event event;
slouken@1895
   238
    Uint32 then, now, frames;
aschiffler@7315
   239
	Uint64 seed;
slouken@7502
   240
    const char *icon = "icon.bmp";
slouken@1895
   241
slouken@1914
   242
    /* Initialize parameters */
slouken@1914
   243
    num_sprites = NUM_SPRITES;
slouken@1914
   244
slouken@1914
   245
    /* Initialize test framework */
slouken@6785
   246
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
slouken@1914
   247
    if (!state) {
slouken@1914
   248
        return 1;
slouken@1895
   249
    }
icculus@5520
   250
slouken@1914
   251
    for (i = 1; i < argc;) {
slouken@1914
   252
        int consumed;
slouken@1895
   253
slouken@6785
   254
        consumed = SDLTest_CommonArg(state, i);
slouken@1915
   255
        if (consumed == 0) {
slouken@1916
   256
            consumed = -1;
slouken@1916
   257
            if (SDL_strcasecmp(argv[i], "--blend") == 0) {
slouken@1916
   258
                if (argv[i + 1]) {
slouken@1916
   259
                    if (SDL_strcasecmp(argv[i + 1], "none") == 0) {
slouken@2884
   260
                        blendMode = SDL_BLENDMODE_NONE;
slouken@1916
   261
                        consumed = 2;
slouken@1916
   262
                    } else if (SDL_strcasecmp(argv[i + 1], "blend") == 0) {
slouken@2884
   263
                        blendMode = SDL_BLENDMODE_BLEND;
slouken@1916
   264
                        consumed = 2;
slouken@1916
   265
                    } else if (SDL_strcasecmp(argv[i + 1], "add") == 0) {
slouken@2884
   266
                        blendMode = SDL_BLENDMODE_ADD;
slouken@1916
   267
                        consumed = 2;
slouken@5184
   268
                    } else if (SDL_strcasecmp(argv[i + 1], "mod") == 0) {
slouken@5184
   269
                        blendMode = SDL_BLENDMODE_MOD;
slouken@5184
   270
                        consumed = 2;
slouken@1916
   271
                    }
slouken@1916
   272
                }
aschiffler@7315
   273
            } else if (SDL_strcasecmp(argv[i], "--iterations") == 0) {
aschiffler@7315
   274
                if (argv[i + 1]) {
aschiffler@7315
   275
                    iterations = SDL_atoi(argv[i + 1]);
aschiffler@7315
   276
                    if (iterations < -1) iterations = -1;
aschiffler@7315
   277
                    consumed = 2;
aschiffler@7315
   278
                }
slouken@1985
   279
            } else if (SDL_strcasecmp(argv[i], "--cyclecolor") == 0) {
slouken@1985
   280
                cycle_color = SDL_TRUE;
slouken@1985
   281
                consumed = 1;
slouken@1985
   282
            } else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
slouken@1985
   283
                cycle_alpha = SDL_TRUE;
slouken@1985
   284
                consumed = 1;
slouken@1916
   285
            } else if (SDL_isdigit(*argv[i])) {
slouken@1916
   286
                num_sprites = SDL_atoi(argv[i]);
slouken@1916
   287
                consumed = 1;
slouken@7502
   288
            } else if (argv[i][0] != '-') {
slouken@7502
   289
                icon = argv[i];
slouken@7502
   290
                consumed = 1;
slouken@1916
   291
            }
slouken@1915
   292
        }
slouken@1914
   293
        if (consumed < 0) {
aschiffler@7639
   294
            SDL_Log("Usage: %s %s [--blend none|blend|add|mod] [--cyclecolor] [--cyclealpha] [--iterations N] [num_sprites] [icon.bmp]\n",
slouken@6785
   295
                    argv[0], SDLTest_CommonUsage(state));
slouken@1895
   296
            quit(1);
slouken@1895
   297
        }
slouken@1914
   298
        i += consumed;
slouken@1895
   299
    }
slouken@6785
   300
    if (!SDLTest_CommonInit(state)) {
slouken@1914
   301
        quit(2);
slouken@1895
   302
    }
slouken@1895
   303
slouken@1895
   304
    /* Create the windows, initialize the renderers, and load the textures */
slouken@1914
   305
    sprites =
slouken@3685
   306
        (SDL_Texture **) SDL_malloc(state->num_windows * sizeof(*sprites));
slouken@1914
   307
    if (!sprites) {
aschiffler@7639
   308
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n");
slouken@1895
   309
        quit(2);
slouken@1895
   310
    }
slouken@1914
   311
    for (i = 0; i < state->num_windows; ++i) {
slouken@5147
   312
        SDL_Renderer *renderer = state->renderers[i];
slouken@5147
   313
        SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
slouken@5147
   314
        SDL_RenderClear(renderer);
slouken@1895
   315
    }
slouken@7502
   316
    if (LoadSprite(icon) < 0) {
slouken@1895
   317
        quit(2);
slouken@1895
   318
    }
slouken@1895
   319
slouken@1895
   320
    /* Allocate memory for the sprite info */
slouken@1895
   321
    positions = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
slouken@1895
   322
    velocities = (SDL_Rect *) SDL_malloc(num_sprites * sizeof(SDL_Rect));
slouken@1895
   323
    if (!positions || !velocities) {
aschiffler@7639
   324
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Out of memory!\n");
slouken@1895
   325
        quit(2);
slouken@1895
   326
    }
aschiffler@7315
   327
aschiffler@7315
   328
    /* Position sprites and set their velocities using the fuzzer */ 
aschiffler@7315
   329
    if (iterations >= 0) {
aschiffler@7315
   330
        /* Deterministic seed - used for visual tests */
aschiffler@7315
   331
        seed = (Uint64)iterations;
aschiffler@7315
   332
    } else {
aschiffler@7315
   333
        /* Pseudo-random seed generated from the time */
aschiffler@7315
   334
        seed = (Uint64)time(NULL);
aschiffler@7315
   335
    }
aschiffler@7315
   336
    SDLTest_FuzzerInit(seed);
slouken@1895
   337
    for (i = 0; i < num_sprites; ++i) {
aschiffler@7315
   338
        positions[i].x = SDLTest_RandomIntegerInRange(0, state->window_w - sprite_w);
aschiffler@7315
   339
        positions[i].y = SDLTest_RandomIntegerInRange(0, state->window_h - sprite_h);
slouken@1895
   340
        positions[i].w = sprite_w;
slouken@1895
   341
        positions[i].h = sprite_h;
slouken@1895
   342
        velocities[i].x = 0;
slouken@1895
   343
        velocities[i].y = 0;
slouken@1895
   344
        while (!velocities[i].x && !velocities[i].y) {
aschiffler@7315
   345
            velocities[i].x = SDLTest_RandomIntegerInRange(-MAX_SPEED, MAX_SPEED);
aschiffler@7315
   346
            velocities[i].y = SDLTest_RandomIntegerInRange(-MAX_SPEED, MAX_SPEED);
slouken@1895
   347
        }
slouken@1895
   348
    }
slouken@1895
   349
slouken@1915
   350
    /* Main render loop */
slouken@1895
   351
    frames = 0;
slouken@1895
   352
    then = SDL_GetTicks();
slouken@1895
   353
    done = 0;
slouken@1895
   354
    while (!done) {
slouken@1895
   355
        /* Check for events */
slouken@1895
   356
        ++frames;
slouken@1895
   357
        while (SDL_PollEvent(&event)) {
slouken@6785
   358
            SDLTest_CommonEvent(state, &event, &done);
slouken@1895
   359
        }
slouken@1914
   360
        for (i = 0; i < state->num_windows; ++i) {
slouken@7787
   361
            if (state->windows[i] == NULL)
slouken@7787
   362
                continue;
slouken@5297
   363
            MoveSprites(state->renderers[i], sprites[i]);
slouken@1895
   364
        }
slouken@1895
   365
    }
slouken@1895
   366
slouken@1895
   367
    /* Print out some timing information */
slouken@1895
   368
    now = SDL_GetTicks();
slouken@1895
   369
    if (now > then) {
slouken@2786
   370
        double fps = ((double) frames * 1000) / (now - then);
aschiffler@7639
   371
        SDL_Log("%2.2f frames per second\n", fps);
slouken@1895
   372
    }
slouken@1895
   373
    quit(0);
slouken@5147
   374
    return 0;
slouken@1895
   375
}
slouken@1895
   376
slouken@1895
   377
/* vi: set ts=4 sw=4 expandtab: */