🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
6.7 KiB

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