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