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