Mercurial > sdl-ios-xcode
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 } |