comparison test/testgesture.c @ 4689:f9ab8df6d45a

Added README.touch and README.gesture. Moved touchtest/gestureSDLTest to test/testgesture
author Jim Grandpre <jim.tla@gmail.com>
date Sun, 15 Aug 2010 00:36:28 -0400
parents
children f5f70fed2c4c
comparison
equal deleted inserted replaced
4688:494f71f57a80 4689:f9ab8df6d45a
1 /* Usage:
2 * Spacebar to begin recording a gesture on all touches.
3 * s to save all touches into "./gestureSave"
4 * l to load all touches from "./gestureSave"
5 */
6
7 #include <stdio.h>
8 #include <SDL.h>
9 #include <math.h>
10 #include <SDL_touch.h>
11 #include <SDL_gesture.h>
12
13
14 /* Make sure we have good macros for printing 32 and 64 bit values */
15 #ifndef PRIs32
16 #define PRIs32 "d"
17 #endif
18 #ifndef PRIu32
19 #define PRIu32 "u"
20 #endif
21 #ifndef PRIs64
22 #ifdef __WIN32__
23 #define PRIs64 "I64"
24 #else
25 #define PRIs64 "lld"
26 #endif
27 #endif
28 #ifndef PRIu64
29 #ifdef __WIN32__
30 #define PRIu64 "I64u"
31 #else
32 #define PRIu64 "llu"
33 #endif
34 #endif
35
36 #define WIDTH 640
37 #define HEIGHT 480
38 #define BPP 4
39 #define DEPTH 32
40
41 //MUST BE A POWER OF 2!
42 #define EVENT_BUF_SIZE 256
43
44
45 #define VERBOSE SDL_FALSE
46
47 SDL_Event events[EVENT_BUF_SIZE];
48 int eventWrite;
49
50 int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
51
52 typedef struct {
53 float x,y;
54 } Point;
55
56 typedef struct {
57 float ang,r;
58 Point p;
59 } Knob;
60
61 Knob knob;
62
63 void handler (int sig)
64 {
65 printf ("\exiting...(%d)\n", sig);
66 exit (0);
67 }
68
69 void perror_exit (char *error)
70 {
71 perror (error);
72 handler (9);
73 }
74
75 void setpix(SDL_Surface *screen, int x, int y, unsigned int col)
76 {
77 Uint32 *pixmem32;
78 Uint32 colour;
79
80 if((unsigned)x > screen->w) return;
81 if((unsigned)y > screen->h) return;
82
83 pixmem32 = (Uint32*) screen->pixels + y*screen->pitch/BPP + x;
84
85 Uint8 r,g,b;
86 float a;
87
88 memcpy(&colour,pixmem32,screen->format->BytesPerPixel);
89
90 SDL_GetRGB(colour,screen->format,&r,&g,&b);
91 //r = 0;g = 0; b = 0;
92 a = (col>>24)&0xFF;
93 if(a == 0) a = 0xFF; //Hack, to make things easier.
94 a /= 0xFF;
95 r = r*(1-a) + ((col>>16)&0xFF)*(a);
96 g = g*(1-a) + ((col>> 8)&0xFF)*(a);
97 b = b*(1-a) + ((col>> 0)&0xFF)*(a);
98 colour = SDL_MapRGB( screen->format,r, g, b);
99
100
101 *pixmem32 = colour;
102 }
103
104 void drawLine(SDL_Surface *screen,int x0,int y0,int x1,int y1,unsigned int col) {
105 float t;
106 for(t=0;t<1;t+=1.f/SDL_max(abs(x0-x1),abs(y0-y1)))
107 setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
108 }
109
110 void drawCircle(SDL_Surface* screen,int x,int y,int r,unsigned int c)
111 {
112 int tx,ty;
113 float xr;
114 for(ty = -abs(r);ty <= abs(r);ty++) {
115 xr = sqrt(r*r - ty*ty);
116 if(r > 0) { //r > 0 ==> filled circle
117 for(tx=-xr+.5;tx<=xr-.5;tx++) {
118 setpix(screen,x+tx,y+ty,c);
119 }
120 }
121 else {
122 setpix(screen,x-xr+.5,y+ty,c);
123 setpix(screen,x+xr-.5,y+ty,c);
124 }
125 }
126 }
127
128 void drawKnob(SDL_Surface* screen,Knob k) {
129 drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF);
130 drawCircle(screen,(k.p.x+k.r/2*cos(k.ang))*screen->w,
131 (k.p.y+k.r/2*sin(k.ang))*screen->h,k.r/4*screen->w,0);
132 }
133
134 void DrawScreen(SDL_Surface* screen)
135 {
136 int x, y;
137 if(SDL_MUSTLOCK(screen))
138 {
139 if(SDL_LockSurface(screen) < 0) return;
140 }
141 for(y = 0;y < screen->h;y++)
142 for(x = 0;x < screen->w;x++)
143 setpix(screen,x,y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
144
145 int i;
146 //draw Touch History
147 for(i = SDL_max(0,eventWrite - EVENT_BUF_SIZE);i < eventWrite;i++) {
148 SDL_Event event = events[i&(EVENT_BUF_SIZE-1)];
149 int age = eventWrite - i - 1;
150 if(event.type == SDL_FINGERMOTION ||
151 event.type == SDL_FINGERDOWN ||
152 event.type == SDL_FINGERUP) {
153 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
154 if(inTouch == NULL) continue;
155
156 float x = ((float)event.tfinger.x)/inTouch->xres;
157 float y = ((float)event.tfinger.y)/inTouch->yres;
158
159 //draw the touch:
160 unsigned int c = colors[event.tfinger.touchId%7];
161 unsigned int col =
162 ((unsigned int)(c*(.1+.85))) |
163 ((unsigned int)((0xFF*(1-((float)age)/EVENT_BUF_SIZE))) & 0xFF)<<24;
164
165 if(event.type == SDL_FINGERMOTION)
166 drawCircle(screen,x*screen->w,y*screen->h,5,col);
167 else if(event.type == SDL_FINGERDOWN)
168 drawCircle(screen,x*screen->w,y*screen->h,-10,col);
169 }
170 }
171
172 if(knob.p.x > 0)
173 drawKnob(screen,knob);
174
175 if(SDL_MUSTLOCK(screen)) SDL_UnlockSurface(screen);
176 SDL_Flip(screen);
177 }
178
179 SDL_Surface* initScreen(int width,int height)
180 {
181 return SDL_SetVideoMode(width, height, DEPTH,
182 SDL_HWSURFACE | SDL_RESIZABLE);
183 }
184
185 int main(int argc, char* argv[])
186 {
187 SDL_Surface *screen;
188 SDL_Event event;
189
190 //gesture variables
191 knob.r = .1;
192 knob.ang = 0;
193
194
195 SDL_bool quitting = SDL_FALSE;
196 SDL_RWops *src;
197
198 if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
199
200 if (!(screen = initScreen(WIDTH,HEIGHT)))
201 {
202 SDL_Quit();
203 return 1;
204 }
205
206 while(!quitting) {
207 while(SDL_PollEvent(&event))
208 {
209 //Record _all_ events
210 events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
211 eventWrite++;
212
213 switch (event.type)
214 {
215 case SDL_QUIT:
216 quitting = SDL_TRUE;
217 break;
218 case SDL_KEYDOWN:
219 switch (event.key.keysym.sym)
220 {
221 case SDLK_SPACE:
222 SDL_RecordGesture(-1);
223 break;
224 case SDLK_s:
225 src = SDL_RWFromFile("gestureSave","w");
226 printf("Wrote %i templates\n",SDL_SaveAllDollarTemplates(src));
227 SDL_RWclose(src);
228 break;
229 case SDLK_l:
230 src = SDL_RWFromFile("gestureSave","r");
231 printf("Loaded: %i\n",SDL_LoadDollarTemplates(-1,src));
232 SDL_RWclose(src);
233 break;
234 case SDLK_ESCAPE:
235 quitting = SDL_TRUE;
236 break;
237 }
238 break;
239 case SDL_VIDEORESIZE:
240 if (!(screen = initScreen(event.resize.w,
241 event.resize.h)))
242 {
243 SDL_Quit();
244 return 1;
245 }
246 break;
247 case SDL_FINGERMOTION:
248 ;
249 #if VERBOSE
250 printf("Finger: %i,x: %i, y: %i\n",event.tfinger.fingerId,
251 event.tfinger.x,event.tfinger.y);
252 #endif
253 SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
254 SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
255 break;
256 case SDL_FINGERDOWN:
257 #if VERBOSE
258 printf("Finger: %"PRIs64" down - x: %i, y: %i\n",
259 event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
260 #endif
261 break;
262 case SDL_FINGERUP:
263 #if VERBOSE
264 printf("Finger: %"PRIs64" up - x: %i, y: %i\n",
265 event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
266 #endif
267 break;
268 case SDL_MULTIGESTURE:
269 #if VERBOSE
270 printf("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f\n",
271 event.mgesture.x,
272 event.mgesture.y,
273 event.mgesture.dTheta,
274 event.mgesture.dDist);
275 printf("MG: numDownTouch = %i\n",event.mgesture.numFingers);
276 #endif
277 knob.p.x = event.mgesture.x;
278 knob.p.y = event.mgesture.y;
279 knob.ang += event.mgesture.dTheta;
280 knob.r += event.mgesture.dDist;
281 break;
282 case SDL_DOLLARGESTURE:
283 printf("Gesture %"PRIs64" performed, error: %f\n",
284 event.dgesture.gestureId,
285 event.dgesture.error);
286 break;
287 case SDL_DOLLARRECORD:
288 printf("Recorded gesture: %"PRIs64"\n",event.dgesture.gestureId);
289 break;
290 }
291 }
292 DrawScreen(screen);
293 }
294 SDL_Quit();
295 return 0;
296 }
297