test/testscale.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:09 -0800
changeset 11730 ac6c607e065c
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Enable building the Metal renderer by default, and weak link the Metal framework so the SDL library is safe to use on older Macs
Also generate iOS versions of the Metal shaders
slouken@5535
     1
/*
slouken@10737
     2
  Copyright (C) 1997-2017 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@5240
    12
/* Simple program:  Move N sprites around on the screen as fast as possible */
slouken@5240
    13
slouken@5240
    14
#include <stdlib.h>
slouken@5240
    15
#include <stdio.h>
slouken@5240
    16
#include <time.h>
slouken@5240
    17
icculus@9278
    18
#ifdef __EMSCRIPTEN__
icculus@9278
    19
#include <emscripten/emscripten.h>
icculus@9278
    20
#endif
icculus@9278
    21
slouken@6785
    22
#include "SDL_test_common.h"
slouken@5240
    23
slouken@5240
    24
#define WINDOW_WIDTH    640
slouken@5240
    25
#define WINDOW_HEIGHT   480
slouken@5240
    26
slouken@6785
    27
static SDLTest_CommonState *state;
slouken@5240
    28
slouken@5240
    29
typedef struct {
slouken@5240
    30
    SDL_Window *window;
slouken@5240
    31
    SDL_Renderer *renderer;
slouken@5240
    32
    SDL_Texture *background;
slouken@5240
    33
    SDL_Texture *sprite;
slouken@5240
    34
    SDL_Rect sprite_rect;
slouken@5240
    35
    int scale_direction;
slouken@5240
    36
} DrawState;
slouken@5240
    37
icculus@9278
    38
DrawState *drawstates;
icculus@9278
    39
int done;
icculus@9278
    40
slouken@5240
    41
/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
slouken@5240
    42
static void
slouken@5240
    43
quit(int rc)
slouken@5240
    44
{
slouken@6785
    45
    SDLTest_CommonQuit(state);
slouken@5240
    46
    exit(rc);
slouken@5240
    47
}
slouken@5240
    48
slouken@5240
    49
SDL_Texture *
slouken@5240
    50
LoadTexture(SDL_Renderer *renderer, char *file, SDL_bool transparent)
slouken@5240
    51
{
slouken@5240
    52
    SDL_Surface *temp;
slouken@5240
    53
    SDL_Texture *texture;
slouken@5240
    54
slouken@5240
    55
    /* Load the sprite image */
slouken@5240
    56
    temp = SDL_LoadBMP(file);
slouken@5240
    57
    if (temp == NULL) {
aschiffler@7639
    58
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s", file, SDL_GetError());
slouken@5240
    59
        return NULL;
slouken@5240
    60
    }
slouken@5240
    61
slouken@5240
    62
    /* Set transparent pixel as the pixel at (0,0) */
slouken@5240
    63
    if (transparent) {
slouken@5240
    64
        if (temp->format->palette) {
slouken@5240
    65
            SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
slouken@5240
    66
        } else {
slouken@5240
    67
            switch (temp->format->BitsPerPixel) {
slouken@5240
    68
            case 15:
slouken@5240
    69
                SDL_SetColorKey(temp, SDL_TRUE,
slouken@5240
    70
                                (*(Uint16 *) temp->pixels) & 0x00007FFF);
slouken@5240
    71
                break;
slouken@5240
    72
            case 16:
slouken@5240
    73
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
slouken@5240
    74
                break;
slouken@5240
    75
            case 24:
slouken@5240
    76
                SDL_SetColorKey(temp, SDL_TRUE,
slouken@5240
    77
                                (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
slouken@5240
    78
                break;
slouken@5240
    79
            case 32:
slouken@5240
    80
                SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
slouken@5240
    81
                break;
slouken@5240
    82
            }
slouken@5240
    83
        }
slouken@5240
    84
    }
slouken@5240
    85
slouken@5240
    86
    /* Create textures from the image */
slouken@5240
    87
    texture = SDL_CreateTextureFromSurface(renderer, temp);
slouken@5240
    88
    if (!texture) {
aschiffler@7639
    89
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
slouken@5240
    90
        SDL_FreeSurface(temp);
slouken@5240
    91
        return NULL;
slouken@5240
    92
    }
slouken@5240
    93
    SDL_FreeSurface(temp);
slouken@5240
    94
slouken@5240
    95
    /* We're ready to roll. :) */
slouken@5240
    96
    return texture;
slouken@5240
    97
}
slouken@5240
    98
slouken@5240
    99
void
slouken@5240
   100
Draw(DrawState *s)
slouken@5240
   101
{
slouken@5297
   102
    SDL_Rect viewport;
slouken@5240
   103
slouken@5297
   104
    SDL_RenderGetViewport(s->renderer, &viewport);
slouken@5240
   105
slouken@5240
   106
    /* Draw the background */
slouken@5240
   107
    SDL_RenderCopy(s->renderer, s->background, NULL, NULL);
slouken@5240
   108
slouken@5240
   109
    /* Scale and draw the sprite */
slouken@5240
   110
    s->sprite_rect.w += s->scale_direction;
slouken@5240
   111
    s->sprite_rect.h += s->scale_direction;
slouken@5240
   112
    if (s->scale_direction > 0) {
slouken@5297
   113
        if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
slouken@5240
   114
            s->scale_direction = -1;
slouken@5240
   115
        }
slouken@5240
   116
    } else {
slouken@5240
   117
        if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
slouken@5240
   118
            s->scale_direction = 1;
slouken@5240
   119
        }
slouken@5240
   120
    }
slouken@5297
   121
    s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
slouken@5297
   122
    s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
slouken@5240
   123
slouken@5240
   124
    SDL_RenderCopy(s->renderer, s->sprite, NULL, &s->sprite_rect);
slouken@5240
   125
slouken@5240
   126
    /* Update the screen! */
slouken@5240
   127
    SDL_RenderPresent(s->renderer);
slouken@5240
   128
}
slouken@5240
   129
icculus@9278
   130
void
icculus@9278
   131
loop()
icculus@9278
   132
{
icculus@9278
   133
    int i;
icculus@9278
   134
    SDL_Event event;
icculus@9278
   135
icculus@9278
   136
    /* Check for events */
icculus@9278
   137
    while (SDL_PollEvent(&event)) {
icculus@9278
   138
        SDLTest_CommonEvent(state, &event, &done);
icculus@9278
   139
    }
icculus@9278
   140
    for (i = 0; i < state->num_windows; ++i) {
icculus@9278
   141
        if (state->windows[i] == NULL)
icculus@9278
   142
            continue;
icculus@9278
   143
        Draw(&drawstates[i]);
icculus@9278
   144
    }
philipp@9607
   145
#ifdef __EMSCRIPTEN__
philipp@9607
   146
    if (done) {
philipp@9607
   147
        emscripten_cancel_main_loop();
philipp@9607
   148
    }
philipp@9607
   149
#endif
icculus@9278
   150
}
icculus@9278
   151
slouken@5240
   152
int
slouken@5240
   153
main(int argc, char *argv[])
slouken@5240
   154
{
icculus@9278
   155
    int i;
slouken@5240
   156
    int frames;
slouken@5240
   157
    Uint32 then, now;
slouken@5240
   158
aschiffler@7639
   159
    /* Enable standard application logging */
aschiffler@7639
   160
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   161
slouken@5240
   162
    /* Initialize test framework */
slouken@6785
   163
    state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
slouken@5240
   164
    if (!state) {
slouken@5240
   165
        return 1;
slouken@5240
   166
    }
slouken@5240
   167
    for (i = 1; i < argc;) {
slouken@5240
   168
        int consumed;
slouken@5240
   169
slouken@6785
   170
        consumed = SDLTest_CommonArg(state, i);
slouken@5240
   171
        if (consumed == 0) {
aschiffler@7639
   172
            SDL_Log("Usage: %s %s\n", argv[0], SDLTest_CommonUsage(state));
slouken@5240
   173
            return 1;
slouken@5240
   174
        }
slouken@5240
   175
        i += consumed;
slouken@5240
   176
    }
slouken@6785
   177
    if (!SDLTest_CommonInit(state)) {
slouken@5240
   178
        quit(2);
slouken@5240
   179
    }
slouken@5240
   180
slouken@5240
   181
    drawstates = SDL_stack_alloc(DrawState, state->num_windows);
slouken@5240
   182
    for (i = 0; i < state->num_windows; ++i) {
slouken@5240
   183
        DrawState *drawstate = &drawstates[i];
slouken@5240
   184
slouken@5240
   185
        drawstate->window = state->windows[i];
slouken@5240
   186
        drawstate->renderer = state->renderers[i];
slouken@5240
   187
        drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", SDL_TRUE);
slouken@5240
   188
        drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", SDL_FALSE);
slouken@5240
   189
        if (!drawstate->sprite || !drawstate->background) {
slouken@5240
   190
            quit(2);
slouken@5240
   191
        }
slouken@5240
   192
        SDL_QueryTexture(drawstate->sprite, NULL, NULL,
slouken@5240
   193
                         &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
slouken@5240
   194
        drawstate->scale_direction = 1;
slouken@5240
   195
    }
slouken@5240
   196
slouken@5240
   197
    /* Main render loop */
slouken@5240
   198
    frames = 0;
slouken@5240
   199
    then = SDL_GetTicks();
slouken@5240
   200
    done = 0;
icculus@9278
   201
icculus@9278
   202
#ifdef __EMSCRIPTEN__
icculus@9278
   203
    emscripten_set_main_loop(loop, 0, 1);
icculus@9278
   204
#else
slouken@5240
   205
    while (!done) {
slouken@5240
   206
        ++frames;
icculus@9278
   207
        loop();
slouken@5240
   208
    }
icculus@9278
   209
#endif
slouken@5240
   210
slouken@5240
   211
    /* Print out some timing information */
slouken@5240
   212
    now = SDL_GetTicks();
slouken@5240
   213
    if (now > then) {
slouken@5240
   214
        double fps = ((double) frames * 1000) / (now - then);
aschiffler@7639
   215
        SDL_Log("%2.2f frames per second\n", fps);
slouken@5240
   216
    }
slouken@5240
   217
slouken@5295
   218
    SDL_stack_free(drawstates);
slouken@5240
   219
slouken@5240
   220
    quit(0);
slouken@5240
   221
    return 0;
slouken@5240
   222
}
slouken@5240
   223
slouken@5240
   224
/* vi: set ts=4 sw=4 expandtab: */