comparison XCodeiPhoneOS/Demos/src/accelerometer.c @ 2380:7fbcfc1574dc gsoc2008_iphone

Demo of iPhone accelerometer as SDL joystick
author Holmes Futrell <hfutrell@umail.ucsb.edu>
date Fri, 18 Jul 2008 20:50:59 +0000
parents
children ecc18fbfdec3
comparison
equal deleted inserted replaced
2379:bce19d88266c 2380:7fbcfc1574dc
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.02f /* how sensitive the ship is to the accelerometer */
15
16 static SDL_Joystick *accelerometer; /* used for controlling the ship */
17
18 static struct {
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 } ship;
23
24 static SDL_TextureID shipID=0; /* texture for spaceship */
25 static SDL_TextureID spaceID=0; /* texture for space (background */
26
27 void render(void) {
28
29 /* get joystick (accelerometer) axis values and normalize them */
30 float amax = (float)(0x7FFF); /* largest Sint16 number */
31 float ax = SDL_JoystickGetAxis(accelerometer, 0) / amax;
32 float ay = -SDL_JoystickGetAxis(accelerometer, 1) / amax;
33
34 /* ship screen constraints */
35 Uint32 minx = 0.0f;
36 Uint32 maxx = SCREEN_WIDTH - ship.rect.w;
37 Uint32 miny = 0.0f;
38 Uint32 maxy = SCREEN_HEIGHT - ship.rect.h;
39
40 /* update velocity from accelerometer */
41 ship.vx += ax * GRAVITY_CONSTANT * MILLESECONDS_PER_FRAME;
42 ship.vy += ay * GRAVITY_CONSTANT * MILLESECONDS_PER_FRAME;
43
44 float speed = sqrt(ship.vx * ship.vx + ship.vy * ship.vy);
45
46 if (speed > 0) {
47 /* compensate for friction */
48 float dirx = ship.vx / speed; /* normalized x velocity */
49 float diry = ship.vy / speed; /* normalized y velocity */
50
51 /* update velocity due to friction */
52 if (speed - FRICTION * MILLESECONDS_PER_FRAME > 0) {
53 /* apply friction */
54 ship.vx -= dirx * FRICTION * MILLESECONDS_PER_FRAME;
55 ship.vy -= diry * FRICTION * MILLESECONDS_PER_FRAME;
56 }
57 else {
58 /* applying friction would MORE than stop the ship, so just stop the ship */
59 ship.vx = 0.0f;
60 ship.vy = 0.0f;
61 }
62 }
63
64 /* update ship location */
65 ship.x += ship.vx * MILLESECONDS_PER_FRAME;
66 ship.y += ship.vy * MILLESECONDS_PER_FRAME;
67
68 if (ship.x > maxx) {
69 ship.x = maxx;
70 ship.vx = -ship.vx * DAMPING;
71 }
72 else if (ship.x < minx) {
73 ship.x = minx;
74 ship.vx = -ship.vx * DAMPING;
75 }
76 if (ship.y > maxy) {
77 ship.y = maxy;
78 ship.vy = -ship.vy * DAMPING;
79 }
80 else if (ship.y < miny) {
81 ship.y = miny;
82 ship.vy = -ship.vy * DAMPING;
83 }
84
85 /* draw the background */
86 SDL_RenderCopy(spaceID, NULL, NULL);
87
88 /* draw the ship */
89 ship.rect.x = ship.x;
90 ship.rect.y = ship.y;
91
92 SDL_RenderCopy(shipID, NULL, &ship.rect);
93
94 /* update screen */
95 SDL_RenderPresent();
96
97 }
98
99 void initializeTextures() {
100
101 SDL_Surface *bmp_surface;
102 SDL_Surface *bmp_surface_rgba;
103 int format = SDL_PIXELFORMAT_ABGR8888; /* desired texture format */
104 Uint32 Rmask, Gmask, Bmask, Amask; /* masks for desired format */
105 int bpp; /* bits per pixel for desired format */
106
107 /* load the ship */
108 bmp_surface = SDL_LoadBMP("ship.bmp");
109 if (bmp_surface == NULL) {
110 fatalError("could not ship.bmp");
111 }
112 /* set blue to transparent on the ship */
113 SDL_SetColorKey(bmp_surface, 1, SDL_MapRGB(bmp_surface->format, 0, 0, 255));
114 SDL_PixelFormatEnumToMasks(format, &bpp, &Rmask, &Gmask, &Bmask, &Amask);
115 /*
116 create a new RGBA surface and blit the bmp to it
117 this is an extra step, but it seems to be necessary for the color key to work
118
119 does the fact that this is necessary indicate a bug in SDL?
120 */
121 bmp_surface_rgba = SDL_CreateRGBSurface(0, bmp_surface->w, bmp_surface->h, bpp, Rmask, Gmask, Bmask, Amask);
122 SDL_BlitSurface(bmp_surface, NULL, bmp_surface_rgba, NULL);
123
124 /* create ship texture from surface */
125 shipID = SDL_CreateTextureFromSurface(format, bmp_surface_rgba);
126 if (shipID == 0) {
127 fatalError("could not create ship texture");
128 }
129 SDL_SetTextureBlendMode(shipID, SDL_TEXTUREBLENDMODE_BLEND);
130
131 /* set the width and height of the ship from the surface dimensions */
132 ship.rect.w = bmp_surface->w;
133 ship.rect.h = bmp_surface->h;
134
135 SDL_FreeSurface(bmp_surface_rgba);
136 SDL_FreeSurface(bmp_surface);
137
138 /* load the space background */
139 bmp_surface = SDL_LoadBMP("space.bmp");
140 if (bmp_surface == NULL) {
141 fatalError("could not load space.bmp");
142 }
143 /* create space texture from surface */
144 spaceID = SDL_CreateTextureFromSurface(format, bmp_surface);
145 if (spaceID == 0) {
146 fatalError("could not create space texture");
147 }
148 SDL_FreeSurface(bmp_surface);
149
150 }
151
152
153
154 int main(int argc, char *argv[]) {
155
156 SDL_WindowID windowID; /* ID of main window */
157 Uint32 startFrame; /* time frame began to process */
158 Uint32 endFrame; /* time frame ended processing */
159 Uint32 delay; /* time to pause waiting to draw next frame */
160 int done; /* should we clean up and exit? */
161
162 /* initialize SDL */
163 if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_JOYSTICK) < 0) {
164 fatalError("Could not initialize SDL");
165 }
166
167 /* create main window and renderer */
168 windowID = SDL_CreateWindow(NULL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,\
169 SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN|SDL_WINDOW_BORDERLESS);
170 SDL_CreateRenderer(windowID, 0, 0);
171
172 /* print out some info about joysticks and try to open accelerometer for use */
173 printf("There are %d joysticks available\n", SDL_NumJoysticks());
174 printf("Default joystick (index 0) is %s\n", SDL_JoystickName(0));
175 accelerometer = SDL_JoystickOpen(0);
176 if (accelerometer == NULL) {
177 fatalError("Could not open joystick (accelerometer)");
178 }
179 printf("joystick number of axis = %d\n", SDL_JoystickNumAxes(accelerometer));
180 printf("joystick number of hats = %d\n", SDL_JoystickNumHats(accelerometer));
181 printf("joystick number of balls = %d\n", SDL_JoystickNumBalls(accelerometer));
182 printf("joystick number of buttons = %d\n", SDL_JoystickNumButtons(accelerometer));
183
184 /* load graphics */
185 initializeTextures();
186
187 /* setup ship */
188 ship.x = (SCREEN_WIDTH - ship.rect.w) / 2;
189 ship.y = (SCREEN_HEIGHT - ship.rect.h) / 2;
190 ship.vx = 0.0f;
191 ship.vy = 0.0f;
192
193 done = 0;
194 /* enter main loop */
195 while(!done) {
196 startFrame = SDL_GetTicks();
197 SDL_Event event;
198 while (SDL_PollEvent(&event)) {
199 if (event.type == SDL_QUIT) {
200 done = 1;
201 }
202 }
203 render();
204 endFrame = SDL_GetTicks();
205
206 /* figure out how much time we have left, and then sleep */
207 delay = MILLESECONDS_PER_FRAME - (endFrame - startFrame);
208 if (delay < 0) {
209 delay = 0;
210 } else if (delay > MILLESECONDS_PER_FRAME) {
211 delay = MILLESECONDS_PER_FRAME;
212 }
213 SDL_Delay(delay);
214 }
215
216 /* delete textures */
217 SDL_DestroyTexture(shipID);
218 SDL_DestroyTexture(spaceID);
219
220 /* shutdown SDL */
221 SDL_Quit();
222
223 return 0;
224
225 }