test/testviewport.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 28 Jun 2020 17:45:07 -0400
changeset 13940 92ea0212b095
parent 13599 5cfc87d218e1
permissions -rw-r--r--
stdinc: Let Clang static analysis see more C runtime functions.

For systems without strlcpy and strlcat, just declare them as if they exist;
the analyzer possibly still knows the details of these functions and can
utilize that in its analysis.

Most of this patch was from meyraud705 at gmail and Martin Gerhardy. Thanks!

Fixes Bugzilla #5163.
     1 /*
     2   Copyright (C) 1997-2020 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:  Check viewports */
    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.h"
    23 #include "SDL_test_common.h"
    24 
    25 
    26 static SDLTest_CommonState *state;
    27 
    28 static SDL_Rect viewport;
    29 static int done, j;
    30 static SDL_bool use_target = SDL_FALSE;
    31 #ifdef __EMSCRIPTEN__
    32 static Uint32 wait_start;
    33 #endif
    34 static SDL_Texture *sprite;
    35 static int sprite_w, sprite_h;
    36 
    37 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    38 static void
    39 quit(int rc)
    40 {
    41     SDLTest_CommonQuit(state);
    42     exit(rc);
    43 }
    44 
    45 int
    46 LoadSprite(char *file, SDL_Renderer *renderer)
    47 {
    48     SDL_Surface *temp;
    49 
    50     /* Load the sprite image */
    51     temp = SDL_LoadBMP(file);
    52     if (temp == NULL) {
    53         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't load %s: %s\n", file, SDL_GetError());
    54         return (-1);
    55     }
    56     sprite_w = temp->w;
    57     sprite_h = temp->h;
    58 
    59     /* Set transparent pixel as the pixel at (0,0) */
    60     if (temp->format->palette) {
    61         SDL_SetColorKey(temp, SDL_TRUE, *(Uint8 *) temp->pixels);
    62     } else {
    63         switch (temp->format->BitsPerPixel) {
    64         case 15:
    65             SDL_SetColorKey(temp, SDL_TRUE,
    66                             (*(Uint16 *) temp->pixels) & 0x00007FFF);
    67             break;
    68         case 16:
    69             SDL_SetColorKey(temp, SDL_TRUE, *(Uint16 *) temp->pixels);
    70             break;
    71         case 24:
    72             SDL_SetColorKey(temp, SDL_TRUE,
    73                             (*(Uint32 *) temp->pixels) & 0x00FFFFFF);
    74             break;
    75         case 32:
    76             SDL_SetColorKey(temp, SDL_TRUE, *(Uint32 *) temp->pixels);
    77             break;
    78         }
    79     }
    80 
    81     /* Create textures from the image */
    82     sprite = SDL_CreateTextureFromSurface(renderer, temp);
    83     if (!sprite) {
    84         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
    85         SDL_FreeSurface(temp);
    86         return (-1);
    87     }
    88     SDL_FreeSurface(temp);
    89 
    90     /* We're ready to roll. :) */
    91     return (0);
    92 }
    93 
    94 void
    95 DrawOnViewport(SDL_Renderer * renderer, SDL_Rect viewport)
    96 {    
    97     SDL_Rect rect;
    98 
    99     /* Set the viewport */
   100     SDL_RenderSetViewport(renderer, &viewport);
   101     
   102     /* Draw a gray background */
   103     SDL_SetRenderDrawColor(renderer, 0x80, 0x80, 0x80, 0xFF);
   104     SDL_RenderClear(renderer);
   105 
   106     /* Test inside points */
   107     SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF);
   108     SDL_RenderDrawPoint(renderer, viewport.h/2 + 20, viewport.w/2);
   109     SDL_RenderDrawPoint(renderer, viewport.h/2 - 20, viewport.w/2);
   110     SDL_RenderDrawPoint(renderer, viewport.h/2     , viewport.w/2 - 20);
   111     SDL_RenderDrawPoint(renderer, viewport.h/2     , viewport.w/2 + 20);
   112 
   113     /* Test horizontal and vertical lines */
   114     SDL_SetRenderDrawColor(renderer, 0x00, 0xFF, 0x00, 0xFF);
   115     SDL_RenderDrawLine(renderer, 1, 0, viewport.w-2, 0);
   116     SDL_RenderDrawLine(renderer, 1, viewport.h-1, viewport.w-2, viewport.h-1);
   117     SDL_RenderDrawLine(renderer, 0, 1, 0, viewport.h-2);
   118     SDL_RenderDrawLine(renderer, viewport.w-1, 1, viewport.w-1, viewport.h-2);
   119 
   120     /* Test diagonal lines */
   121     SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0xFF, 0xFF);
   122     SDL_RenderDrawLine(renderer, 0, 0, viewport.w-1, viewport.h-1);
   123     SDL_RenderDrawLine(renderer, viewport.w-1, 0, 0, viewport.h-1);                      
   124 
   125     /* Test outside points */
   126     SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0x00, 0xFF);
   127     SDL_RenderDrawPoint(renderer, viewport.h/2 + viewport.h, viewport.w/2);
   128     SDL_RenderDrawPoint(renderer, viewport.h/2 - viewport.h, viewport.w/2);
   129     SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 - viewport.w);
   130     SDL_RenderDrawPoint(renderer, viewport.h/2, viewport.w/2 + viewport.w);
   131 
   132     /* Add a box at the top */
   133     rect.w = 8;
   134     rect.h = 8;
   135     rect.x = (viewport.w - rect.w) / 2;
   136     rect.y = 0;
   137     SDL_RenderFillRect(renderer, &rect);
   138 
   139     /* Add a clip rect and fill it with the sprite */
   140     SDL_QueryTexture(sprite, NULL, NULL, &rect.w, &rect.h);
   141     rect.x = (viewport.w - rect.w) / 2;
   142     rect.y = (viewport.h - rect.h) / 2;
   143     SDL_RenderSetClipRect(renderer, &rect);
   144     SDL_RenderCopy(renderer, sprite, NULL, &rect);
   145     SDL_RenderSetClipRect(renderer, NULL);
   146 }
   147 
   148 void
   149 loop()
   150 {
   151 #ifdef __EMSCRIPTEN__
   152     /* Avoid using delays */
   153     if(SDL_GetTicks() - wait_start < 1000)
   154         return;
   155     wait_start = SDL_GetTicks();
   156 #endif
   157     SDL_Event event;
   158     int i;
   159     /* Check for events */
   160     while (SDL_PollEvent(&event)) {
   161         SDLTest_CommonEvent(state, &event, &done);
   162     }
   163 
   164     /* Move a viewport box in steps around the screen */
   165     viewport.x = j * 100;
   166     viewport.y = viewport.x;
   167     viewport.w = 100 + j * 50;
   168     viewport.h = 100 + j * 50;
   169     j = (j + 1) % 4;
   170     SDL_Log("Current Viewport x=%i y=%i w=%i h=%i", viewport.x, viewport.y, viewport.w, viewport.h);
   171 
   172     for (i = 0; i < state->num_windows; ++i) {
   173         if (state->windows[i] == NULL)
   174             continue;
   175 
   176         /* Draw using viewport */
   177         DrawOnViewport(state->renderers[i], viewport);
   178 
   179         /* Update the screen! */
   180         if (use_target) {
   181             SDL_SetRenderTarget(state->renderers[i], NULL);
   182             SDL_RenderCopy(state->renderers[i], state->targets[i], NULL, NULL);
   183             SDL_RenderPresent(state->renderers[i]);
   184             SDL_SetRenderTarget(state->renderers[i], state->targets[i]);
   185         } else {
   186             SDL_RenderPresent(state->renderers[i]);
   187         }
   188     }
   189 
   190 #ifdef __EMSCRIPTEN__
   191     if (done) {
   192         emscripten_cancel_main_loop();
   193     }
   194 #endif
   195 }
   196 
   197 int
   198 main(int argc, char *argv[])
   199 {
   200     int i;
   201     Uint32 then, now, frames;
   202 
   203     /* Initialize test framework */
   204     state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
   205     if (!state) {
   206         return 1;
   207     }
   208 
   209 
   210     for (i = 1; i < argc;) {
   211         int consumed;
   212 
   213         consumed = SDLTest_CommonArg(state, i);
   214         if (consumed == 0) {
   215             consumed = -1;
   216             if (SDL_strcasecmp(argv[i], "--target") == 0) {
   217                 use_target = SDL_TRUE;
   218                 consumed = 1;
   219             }
   220         }
   221         if (consumed < 0) {
   222             static const char *options[] = { "[--target]", NULL };
   223             SDLTest_CommonLogUsage(state, argv[0], options);
   224             quit(1);
   225         }
   226         i += consumed;
   227     }
   228     if (!SDLTest_CommonInit(state)) {
   229         quit(2);
   230     }
   231 
   232     if (LoadSprite("icon.bmp", state->renderers[0]) < 0) {
   233         quit(2);
   234     }
   235 
   236     if (use_target) {
   237         int w, h;
   238 
   239         for (i = 0; i < state->num_windows; ++i) {
   240             SDL_GetWindowSize(state->windows[i], &w, &h);
   241             state->targets[i] = SDL_CreateTexture(state->renderers[i], SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
   242             SDL_SetRenderTarget(state->renderers[i], state->targets[i]);
   243         }
   244     }
   245 
   246     for (i = 0; i < state->num_windows; ++i) {
   247         SDL_Renderer *renderer = state->renderers[i];
   248         SDL_SetRenderDrawColor(renderer, 0xA0, 0xA0, 0xA0, 0xFF);
   249         SDL_RenderClear(renderer);
   250     }
   251 
   252     /* Main render loop */
   253     frames = 0;
   254     then = SDL_GetTicks();
   255     done = 0;
   256     j = 0;
   257 
   258 #ifdef __EMSCRIPTEN__
   259     wait_start = SDL_GetTicks();
   260     emscripten_set_main_loop(loop, 0, 1);
   261 #else
   262     while (!done) {
   263         ++frames;
   264         loop();
   265         SDL_Delay(1000);
   266     }
   267 #endif
   268 
   269     /* Print out some timing information */
   270     now = SDL_GetTicks();
   271     if (now > then) {
   272         double fps = ((double) frames * 1000) / (now - then);
   273         SDL_Log("%2.2f frames per second\n", fps);
   274     }
   275     quit(0);
   276     return 0;
   277 }
   278 
   279 /* vi: set ts=4 sw=4 expandtab: */