Mercurial > sdl-ios-xcode
comparison touchTest/gestureSDLTest.c @ 4688:494f71f57a80
Fixed bugs related to keyboard handling in gestureSDLTest. Fixed gesture code (dynamic memory allocation). Cleaned up gesture and test code.
author | Jim Grandpre <jim.tla@gmail.com> |
---|---|
date | Fri, 13 Aug 2010 23:08:32 -0400 |
parents | 15dfe42edbfd |
children | f9ab8df6d45a |
comparison
equal
deleted
inserted
replaced
4687:257bdf117af8 | 4688:494f71f57a80 |
---|---|
24 #else | 24 #else |
25 #define PRIu64 "llu" | 25 #define PRIu64 "llu" |
26 #endif | 26 #endif |
27 #endif | 27 #endif |
28 | 28 |
29 #define PI 3.1415926535897 | |
30 #define PHI ((sqrt(5)-1)/2) | |
31 #define WIDTH 640 | 29 #define WIDTH 640 |
32 #define HEIGHT 480 | 30 #define HEIGHT 480 |
33 #define BPP 4 | 31 #define BPP 4 |
34 #define DEPTH 32 | 32 #define DEPTH 32 |
35 | 33 |
36 #define MAXFINGERS 5 | |
37 | |
38 #define DOLLARNPOINTS 64 | |
39 #define DOLLARSIZE 256 | |
40 | |
41 //MUST BE A POWER OF 2! | 34 //MUST BE A POWER OF 2! |
42 #define EVENT_BUF_SIZE 256 | 35 #define EVENT_BUF_SIZE 256 |
43 | 36 |
37 | |
38 #define VERBOSE SDL_FALSE | |
39 | |
44 SDL_Event events[EVENT_BUF_SIZE]; | 40 SDL_Event events[EVENT_BUF_SIZE]; |
45 int eventWrite; | 41 int eventWrite; |
46 | 42 |
47 int mousx,mousy; | |
48 int keystat[512]; | |
49 int bstatus; | |
50 | |
51 int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF}; | 43 int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF}; |
52 | |
53 SDL_FingerID index2fingerid[MAXFINGERS]; | |
54 int fingersDown; | |
55 | 44 |
56 typedef struct { | 45 typedef struct { |
57 float x,y; | 46 float x,y; |
58 } Point; | 47 } Point; |
59 | |
60 typedef struct { | |
61 Point p; | |
62 float pressure; | |
63 SDL_FingerID id; | |
64 } Finger; | |
65 | |
66 typedef struct { | |
67 Finger f; | |
68 Point cv; | |
69 float dtheta,dDist; | |
70 } TouchPoint; | |
71 | |
72 | |
73 typedef struct { //dt + s | |
74 Point d,s; //direction, start | |
75 int points; | |
76 } Line; | |
77 | |
78 | |
79 typedef struct { | |
80 float length; | |
81 | |
82 int numPoints; | |
83 Point p[EVENT_BUF_SIZE]; //To be safe | |
84 } DollarPath; | |
85 | 48 |
86 typedef struct { | 49 typedef struct { |
87 float ang,r; | 50 float ang,r; |
88 Point p; | 51 Point p; |
89 } Knob; | 52 } Knob; |
90 | 53 |
91 Knob knob; | 54 Knob knob; |
92 | 55 |
93 Finger finger[MAXFINGERS]; | |
94 | |
95 | |
96 DollarPath dollarPath[MAXFINGERS]; | |
97 | |
98 #define MAXTEMPLATES 4 | |
99 | |
100 Point dollarTemplate[MAXTEMPLATES][DOLLARNPOINTS]; | |
101 int numDollarTemplates = 0; | |
102 #ifdef DRAW_VECTOR_EST | |
103 Line gestureLine[MAXFINGERS]; | |
104 #endif | |
105 | |
106 void handler (int sig) | 56 void handler (int sig) |
107 { | 57 { |
108 printf ("\exiting...(%d)\n", sig); | 58 printf ("\exiting...(%d)\n", sig); |
109 exit (0); | 59 exit (0); |
110 } | 60 } |
112 void perror_exit (char *error) | 62 void perror_exit (char *error) |
113 { | 63 { |
114 perror (error); | 64 perror (error); |
115 handler (9); | 65 handler (9); |
116 } | 66 } |
117 | |
118 | 67 |
119 void setpix(SDL_Surface *screen, int x, int y, unsigned int col) | 68 void setpix(SDL_Surface *screen, int x, int y, unsigned int col) |
120 { | 69 { |
121 Uint32 *pixmem32; | 70 Uint32 *pixmem32; |
122 Uint32 colour; | 71 Uint32 colour; |
148 void drawLine(SDL_Surface *screen,int x0,int y0,int x1,int y1,unsigned int col) { | 97 void drawLine(SDL_Surface *screen,int x0,int y0,int x1,int y1,unsigned int col) { |
149 float t; | 98 float t; |
150 for(t=0;t<1;t+=1.f/SDL_max(abs(x0-x1),abs(y0-y1))) | 99 for(t=0;t<1;t+=1.f/SDL_max(abs(x0-x1),abs(y0-y1))) |
151 setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col); | 100 setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col); |
152 } | 101 } |
102 | |
153 void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c) | 103 void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c) |
154 { | 104 { |
155 | 105 int tx,ty; |
156 float a; | |
157 int tx; | |
158 | |
159 int ty; | |
160 float xr; | 106 float xr; |
161 for(ty = -abs(r);ty <= abs(r);ty++) { | 107 for(ty = -abs(r);ty <= abs(r);ty++) { |
162 xr = sqrt(r*r - ty*ty); | 108 xr = sqrt(r*r - ty*ty); |
163 if(r > 0) { //r > 0 ==> filled circle | 109 if(r > 0) { //r > 0 ==> filled circle |
164 for(tx=-xr+.5;tx<=xr-.5;tx++) { | 110 for(tx=-xr+.5;tx<=xr-.5;tx++) { |
171 } | 117 } |
172 } | 118 } |
173 } | 119 } |
174 | 120 |
175 void drawKnob(SDL_Surface* screen,Knob k) { | 121 void drawKnob(SDL_Surface* screen,Knob k) { |
176 //printf("Knob: x = %f, y = %f, r = %f, a = %f\n",k.p.x,k.p.y,k.r,k.ang); | 122 drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF); |
177 | |
178 drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF); | |
179 | |
180 drawCircle(screen,(k.p.x+k.r/2*cos(k.ang))*screen->w, | 123 drawCircle(screen,(k.p.x+k.r/2*cos(k.ang))*screen->w, |
181 (k.p.y+k.r/2*sin(k.ang))*screen->h,k.r/4*screen->w,0); | 124 (k.p.y+k.r/2*sin(k.ang))*screen->h,k.r/4*screen->w,0); |
182 | 125 } |
183 } | 126 |
184 | 127 void DrawScreen(SDL_Surface* screen) |
185 void DrawScreen(SDL_Surface* screen, int h) | 128 { |
186 { | 129 int x, y; |
187 int x, y, xm,ym,c; | |
188 if(SDL_MUSTLOCK(screen)) | 130 if(SDL_MUSTLOCK(screen)) |
189 { | 131 { |
190 if(SDL_LockSurface(screen) < 0) return; | 132 if(SDL_LockSurface(screen) < 0) return; |
191 } | 133 } |
192 for(y = 0; y < screen->h; y++ ) | 134 for(y = 0;y < screen->h;y++) |
193 { | 135 for(x = 0;x < screen->w;x++) |
194 for( x = 0; x < screen->w; x++ ) | 136 setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255); |
195 { | |
196 //setpixel(screen, x, y, (x*x)/256+3*y+h, (y*y)/256+x+h, h); | |
197 //xm = (x+h)%screen->w; | |
198 //ym = (y+h)%screen->w; | |
199 //c = sin(h/256*2*PI)*x*y/screen->w/screen->h; | |
200 //setpix(screen,x,y,255*sin(xm/screen->w*2*PI),sin(h/255*2*PI)*255*y/screen->h,c); | |
201 setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255); | |
202 //setpix(screen,x,y,0); //Inefficient, but that's okay... | |
203 } | |
204 } | |
205 drawCircle(screen,mousx,mousy,-30,0xFFFFFF); | |
206 drawLine(screen,0,0,screen->w,screen->h,0xFFFFFF); | |
207 | 137 |
208 int i; | 138 int i; |
209 //draw Touch History | 139 //draw Touch History |
210 TouchPoint gestureLast[MAXFINGERS]; | |
211 //printf("------------------Start History------------------\n"); | |
212 for(i = 0;i < MAXFINGERS;i++) { | |
213 gestureLast[i].f.id = -1; | |
214 } | |
215 int numDownFingers = 0; | |
216 Point centroid; | |
217 float gdtheta,gdDist; | |
218 | |
219 | |
220 for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i < eventWrite;i++) { | 140 for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i < eventWrite;i++) { |
221 SDL_Event event = events[i&(EVENT_BUF_SIZE-1)]; | 141 SDL_Event event = events[i&(EVENT_BUF_SIZE-1)]; |
222 int age = eventWrite - i - 1; | 142 int age = eventWrite - i - 1; |
223 if(event.type == SDL_FINGERMOTION || | 143 if(event.type == SDL_FINGERMOTION || |
224 event.type == SDL_FINGERDOWN || | 144 event.type == SDL_FINGERDOWN || |
225 event.type == SDL_FINGERUP) { | 145 event.type == SDL_FINGERUP) { |
226 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId); | 146 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId); |
227 //SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId); | 147 if(inTouch == NULL) continue; |
228 | 148 |
229 float x = ((float)event.tfinger.x)/inTouch->xres; | 149 float x = ((float)event.tfinger.x)/inTouch->xres; |
230 float y = ((float)event.tfinger.y)/inTouch->yres; | 150 float y = ((float)event.tfinger.y)/inTouch->yres; |
231 | 151 |
232 //draw the touch: | 152 //draw the touch: |
233 | |
234 unsigned int c = colors[event.tfinger.touchId%7]; | 153 unsigned int c = colors[event.tfinger.touchId%7]; |
235 unsigned int col = | 154 unsigned int col = |
236 ((unsigned int)(c*(.1+.85))) | | 155 ((unsigned int)(c*(.1+.85))) | |
237 ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24; | 156 ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24; |
238 | 157 |
241 else if(event.type == SDL_FINGERDOWN) | 160 else if(event.type == SDL_FINGERDOWN) |
242 drawCircle(screen,x*screen->w,y*screen->h,-10,col); | 161 drawCircle(screen,x*screen->w,y*screen->h,-10,col); |
243 } | 162 } |
244 } | 163 } |
245 | 164 |
246 /* | |
247 for(i=0;i<MAXFINGERS;i++) | |
248 if(finger[i].p.x >= 0 && finger[i].p.y >= 0) | |
249 if(finger[i].pressure > 0) | |
250 drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h | |
251 ,20,0xFF*finger[i].pressure); | |
252 else | |
253 drawCircle(screen,finger[i].p.x*screen->w,finger[i].p.y*screen->h | |
254 ,20,0xFF); | |
255 */ | |
256 | |
257 | |
258 keystat[32] = 0; | |
259 | |
260 if(knob.p.x > 0) | 165 if(knob.p.x > 0) |
261 drawKnob(screen,knob); | 166 drawKnob(screen,knob); |
262 | 167 |
263 if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); | 168 if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen); |
264 | |
265 SDL_Flip(screen); | 169 SDL_Flip(screen); |
266 } | 170 } |
267 | 171 |
268 SDL_Surface* initScreen(int width,int height) | 172 SDL_Surface* initScreen(int width,int height) |
269 { | 173 { |
273 | 177 |
274 int main(int argc, char* argv[]) | 178 int main(int argc, char* argv[]) |
275 { | 179 { |
276 SDL_Surface *screen; | 180 SDL_Surface *screen; |
277 SDL_Event event; | 181 SDL_Event event; |
278 | |
279 int keypress = 0; | |
280 int h=0,s=1,i,j; | |
281 | 182 |
282 //gesture variables | 183 //gesture variables |
283 int numDownFingers = 0; | |
284 float gdtheta = 0,gdDist = 0; | |
285 Point centroid; | |
286 knob.r = .1; | 184 knob.r = .1; |
287 knob.ang = 0; | 185 knob.ang = 0; |
288 TouchPoint gestureLast[MAXFINGERS]; | 186 |
289 | 187 |
290 | 188 SDL_bool quitting = SDL_FALSE; |
291 | 189 SDL_RWops *src; |
292 memset(keystat,0,512*sizeof(keystat[0])); | 190 |
293 if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1; | 191 if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1; |
294 | 192 |
295 if (!(screen = initScreen(WIDTH,HEIGHT))) | 193 if (!(screen = initScreen(WIDTH,HEIGHT))) |
296 { | 194 { |
297 SDL_Quit(); | 195 SDL_Quit(); |
298 return 1; | 196 return 1; |
299 } | 197 } |
300 | 198 |
301 while(!keystat[27]) { | 199 while(!quitting) { |
302 //Poll SDL | |
303 while(SDL_PollEvent(&event)) | 200 while(SDL_PollEvent(&event)) |
304 { | 201 { |
305 //Record _all_ events | 202 //Record _all_ events |
306 events[eventWrite & (EVENT_BUF_SIZE-1)] = event; | 203 events[eventWrite & (EVENT_BUF_SIZE-1)] = event; |
307 eventWrite++; | 204 eventWrite++; |
308 | 205 |
309 switch (event.type) | 206 switch (event.type) |
310 { | 207 { |
311 case SDL_QUIT: | 208 case SDL_QUIT: |
312 keystat[27] = 1; | 209 quitting = SDL_TRUE; |
313 break; | 210 break; |
314 case SDL_KEYDOWN: | 211 case SDL_KEYDOWN: |
315 //printf("%i\n",event.key.keysym.sym); | 212 switch (event.key.keysym.sym) |
316 keystat[event.key.keysym.sym] = 1; | 213 { |
317 if(event.key.keysym.sym == 32) { | 214 case SDLK_SPACE: |
318 SDL_RecordGesture(-1); | 215 SDL_RecordGesture(-1); |
216 break; | |
217 case SDLK_s: | |
218 src = SDL_RWFromFile("gestureSave","w"); | |
219 printf("Wrote %i templates\n",SDL_SaveAllDollarTemplates(src)); | |
220 SDL_RWclose(src); | |
221 break; | |
222 case SDLK_l: | |
223 src = SDL_RWFromFile("gestureSave","r"); | |
224 printf("Loaded: %i\n",SDL_LoadDollarTemplates(-1,src)); | |
225 SDL_RWclose(src); | |
226 break; | |
227 case SDLK_ESCAPE: | |
228 quitting = SDL_TRUE; | |
229 break; | |
319 } | 230 } |
320 else if(event.key.keysym.sym == 115) { | |
321 SDL_RWops *src; | |
322 //fp = fopen("gestureSave","w"); | |
323 src = SDL_RWFromFile("gestureSave","w"); | |
324 | |
325 printf("Wrote %i templates\n",SDL_SaveAllDollarTemplates(src)); | |
326 //fclose(fp); | |
327 SDL_RWclose(src); | |
328 } | |
329 else if(event.key.keysym.sym == 108) { | |
330 SDL_RWops *src; | |
331 //fp = fopen("gestureSave","r"); | |
332 src = SDL_RWFromFile("gestureSave","r"); | |
333 printf("Loaded: %i\n",SDL_LoadDollarTemplates(-1,src)); | |
334 //fclose(fp); | |
335 SDL_RWclose(src); | |
336 } | |
337 | |
338 //keypress = 1; | |
339 break; | |
340 case SDL_KEYUP: | |
341 //printf("%i\n",event.key.keysym.sym); | |
342 keystat[event.key.keysym.sym] = 0; | |
343 //keypress = 1; | |
344 break; | 231 break; |
345 case SDL_VIDEORESIZE: | 232 case SDL_VIDEORESIZE: |
346 if (!(screen = initScreen(event.resize.w, | 233 if (!(screen = initScreen(event.resize.w, |
347 event.resize.h))) | 234 event.resize.h))) |
348 { | 235 { |
349 SDL_Quit(); | 236 SDL_Quit(); |
350 return 1; | 237 return 1; |
351 } | 238 } |
352 break; | 239 break; |
353 case SDL_MOUSEMOTION: | |
354 mousx = event.motion.x; | |
355 mousy = event.motion.y; | |
356 break; | |
357 case SDL_MOUSEBUTTONDOWN: | |
358 bstatus |= (1<<(event.button.button-1)); | |
359 break; | |
360 case SDL_MOUSEBUTTONUP: | |
361 bstatus &= ~(1<<(event.button.button-1)); | |
362 break; | |
363 case SDL_FINGERMOTION: | 240 case SDL_FINGERMOTION: |
364 ; | 241 ; |
365 //printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId, | 242 #if VERBOSE |
366 // event.tfinger.x,event.tfinger.y); | 243 printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId, |
244 event.tfinger.x,event.tfinger.y); | |
245 #endif | |
367 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId); | 246 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId); |
368 SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId); | 247 SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId); |
369 /* | |
370 for(i = 0;i<MAXFINGERS;i++) | |
371 if(index2fingerid[i] == event.tfinger.fingerId) | |
372 break; | |
373 if(i == MAXFINGERS) break; | |
374 if(inTouch > 0) { | |
375 finger[i].p.x = ((float)event.tfinger.x)/ | |
376 inTouch->xres; | |
377 finger[i].p.y = ((float)event.tfinger.y)/ | |
378 inTouch->yres; | |
379 | |
380 finger[i].pressure = | |
381 ((float)event.tfinger.pressure)/inTouch->pressureres; | |
382 */ | |
383 /* | |
384 printf("Finger: %i, Pressure: %f Pressureres: %i\n", | |
385 event.tfinger.fingerId, | |
386 finger[i].pressure, | |
387 inTouch->pressureres); | |
388 */ | |
389 //printf("Finger: %i, pressure: %f\n",event.tfinger.fingerId, | |
390 // finger[event.tfinger.fingerId].pressure); | |
391 //} | |
392 | |
393 break; | 248 break; |
394 case SDL_FINGERDOWN: | 249 case SDL_FINGERDOWN: |
395 //printf("Finger: %"PRIs64" down - x: %i, y: %i\n",event.tfinger.fingerId,event.tfinger.x,event.tfinger.y); | 250 #if VERBOSE |
396 /* | 251 printf("Finger: %"PRIs64" down - x: %i, y: %i\n", |
397 for(i = 0;i<MAXFINGERS;i++) | 252 event.tfinger.fingerId,event.tfinger.x,event.tfinger.y); |
398 if(index2fingerid[i] == -1) { | 253 #endif |
399 index2fingerid[i] = event.tfinger.fingerId; | |
400 break; | |
401 } | |
402 finger[i].p.x = event.tfinger.x; | |
403 finger[i].p.y = event.tfinger.y; | |
404 break; | 254 break; |
405 case SDL_FINGERUP: | 255 case SDL_FINGERUP: |
406 //printf("Finger: %"PRIs64" up - x: %i, y: %i\n",event.tfinger.fingerId,event.tfinger.x,event.tfinger.y); | 256 #if VERBOSE |
407 for(i = 0;i<MAXFINGERS;i++) | 257 printf("Finger: %"PRIs64" up - x: %i, y: %i\n", |
408 if(index2fingerid[i] == event.tfinger.fingerId) { | 258 event.tfinger.fingerId,event.tfinger.x,event.tfinger.y); |
409 index2fingerid[i] = -1; | 259 #endif |
410 break; | |
411 } | |
412 finger[i].p.x = -1; | |
413 finger[i].p.y = -1; | |
414 */ | |
415 break; | 260 break; |
416 case SDL_MULTIGESTURE: | 261 case SDL_MULTIGESTURE: |
417 /* | 262 #if VERBOSE |
418 printf("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f\n", | 263 printf("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f\n", |
419 event.mgesture.x, | 264 event.mgesture.x, |
420 event.mgesture.y, | 265 event.mgesture.y, |
421 event.mgesture.dTheta, | 266 event.mgesture.dTheta, |
422 event.mgesture.dDist); | 267 event.mgesture.dDist); |
423 printf("MG: numDownTouch = %i\n",event.mgesture.numFingers); | 268 printf("MG: numDownTouch = %i\n",event.mgesture.numFingers); |
424 */ | 269 #endif |
425 knob.p.x = event.mgesture.x; | 270 knob.p.x = event.mgesture.x; |
426 knob.p.y = event.mgesture.y; | 271 knob.p.y = event.mgesture.y; |
427 knob.ang += event.mgesture.dTheta; | 272 knob.ang += event.mgesture.dTheta; |
428 knob.r += event.mgesture.dDist; | 273 knob.r += event.mgesture.dDist; |
429 break; | 274 break; |
435 case SDL_DOLLARRECORD: | 280 case SDL_DOLLARRECORD: |
436 printf("Recorded gesture: %"PRIs64"\n",event.dgesture.gestureId); | 281 printf("Recorded gesture: %"PRIs64"\n",event.dgesture.gestureId); |
437 break; | 282 break; |
438 } | 283 } |
439 } | 284 } |
440 DrawScreen(screen,h); | 285 DrawScreen(screen); |
441 //for(i = 0; i < 256; i++) | |
442 // if(keystat[i]) | |
443 // printf("Key %i down\n",i); | |
444 } | 286 } |
445 SDL_Quit(); | 287 SDL_Quit(); |
446 | |
447 return 0; | 288 return 0; |
448 } | 289 } |
449 | 290 |