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