sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

accelerometer.c (6878B)


      1 /*
      2  *  accelerometer.c
      3  *  written by Holmes Futrell
      4  *  use however you want
      5  */
      6 
      7 #include "SDL.h"
      8 #include <math.h>
      9 #include "common.h"
     10 
     11 #define DAMPING 0.5f;           /* after bouncing off a wall, damping coefficient determines final speed */
     12 #define FRICTION 0.0008f        /* coefficient of acceleration that opposes direction of motion */
     13 #define GRAVITY_CONSTANT 0.004f /* how sensitive the ship is to the accelerometer */
     14 
     15 /*  If we aren't on an iPhone, then this definition ought to yield reasonable behavior */
     16 #ifndef SDL_IPHONE_MAX_GFORCE
     17 #define SDL_IPHONE_MAX_GFORCE 5.0f
     18 #endif
     19 
     20 static SDL_Joystick *accelerometer;     /* used for controlling the ship */
     21 
     22 static struct
     23 {
     24     float x, y;                 /* position of ship */
     25     float vx, vy;               /* velocity of ship (in pixels per millesecond) */
     26     SDL_Rect rect;              /* (drawn) position and size of ship */
     27 } shipData;
     28 
     29 static SDL_Texture *ship = 0;        /* texture for spaceship */
     30 static SDL_Texture *space = 0;       /* texture for space (background */
     31 
     32 void
     33 render(SDL_Renderer *renderer, int w, int h, double deltaTime)
     34 {
     35     double deltaMilliseconds = deltaTime * 1000;
     36     float speed;
     37 
     38     /* get joystick (accelerometer) axis values and normalize them */
     39     float ax = SDL_JoystickGetAxis(accelerometer, 0);
     40     float ay = SDL_JoystickGetAxis(accelerometer, 1);
     41 
     42     /* ship screen constraints */
     43     Uint32 minx = 0.0f;
     44     Uint32 maxx = w - shipData.rect.w;
     45     Uint32 miny = 0.0f;
     46     Uint32 maxy = h - shipData.rect.h;
     47 
     48 #define SINT16_MAX ((float)(0x7FFF))
     49 
     50     /* update velocity from accelerometer
     51        the factor SDL_IPHONE_MAX_G_FORCE / SINT16_MAX converts between
     52        SDL's units reported from the joytick, and units of g-force, as reported by the accelerometer
     53      */
     54     shipData.vx +=
     55         ax * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
     56         deltaMilliseconds;
     57     shipData.vy +=
     58         ay * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
     59         deltaMilliseconds;
     60 
     61     speed = sqrt(shipData.vx * shipData.vx + shipData.vy * shipData.vy);
     62 
     63     if (speed > 0) {
     64         /* compensate for friction */
     65         float dirx = shipData.vx / speed;   /* normalized x velocity */
     66         float diry = shipData.vy / speed;   /* normalized y velocity */
     67 
     68         /* update velocity due to friction */
     69         if (speed - FRICTION * deltaMilliseconds > 0) {
     70             /* apply friction */
     71             shipData.vx -= dirx * FRICTION * deltaMilliseconds;
     72             shipData.vy -= diry * FRICTION * deltaMilliseconds;
     73         } else {
     74             /* applying friction would MORE than stop the ship, so just stop the ship */
     75             shipData.vx = 0.0f;
     76             shipData.vy = 0.0f;
     77         }
     78     }
     79 
     80     /* update ship location */
     81     shipData.x += shipData.vx * deltaMilliseconds;
     82     shipData.y += shipData.vy * deltaMilliseconds;
     83 
     84     if (shipData.x > maxx) {
     85         shipData.x = maxx;
     86         shipData.vx = -shipData.vx * DAMPING;
     87     } else if (shipData.x < minx) {
     88         shipData.x = minx;
     89         shipData.vx = -shipData.vx * DAMPING;
     90     }
     91     if (shipData.y > maxy) {
     92         shipData.y = maxy;
     93         shipData.vy = -shipData.vy * DAMPING;
     94     } else if (shipData.y < miny) {
     95         shipData.y = miny;
     96         shipData.vy = -shipData.vy * DAMPING;
     97     }
     98 
     99     /* draw the background */
    100     SDL_RenderCopy(renderer, space, NULL, NULL);
    101 
    102     /* draw the ship */
    103     shipData.rect.x = shipData.x;
    104     shipData.rect.y = shipData.y;
    105 
    106     SDL_RenderCopy(renderer, ship, NULL, &shipData.rect);
    107 
    108     /* update screen */
    109     SDL_RenderPresent(renderer);
    110 
    111 }
    112 
    113 void
    114 initializeTextures(SDL_Renderer *renderer)
    115 {
    116 
    117     SDL_Surface *bmp_surface;
    118 
    119     /* load the ship */
    120     bmp_surface = SDL_LoadBMP("ship.bmp");
    121     if (bmp_surface == NULL) {
    122         fatalError("could not ship.bmp");
    123     }
    124     /* set blue to transparent on the ship */
    125     SDL_SetColorKey(bmp_surface, 1,
    126                     SDL_MapRGB(bmp_surface->format, 0, 0, 255));
    127 
    128     /* create ship texture from surface */
    129     ship = SDL_CreateTextureFromSurface(renderer, bmp_surface);
    130     if (ship == 0) {
    131         fatalError("could not create ship texture");
    132     }
    133     SDL_SetTextureBlendMode(ship, SDL_BLENDMODE_BLEND);
    134 
    135     /* set the width and height of the ship from the surface dimensions */
    136     shipData.rect.w = bmp_surface->w;
    137     shipData.rect.h = bmp_surface->h;
    138 
    139     SDL_FreeSurface(bmp_surface);
    140 
    141     /* load the space background */
    142     bmp_surface = SDL_LoadBMP("space.bmp");
    143     if (bmp_surface == NULL) {
    144         fatalError("could not load space.bmp");
    145     }
    146     /* create space texture from surface */
    147     space = SDL_CreateTextureFromSurface(renderer, bmp_surface);
    148     if (space == 0) {
    149         fatalError("could not create space texture");
    150     }
    151     SDL_FreeSurface(bmp_surface);
    152 
    153 }
    154 
    155 
    156 
    157 int
    158 main(int argc, char *argv[])
    159 {
    160 
    161     SDL_Window *window;         /* main window */
    162     SDL_Renderer *renderer;
    163     int done;                   /* should we clean up and exit? */
    164     int w, h;
    165 
    166     /* initialize SDL */
    167     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
    168         fatalError("Could not initialize SDL");
    169     }
    170 
    171     /* create main window and renderer */
    172     window = SDL_CreateWindow(NULL, 0, 0, 320, 480, SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI);
    173     renderer = SDL_CreateRenderer(window, 0, 0);
    174     
    175     SDL_GetWindowSize(window, &w, &h);
    176     SDL_RenderSetLogicalSize(renderer, w, h);
    177 
    178     /* print out some info about joysticks and try to open accelerometer for use */
    179     printf("There are %d joysticks available\n", SDL_NumJoysticks());
    180     printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0));
    181     accelerometer = SDL_JoystickOpen(0);
    182     if (accelerometer == NULL) {
    183         fatalError("Could not open joystick (accelerometer)");
    184     }
    185     printf("joystick number of axis = %d\n",
    186            SDL_JoystickNumAxes(accelerometer));
    187     printf("joystick number of hats = %d\n",
    188            SDL_JoystickNumHats(accelerometer));
    189     printf("joystick number of balls = %d\n",
    190            SDL_JoystickNumBalls(accelerometer));
    191     printf("joystick number of buttons = %d\n",
    192            SDL_JoystickNumButtons(accelerometer));
    193 
    194     /* load graphics */
    195     initializeTextures(renderer);
    196 
    197     /* setup ship */
    198     shipData.x = (w - shipData.rect.w) / 2;
    199     shipData.y = (h - shipData.rect.h) / 2;
    200     shipData.vx = 0.0f;
    201     shipData.vy = 0.0f;
    202 
    203     done = 0;
    204     /* enter main loop */
    205     while (!done) {
    206         double deltaTime = updateDeltaTime();
    207         SDL_Event event;
    208         while (SDL_PollEvent(&event)) {
    209             if (event.type == SDL_QUIT) {
    210                 done = 1;
    211             }
    212         }
    213         render(renderer, w, h, deltaTime);
    214         SDL_Delay(1);
    215     }
    216 
    217     /* delete textures */
    218     SDL_DestroyTexture(ship);
    219     SDL_DestroyTexture(space);
    220 
    221     /* shutdown SDL */
    222     SDL_Quit();
    223 
    224     return 0;
    225 
    226 }