cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

testsprite2.c (12305B)


      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
     24static SDLTest_CommonState *state;
     25static int num_sprites;
     26static SDL_Texture **sprites;
     27static SDL_bool cycle_color;
     28static SDL_bool cycle_alpha;
     29static int cycle_direction = 1;
     30static int current_alpha = 0;
     31static int current_color = 0;
     32static SDL_Rect *positions;
     33static SDL_Rect *velocities;
     34static int sprite_w, sprite_h;
     35static 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 */
     39static int iterations = -1;
     40
     41/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
     42static void
     43quit(int rc)
     44{
     45    SDL_free(sprites);
     46    SDL_free(positions);
     47    SDL_free(velocities);
     48    SDLTest_CommonQuit(state);
     49    exit(rc);
     50}
     51
     52int
     53LoadSprite(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
    104void
    105MoveSprites(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
    233int
    234main(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: */