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