cscg22-gearboy

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

happy.c (4679B)


      1/*
      2 *  happy.c
      3 *  written by Holmes Futrell
      4 *  use however you want
      5 */
      6
      7#include "SDL.h"
      8#include "common.h"
      9
     10#define NUM_HAPPY_FACES 100     /* number of faces to draw */
     11#define MILLESECONDS_PER_FRAME 16       /* about 60 frames per second */
     12#define HAPPY_FACE_SIZE 32      /* width and height of happyface (pixels) */
     13
     14static SDL_Texture *texture = 0;    /* reference to texture holding happyface */
     15
     16static struct
     17{
     18    float x, y;                 /* position of happyface */
     19    float xvel, yvel;           /* velocity of happyface */
     20} faces[NUM_HAPPY_FACES];
     21
     22/*
     23    Sets initial positions and velocities of happyfaces
     24    units of velocity are pixels per millesecond
     25*/
     26void
     27initializeHappyFaces()
     28{
     29    int i;
     30    for (i = 0; i < NUM_HAPPY_FACES; i++) {
     31        faces[i].x = randomFloat(0.0f, SCREEN_WIDTH - HAPPY_FACE_SIZE);
     32        faces[i].y = randomFloat(0.0f, SCREEN_HEIGHT - HAPPY_FACE_SIZE);
     33        faces[i].xvel = randomFloat(-0.1f, 0.1f);
     34        faces[i].yvel = randomFloat(-0.1f, 0.1f);
     35    }
     36}
     37
     38void
     39render(SDL_Renderer *renderer)
     40{
     41
     42    int i;
     43    SDL_Rect srcRect;
     44    SDL_Rect dstRect;
     45
     46    /* setup boundaries for happyface bouncing */
     47    Uint16 maxx = SCREEN_WIDTH - HAPPY_FACE_SIZE;
     48    Uint16 maxy = SCREEN_HEIGHT - HAPPY_FACE_SIZE;
     49    Uint16 minx = 0;
     50    Uint16 miny = 0;
     51
     52    /* setup rects for drawing */
     53    srcRect.x = 0;
     54    srcRect.y = 0;
     55    srcRect.w = HAPPY_FACE_SIZE;
     56    srcRect.h = HAPPY_FACE_SIZE;
     57    dstRect.w = HAPPY_FACE_SIZE;
     58    dstRect.h = HAPPY_FACE_SIZE;
     59
     60    /* fill background in with black */
     61    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
     62    SDL_RenderClear(renderer);
     63
     64    /*
     65       loop through all the happy faces:
     66       - update position
     67       - update velocity (if boundary is hit)
     68       - draw
     69     */
     70    for (i = 0; i < NUM_HAPPY_FACES; i++) {
     71        faces[i].x += faces[i].xvel * MILLESECONDS_PER_FRAME;
     72        faces[i].y += faces[i].yvel * MILLESECONDS_PER_FRAME;
     73        if (faces[i].x > maxx) {
     74            faces[i].x = maxx;
     75            faces[i].xvel = -faces[i].xvel;
     76        } else if (faces[i].y > maxy) {
     77            faces[i].y = maxy;
     78            faces[i].yvel = -faces[i].yvel;
     79        }
     80        if (faces[i].x < minx) {
     81            faces[i].x = minx;
     82            faces[i].xvel = -faces[i].xvel;
     83        } else if (faces[i].y < miny) {
     84            faces[i].y = miny;
     85            faces[i].yvel = -faces[i].yvel;
     86        }
     87        dstRect.x = faces[i].x;
     88        dstRect.y = faces[i].y;
     89        SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
     90    }
     91    /* update screen */
     92    SDL_RenderPresent(renderer);
     93
     94}
     95
     96/*
     97    loads the happyface graphic into a texture
     98*/
     99void
    100initializeTexture(SDL_Renderer *renderer)
    101{
    102    SDL_Surface *bmp_surface;
    103    /* load the bmp */
    104    bmp_surface = SDL_LoadBMP("icon.bmp");
    105    if (bmp_surface == NULL) {
    106        fatalError("could not load bmp");
    107    }
    108    /* set white to transparent on the happyface */
    109    SDL_SetColorKey(bmp_surface, 1,
    110                    SDL_MapRGB(bmp_surface->format, 255, 255, 255));
    111
    112    /* convert RGBA surface to texture */
    113    texture = SDL_CreateTextureFromSurface(renderer, bmp_surface);
    114    if (texture == 0) {
    115        fatalError("could not create texture");
    116    }
    117    SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
    118
    119    /* free up allocated memory */
    120    SDL_FreeSurface(bmp_surface);
    121}
    122
    123int
    124main(int argc, char *argv[])
    125{
    126
    127    SDL_Window *window;
    128    SDL_Renderer *renderer;
    129    Uint32 startFrame;
    130    Uint32 endFrame;
    131    Uint32 delay;
    132    int done;
    133
    134    /* initialize SDL */
    135    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    136        fatalError("Could not initialize SDL");
    137    }
    138    window = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
    139                                SDL_WINDOW_OPENGL |
    140                                SDL_WINDOW_BORDERLESS);
    141
    142    renderer = SDL_CreateRenderer(window, -1, 0);
    143
    144    initializeTexture(renderer);
    145    initializeHappyFaces();
    146
    147    /* main loop */
    148    done = 0;
    149    while (!done) {
    150        startFrame = SDL_GetTicks();
    151        SDL_Event event;
    152        while (SDL_PollEvent(&event)) {
    153            if (event.type == SDL_QUIT) {
    154                done = 1;
    155            }
    156        }
    157        render(renderer);
    158        endFrame = SDL_GetTicks();
    159
    160        /* figure out how much time we have left, and then sleep */
    161        delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
    162        if (delay < 0) {
    163            delay = 0;
    164        } else if (delay > MILLESECONDS_PER_FRAME) {
    165            delay = MILLESECONDS_PER_FRAME;
    166        }
    167        SDL_Delay(delay);
    168    }
    169
    170    /* cleanup */
    171    SDL_DestroyTexture(texture);
    172    /* shutdown SDL */
    173    SDL_Quit();
    174
    175    return 0;
    176
    177}