Mercurial > sdl-ios-xcode
comparison touchTest/gestureTest.c @ 4651:86c171888eee
Added gesture test c file. Beginning of gesture recognition.
author | Jim Grandpre <jim.tla@gmail.com> |
---|---|
date | Mon, 14 Jun 2010 01:44:04 -0400 |
parents | |
children | 744b75ad18b8 |
comparison
equal
deleted
inserted
replaced
4646:eea1bf53effa | 4651:86c171888eee |
---|---|
1 #include <stdio.h> | |
2 #include <SDL.h> | |
3 #include <math.h> | |
4 #include <SDL_touch.h> | |
5 | |
6 #define PI 3.1415926535897 | |
7 #define WIDTH 640 | |
8 #define HEIGHT 480 | |
9 #define BPP 4 | |
10 #define DEPTH 32 | |
11 | |
12 #define MAXFINGERS 3 | |
13 | |
14 | |
15 | |
16 | |
17 //MUST BE A POWER OF 2! | |
18 #define EVENT_BUF_SIZE 256 | |
19 | |
20 SDL_Event events[EVENT_BUF_SIZE]; | |
21 int eventWrite; | |
22 | |
23 int mousx,mousy; | |
24 int keystat[512]; | |
25 int bstatus; | |
26 | |
27 int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF}; | |
28 | |
29 int index2fingerid[MAXFINGERS]; | |
30 int fingersDown; | |
31 | |
32 typedef struct { | |
33 float x,y; | |
34 } Point; | |
35 | |
36 typedef struct { | |
37 Point p; | |
38 float pressure; | |
39 int id; | |
40 } Finger; | |
41 | |
42 | |
43 Finger finger[MAXFINGERS]; | |
44 | |
45 Finger gestureLast[MAXFINGERS]; | |
46 | |
47 void handler (int sig) | |
48 { | |
49 printf ("\exiting...(%d)\n", sig); | |
50 exit (0); | |
51 } | |
52 | |
53 void perror_exit (char *error) | |
54 { | |
55 perror (error); | |
56 handler (9); | |
57 } | |
58 | |
59 | |
60 void setpix(SDL_Surface *screen, int x, int y, unsigned int col) | |
61 { | |
62 Uint32 *pixmem32; | |
63 Uint32 colour; | |
64 | |
65 if((unsigned)x > screen->w) return; | |
66 if((unsigned)y > screen->h) return; | |
67 | |
68 pixmem32 = (Uint32*) screen->pixels + y*screen->pitch/BPP + x; | |
69 | |
70 Uint8 r,g,b; | |
71 float a; | |
72 | |
73 memcpy(&colour,pixmem32,screen->format->BytesPerPixel); | |
74 | |
75 SDL_GetRGB(colour,screen->format,&r,&g,&b); //Always returns 0xFFFFFF? | |
76 //r = 0;g = 0; b = 0; | |
77 a = (col>>24)&0xFF; | |
78 if(a == 0) a = 0xFF; //Hack, to make things easier. | |
79 a /= 0xFF; | |
80 r = r*(1-a) + ((col>>16)&0xFF)*(a); | |
81 g = g*(1-a) + ((col>> 8)&0xFF)*(a); | |
82 b = b*(1-a) + ((col>> 0)&0xFF)*(a); | |
83 colour = SDL_MapRGB( screen->format,r, g, b); | |
84 | |
85 | |
86 *pixmem32 = colour; | |
87 } | |
88 | |
89 void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c) | |
90 { | |
91 | |
92 float a; | |
93 int tx; | |
94 /* | |
95 for(a=0;a<PI/2;a+=1.f/(float)abs(r)) | |
96 { | |
97 if(r > 0) { //r > 0 ==> filled circle | |
98 for(tx=x-r*cos(a);tx<x+r*cos(a);tx++) { | |
99 setpix(screen,tx,(int)(y+r*sin(a)),c); | |
100 setpix(screen,tx,(int)(y-r*sin(a)),c); | |
101 } | |
102 } | |
103 else { | |
104 //Draw Outline | |
105 setpix(screen,(int)(x+r*cos(a)),(int)(y+r*sin(a)),c); | |
106 setpix(screen,(int)(x-r*cos(a)),(int)(y+r*sin(a)),c); | |
107 setpix(screen,(int)(x+r*cos(a)),(int)(y-r*sin(a)),c); | |
108 setpix(screen,(int)(x-r*cos(a)),(int)(y-r*sin(a)),c); | |
109 } | |
110 }*/ | |
111 int ty; | |
112 float xr; | |
113 for(ty = -abs(r);ty <= abs(r);ty++) { | |
114 xr = sqrt(r*r - ty*ty); | |
115 if(r > 0) { //r > 0 ==> filled circle | |
116 for(tx=-xr+.5;tx<=xr-.5;tx++) { | |
117 setpix(screen,x+tx,y+ty,c); | |
118 } | |
119 } | |
120 else { | |
121 setpix(screen,x-xr+.5,y+ty,c); | |
122 setpix(screen,x+xr-.5,y+ty,c); | |
123 } | |
124 } | |
125 } | |
126 | |
127 void DrawScreen(SDL_Surface* screen, int h) | |
128 { | |
129 int x, y, xm,ym,c; | |
130 if(SDL_MUSTLOCK(screen)) | |
131 { | |
132 if(SDL_LockSurface(screen) < 0) return; | |
133 } | |
134 for(y = 0; y < screen->h; y++ ) | |
135 { | |
136 for( x = 0; x < screen->w; x++ ) | |
137 { | |
138 //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h); | |
139 //xm = (x+h)%screen->w; | |
140 //ym = (y+h)%screen->w; | |
141 //c = sin(h/256*2*PI)*x*y/screen->w/screen->h; | |
142 //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c); | |
143 setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255); | |
144 //setpix(screen,x,y,0); //Inefficient, but that's okay... | |
145 } | |
146 } | |
147 drawCircle(screen,mousx,mousy,-30,0xFFFFFF); | |
148 | |
149 int i; | |
150 //draw Touch History | |
151 for(i = 0;i < MAXFINGERS;i++) gestureLast[i].id = -1; | |
152 for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i != eventWrite;i++) { | |
153 SDL_Event event = events[i&(EVENT_BUF_SIZE-1)]; | |
154 int age = eventWrite - i - 1; | |
155 if(event.type == SDL_FINGERMOTION || | |
156 event.type == SDL_FINGERDOWN || | |
157 event.type == SDL_FINGERUP) { | |
158 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId); | |
159 //SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId); | |
160 | |
161 float x = ((float)event.tfinger.x)/inTouch->xres; | |
162 float y = ((float)event.tfinger.y)/inTouch->yres; | |
163 int j,empty = -1; | |
164 for(j = 0;j<MAXFINGERS;j++) { | |
165 if(gestureLast[j].id == event.tfinger.fingerId) { | |
166 if(event.type == SDL_FINGERUP) { | |
167 gestureLast[j].id = -1; | |
168 break; | |
169 } | |
170 else { | |
171 gestureLast[j].p.x = x; | |
172 gestureLast[j].p.y = y; | |
173 break; | |
174 //pressure? | |
175 } | |
176 } | |
177 else if(gestureLast[j].id == -1 && empty == -1) { | |
178 empty = j; | |
179 } | |
180 } | |
181 | |
182 if(j >= MAXFINGERS && empty >= 0) { | |
183 printf("Finger Down!!!\n"); | |
184 j = empty; //important that j is the index of the added finger | |
185 gestureLast[j].id = event.tfinger.fingerId; | |
186 gestureLast[j].p.x = x; | |
187 gestureLast[j].p.y = y; | |
188 } | |
189 | |
190 //draw the touch && each centroid: | |
191 | |
192 if(gestureLast[j].id < 0) continue; //Finger up. Or some error... | |
193 int k; | |
194 for(k = 0; k < MAXFINGERS;k++) { | |
195 | |
196 if(gestureLast[k].id < 0) continue; | |
197 //colors have no alpha, so shouldn't overflow | |
198 unsigned int c = (colors[gestureLast[j].id%7] + | |
199 colors[gestureLast[k].id%7])/2; | |
200 unsigned int col = | |
201 ((unsigned int)(c*(.1+.85))) | | |
202 ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24; | |
203 x = (gestureLast[j].p.x + gestureLast[k].p.x)/2; | |
204 y = (gestureLast[j].p.y + gestureLast[k].p.y)/2; | |
205 if(event.type == SDL_FINGERMOTION) | |
206 drawCircle(screen,x*screen->w,y*screen->h,5,col); | |
207 else if(event.type == SDL_FINGERDOWN) | |
208 drawCircle(screen,x*screen->w,y*screen->h,-10,col); | |
209 } | |
210 } | |
211 } | |
212 | |
213 | |
214 for(i=0;i<MAXFINGERS;i++) | |
215 if(finger[i].p.x >= 0 && finger[i].p.y >= 0) | |
216 if(finger[i].pressure > 0) | |
217 drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h | |
218 ,20,0xFF*finger[i].pressure); | |
219 else | |
220 drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h | |
221 ,20,0xFF); | |
222 | |
223 | |
224 | |
225 | |
226 if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); | |
227 | |
228 SDL_Flip(screen); | |
229 } | |
230 | |
231 SDL_Surface* initScreen(int width,int height) | |
232 { | |
233 return SDL_SetVideoMode(width, height, DEPTH, | |
234 SDL_HWSURFACE | SDL_RESIZABLE); | |
235 } | |
236 | |
237 int main(int argc, char* argv[]) | |
238 { | |
239 SDL_Surface *screen; | |
240 SDL_Event event; | |
241 | |
242 int keypress = 0; | |
243 int h=0,s=1,i,j; | |
244 | |
245 memset(keystat,0,512*sizeof(keystat[0])); | |
246 if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1; | |
247 | |
248 if (!(screen = initScreen(WIDTH,HEIGHT))) | |
249 { | |
250 SDL_Quit(); | |
251 return 1; | |
252 } | |
253 | |
254 while(!keystat[27]) { | |
255 //Poll SDL | |
256 while(SDL_PollEvent(&event)) | |
257 { | |
258 //Record _all_ events | |
259 events[eventWrite & (EVENT_BUF_SIZE-1)] = event; | |
260 eventWrite++; | |
261 | |
262 switch (event.type) | |
263 { | |
264 case SDL_QUIT: | |
265 keystat[27] = 1; | |
266 break; | |
267 case SDL_KEYDOWN: | |
268 //printf("%i\n",event.key.keysym.sym); | |
269 keystat[event.key.keysym.sym] = 1; | |
270 //keypress = 1; | |
271 break; | |
272 case SDL_KEYUP: | |
273 //printf("%i\n",event.key.keysym.sym); | |
274 keystat[event.key.keysym.sym] = 0; | |
275 //keypress = 1; | |
276 break; | |
277 case SDL_VIDEORESIZE: | |
278 if (!(screen = initScreen(event.resize.w, | |
279 event.resize.h))) | |
280 { | |
281 SDL_Quit(); | |
282 return 1; | |
283 } | |
284 break; | |
285 case SDL_MOUSEMOTION: | |
286 mousx = event.motion.x; | |
287 mousy = event.motion.y; | |
288 break; | |
289 case SDL_MOUSEBUTTONDOWN: | |
290 bstatus |= (1<<(event.button.button-1)); | |
291 break; | |
292 case SDL_MOUSEBUTTONUP: | |
293 bstatus &= ~(1<<(event.button.button-1)); | |
294 break; | |
295 case SDL_FINGERMOTION: | |
296 ; | |
297 //printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId, | |
298 // event.tfinger.x,event.tfinger.y); | |
299 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId); | |
300 SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId); | |
301 | |
302 for(i = 0;i<MAXFINGERS;i++) | |
303 if(index2fingerid[i] == event.tfinger.fingerId) | |
304 break; | |
305 if(i == MAXFINGERS) break; | |
306 if(inTouch > 0) { | |
307 finger[i].p.x = ((float)event.tfinger.x)/ | |
308 inTouch->xres; | |
309 finger[i].p.y = ((float)event.tfinger.y)/ | |
310 inTouch->yres; | |
311 | |
312 finger[i].pressure = | |
313 ((float)event.tfinger.pressure)/inTouch->pressureres; | |
314 | |
315 printf("Finger: %i, Pressure: %f Pressureres: %i\n", | |
316 event.tfinger.fingerId, | |
317 finger[i].pressure, | |
318 inTouch->pressureres); | |
319 //printf("Finger: %i, pressure: %f\n",event.tfinger.fingerId, | |
320 // finger[event.tfinger.fingerId].pressure); | |
321 } | |
322 | |
323 break; | |
324 case SDL_FINGERDOWN: | |
325 printf("Finger: %i down - x: %i, y: %i\n",event.tfinger.fingerId, | |
326 event.tfinger.x,event.tfinger.y); | |
327 | |
328 for(i = 0;i<MAXFINGERS;i++) | |
329 if(index2fingerid[i] == -1) { | |
330 index2fingerid[i] = event.tfinger.fingerId; | |
331 break; | |
332 } | |
333 finger[i].p.x = event.tfinger.x; | |
334 finger[i].p.y = event.tfinger.y; | |
335 break; | |
336 case SDL_FINGERUP: | |
337 printf("Figner: %i up - x: %i, y: %i\n",event.tfinger.fingerId, | |
338 event.tfinger.x,event.tfinger.y); | |
339 for(i = 0;i<MAXFINGERS;i++) | |
340 if(index2fingerid[i] == event.tfinger.fingerId) { | |
341 index2fingerid[i] = -1; | |
342 break; | |
343 } | |
344 finger[i].p.x = -1; | |
345 finger[i].p.y = -1; | |
346 break; | |
347 } | |
348 } | |
349 //And draw | |
350 DrawScreen(screen,h); | |
351 /* | |
352 for(i=0;i<512;i++) | |
353 if(keystat[i]) printf("%i\n",i); | |
354 printf("Buttons:%i\n",bstatus); | |
355 */ | |
356 } | |
357 SDL_Quit(); | |
358 | |
359 return 0; | |
360 } |