comparison Xcode-iPhoneOS/Demos/src/accelerometer.c @ 3277:20326ba2bda2

This name inconsistency has been bugging me for a while...
author Sam Lantinga <slouken@libsdl.org>
date Sat, 19 Sep 2009 07:32:36 +0000
parents
children 64ce267332c6
comparison
equal deleted inserted replaced
3276:720d176be107 3277:20326ba2bda2
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 MILLESECONDS_PER_FRAME 16 /* about 60 frames per second */
12 #define DAMPING 0.5f; /* after bouncing off a wall, damping coefficient determines final speed */
13 #define FRICTION 0.0008f /* coefficient of acceleration that opposes direction of motion */
14 #define GRAVITY_CONSTANT 0.004f /* how sensitive the ship is to the accelerometer */
15
16 /* If we aren't on an iPhone, then this definition ought to yield reasonable behavior */
17 #ifndef SDL_IPHONE_MAX_GFORCE
18 #define SDL_IPHONE_MAX_GFORCE 5.0f
19 #endif
20
21 static SDL_Joystick *accelerometer; /* used for controlling the ship */
22
23 static struct
24 {
25 float x, y; /* position of ship */
26 float vx, vy; /* velocity of ship (in pixels per millesecond) */
27 SDL_Rect rect; /* (drawn) position and size of ship */
28 } ship;
29
30 static SDL_TextureID shipID = 0; /* texture for spaceship */
31 static SDL_TextureID spaceID = 0; /* texture for space (background */
32
33 void
34 render(void)
35 {
36
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 = SCREEN_WIDTH - ship.rect.w;
45 Uint32 miny = 0.0f;
46 Uint32 maxy = SCREEN_HEIGHT - ship.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 ship.vx +=
55 ax * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
56 MILLESECONDS_PER_FRAME;
57 ship.vy +=
58 ay * SDL_IPHONE_MAX_GFORCE / SINT16_MAX * GRAVITY_CONSTANT *
59 MILLESECONDS_PER_FRAME;
60
61 float speed = sqrt(ship.vx * ship.vx + ship.vy * ship.vy);
62
63 if (speed > 0) {
64 /* compensate for friction */
65 float dirx = ship.vx / speed; /* normalized x velocity */
66 float diry = ship.vy / speed; /* normalized y velocity */
67
68 /* update velocity due to friction */
69 if (speed - FRICTION * MILLESECONDS_PER_FRAME > 0) {
70 /* apply friction */
71 ship.vx -= dirx * FRICTION * MILLESECONDS_PER_FRAME;
72 ship.vy -= diry * FRICTION * MILLESECONDS_PER_FRAME;
73 } else {
74 /* applying friction would MORE than stop the ship, so just stop the ship */
75 ship.vx = 0.0f;
76 ship.vy = 0.0f;
77 }
78 }
79
80 /* update ship location */
81 ship.x += ship.vx * MILLESECONDS_PER_FRAME;
82 ship.y += ship.vy * MILLESECONDS_PER_FRAME;
83
84 if (ship.x > maxx) {
85 ship.x = maxx;
86 ship.vx = -ship.vx * DAMPING;
87 } else if (ship.x < minx) {
88 ship.x = minx;
89 ship.vx = -ship.vx * DAMPING;
90 }
91 if (ship.y > maxy) {
92 ship.y = maxy;
93 ship.vy = -ship.vy * DAMPING;
94 } else if (ship.y < miny) {
95 ship.y = miny;
96 ship.vy = -ship.vy * DAMPING;
97 }
98
99 /* draw the background */
100 SDL_RenderCopy(spaceID, NULL, NULL);
101
102 /* draw the ship */
103 ship.rect.x = ship.x;
104 ship.rect.y = ship.y;
105
106 SDL_RenderCopy(shipID, NULL, &ship.rect);
107
108 /* update screen */
109 SDL_RenderPresent();
110
111 }
112
113 void
114 initializeTextures()
115 {
116
117 SDL_Surface *bmp_surface;
118 SDL_Surface *bmp_surface_rgba;
119 int format = SDL_PIXELFORMAT_ABGR8888; /* desired texture format */
120 Uint32 Rmask, Gmask, Bmask, Amask; /* masks for desired format */
121 int bpp; /* bits per pixel for desired format */
122
123 /* load the ship */
124 bmp_surface = SDL_LoadBMP("ship.bmp");
125 if (bmp_surface == NULL) {
126 fatalError("could not ship.bmp");
127 }
128 /* set blue to transparent on the ship */
129 SDL_SetColorKey(bmp_surface, 1,
130 SDL_MapRGB(bmp_surface->format, 0, 0, 255));
131 SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
132 /*
133 create a new RGBA surface and blit the bmp to it
134 this is an extra step, but it seems to be necessary for the color key to work
135
136 does the fact that this is necessary indicate a bug in SDL?
137 */
138 bmp_surface_rgba =
139 SDL_CreateRGBSurface(0, bmp_surface->w, bmp_surface->h, bpp, Rmask,
140 Gmask, Bmask, Amask);
141 SDL_BlitSurface(bmp_surface, NULL, bmp_surface_rgba, NULL);
142
143 /* create ship texture from surface */
144 shipID = SDL_CreateTextureFromSurface(format, bmp_surface_rgba);
145 if (shipID == 0) {
146 fatalError("could not create ship texture");
147 }
148 SDL_SetTextureBlendMode(shipID, SDL_BLENDMODE_BLEND);
149
150 /* set the width and height of the ship from the surface dimensions */
151 ship.rect.w = bmp_surface->w;
152 ship.rect.h = bmp_surface->h;
153
154 SDL_FreeSurface(bmp_surface_rgba);
155 SDL_FreeSurface(bmp_surface);
156
157 /* load the space background */
158 bmp_surface = SDL_LoadBMP("space.bmp");
159 if (bmp_surface == NULL) {
160 fatalError("could not load space.bmp");
161 }
162 /* create space texture from surface */
163 spaceID = SDL_CreateTextureFromSurface(format, bmp_surface);
164 if (spaceID == 0) {
165 fatalError("could not create space texture");
166 }
167 SDL_FreeSurface(bmp_surface);
168
169 }
170
171
172
173 int
174 main(int argc, char *argv[])
175 {
176
177 SDL_WindowID windowID; /* ID of main window */
178 Uint32 startFrame; /* time frame began to process */
179 Uint32 endFrame; /* time frame ended processing */
180 Uint32 delay; /* time to pause waiting to draw next frame */
181 int done; /* should we clean up and exit? */
182
183 /* initialize SDL */
184 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
185 fatalError("Could not initialize SDL");
186 }
187
188 /* create main window and renderer */
189 windowID = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
190 SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN |
191 SDL_WINDOW_BORDERLESS);
192 SDL_CreateRenderer(windowID, 0, 0);
193
194 /* print out some info about joysticks and try to open accelerometer for use */
195 printf("There are %d joysticks available\n", SDL_NumJoysticks());
196 printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0));
197 accelerometer = SDL_JoystickOpen(0);
198 if (accelerometer == NULL) {
199 fatalError("Could not open joystick (accelerometer)");
200 }
201 printf("joystick number of axis = %d\n",
202 SDL_JoystickNumAxes(accelerometer));
203 printf("joystick number of hats = %d\n",
204 SDL_JoystickNumHats(accelerometer));
205 printf("joystick number of balls = %d\n",
206 SDL_JoystickNumBalls(accelerometer));
207 printf("joystick number of buttons = %d\n",
208 SDL_JoystickNumButtons(accelerometer));
209
210 /* load graphics */
211 initializeTextures();
212
213 /* setup ship */
214 ship.x = (SCREEN_WIDTH - ship.rect.w) / 2;
215 ship.y = (SCREEN_HEIGHT - ship.rect.h) / 2;
216 ship.vx = 0.0f;
217 ship.vy = 0.0f;
218
219 done = 0;
220 /* enter main loop */
221 while (!done) {
222 startFrame = SDL_GetTicks();
223 SDL_Event event;
224 while (SDL_PollEvent(&event)) {
225 if (event.type == SDL_QUIT) {
226 done = 1;
227 }
228 }
229 render();
230 endFrame = SDL_GetTicks();
231
232 /* figure out how much time we have left, and then sleep */
233 delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
234 if (delay < 0) {
235 delay = 0;
236 } else if (delay > MILLESECONDS_PER_FRAME) {
237 delay = MILLESECONDS_PER_FRAME;
238 }
239 SDL_Delay(delay);
240 }
241
242 /* delete textures */
243 SDL_DestroyTexture(shipID);
244 SDL_DestroyTexture(spaceID);
245
246 /* shutdown SDL */
247 SDL_Quit();
248
249 return 0;
250
251 }