This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
testgesture.c
318 lines (275 loc) · 7.41 KB
1
2
3
4
5
6
7
8
9
10
11
/*
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
12
13
14
15
16
17
18
19
/* Usage:
* Spacebar to begin recording a gesture on all touches.
* s to save all touches into "./gestureSave"
* l to load all touches from "./gestureSave"
*/
#include <stdio.h>
#include <math.h>
20
21
22
23
#include "SDL.h"
#include "SDL_touch.h"
#include "SDL_gesture.h"
24
25
26
27
28
29
30
31
32
/* Make sure we have good macros for printing 32 and 64 bit values */
#ifndef PRIs32
#define PRIs32 "d"
#endif
#ifndef PRIu32
#define PRIu32 "u"
#endif
#ifndef PRIs64
33
#ifdef __WIN32__
34
35
36
37
38
39
#define PRIs64 "I64"
#else
#define PRIs64 "lld"
#endif
#endif
#ifndef PRIu64
40
#ifdef __WIN32__
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#define PRIu64 "I64u"
#else
#define PRIu64 "llu"
#endif
#endif
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
#define DEPTH 32
//MUST BE A POWER OF 2!
#define EVENT_BUF_SIZE 256
56
#define VERBOSE 0
57
58
59
60
static SDL_Window *window;
static SDL_Event events[EVENT_BUF_SIZE];
static int eventWrite;
61
62
63
static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
64
65
66
67
68
69
70
71
72
73
typedef struct {
float x,y;
} Point;
typedef struct {
float ang,r;
Point p;
} Knob;
74
static Knob knob;
75
76
77
void handler (int sig)
{
78
SDL_Log ("exiting...(%d)", sig);
79
80
81
82
83
84
85
86
87
exit (0);
}
void perror_exit (char *error)
{
perror (error);
handler (9);
}
88
void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
89
90
91
{
Uint32 *pixmem32;
Uint32 colour;
92
93
94
95
Uint8 r,g,b;
int x = (int)_x;
int y = (int)_y;
float a;
96
97
98
if(x < 0 || x > screen->w) return;
if(y < 0 || y > screen->h) return;
99
100
101
pixmem32 = (Uint32*) screen->pixels + y*screen->pitch/BPP + x;
102
SDL_memcpy(&colour,pixmem32,screen->format->BytesPerPixel);
103
104
105
SDL_GetRGB(colour,screen->format,&r,&g,&b);
//r = 0;g = 0; b = 0;
106
a = (float)((col>>24)&0xFF);
107
108
if(a == 0) a = 0xFF; //Hack, to make things easier.
a /= 0xFF;
109
110
111
r = (Uint8)(r*(1-a) + ((col>>16)&0xFF)*(a));
g = (Uint8)(g*(1-a) + ((col>> 8)&0xFF)*(a));
b = (Uint8)(b*(1-a) + ((col>> 0)&0xFF)*(a));
112
113
114
115
116
117
colour = SDL_MapRGB( screen->format,r, g, b);
*pixmem32 = colour;
}
118
void drawLine(SDL_Surface *screen,float x0,float y0,float x1,float y1,unsigned int col) {
119
float t;
120
for(t=0;t<1;t+=(float)(1.f/SDL_max(SDL_fabs(x0-x1),SDL_fabs(y0-y1))))
121
122
123
setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
}
124
void drawCircle(SDL_Surface* screen,float x,float y,float r,unsigned int c)
125
{
126
float tx,ty;
127
float xr;
128
129
for(ty = (float)-SDL_fabs(r);ty <= (float)SDL_fabs((int)r);ty++) {
xr = (float)sqrt(r*r - ty*ty);
130
if(r > 0) { //r > 0 ==> filled circle
131
for(tx=-xr+.5f;tx<=xr-.5;tx++) {
132
133
134
135
setpix(screen,x+tx,y+ty,c);
}
}
else {
136
137
setpix(screen,x-xr+.5f,y+ty,c);
setpix(screen,x+xr-.5f,y+ty,c);
138
139
140
141
142
143
}
}
}
void drawKnob(SDL_Surface* screen,Knob k) {
drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF);
144
145
drawCircle(screen,(k.p.x+k.r/2*cosf(k.ang))*screen->w,
(k.p.y+k.r/2*sinf(k.ang))*screen->h,k.r/4*screen->w,0);
146
147
148
149
}
void DrawScreen(SDL_Surface* screen)
{
150
151
152
153
154
int i;
#if 1
SDL_FillRect(screen, NULL, 0);
#else
int x, y;
155
156
for(y = 0;y < screen->h;y++)
for(x = 0;x < screen->w;x++)
157
setpix(screen,(float)x,(float)y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
158
#endif
159
160
//draw Touch History
161
162
163
for(i = eventWrite; i < eventWrite+EVENT_BUF_SIZE; ++i) {
const SDL_Event *event = &events[i&(EVENT_BUF_SIZE-1)];
float age = (float)(i - eventWrite) / EVENT_BUF_SIZE;
164
165
166
float x, y;
unsigned int c, col;
167
168
169
170
if(event->type == SDL_FINGERMOTION ||
event->type == SDL_FINGERDOWN ||
event->type == SDL_FINGERUP) {
SDL_Touch* inTouch = SDL_GetTouch(event->tfinger.touchId);
171
172
if(inTouch == NULL) continue;
173
174
x = ((float)event->tfinger.x)/inTouch->xres;
y = ((float)event->tfinger.y)/inTouch->yres;
175
176
//draw the touch:
177
178
c = colors[event->tfinger.fingerId%7];
col = ((unsigned int)(c*(.1+.85))) | (unsigned int)(0xFF*age)<<24;
179
180
if(event->type == SDL_FINGERMOTION)
181
drawCircle(screen,x*screen->w,y*screen->h,5,col);
182
else if(event->type == SDL_FINGERDOWN)
183
184
185
186
187
188
189
drawCircle(screen,x*screen->w,y*screen->h,-10,col);
}
}
if(knob.p.x > 0)
drawKnob(screen,knob);
190
SDL_UpdateWindowSurface(window);
191
192
193
194
}
SDL_Surface* initScreen(int width,int height)
{
195
196
197
198
199
200
201
202
203
if (!window) {
window = SDL_CreateWindow("Gesture Test",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
WIDTH, HEIGHT, SDL_WINDOW_RESIZABLE);
}
if (!window) {
return NULL;
}
return SDL_GetWindowSurface(window);
204
205
206
207
208
209
}
int main(int argc, char* argv[])
{
SDL_Surface *screen;
SDL_Event event;
210
211
SDL_bool quitting = SDL_FALSE;
SDL_RWops *src;
212
213
//gesture variables
214
knob.r = .1f;
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
knob.ang = 0;
if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
if (!(screen = initScreen(WIDTH,HEIGHT)))
{
SDL_Quit();
return 1;
}
while(!quitting) {
while(SDL_PollEvent(&event))
{
//Record _all_ events
events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
eventWrite++;
switch (event.type)
{
case SDL_QUIT:
quitting = SDL_TRUE;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_SPACE:
SDL_RecordGesture(-1);
break;
case SDLK_s:
src = SDL_RWFromFile("gestureSave","w");
245
SDL_Log("Wrote %i templates",SDL_SaveAllDollarTemplates(src));
246
247
248
249
SDL_RWclose(src);
break;
case SDLK_l:
src = SDL_RWFromFile("gestureSave","r");
250
SDL_Log("Loaded: %i",SDL_LoadDollarTemplates(-1,src));
251
252
253
254
255
256
257
SDL_RWclose(src);
break;
case SDLK_ESCAPE:
quitting = SDL_TRUE;
break;
}
break;
258
259
260
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
if (!(screen = initScreen(0, 0)))
261
262
263
264
{
SDL_Quit();
return 1;
}
265
}
266
break;
267
case SDL_FINGERMOTION:
268
#if VERBOSE
269
SDL_Log("Finger: %i,x: %i, y: %i",event.tfinger.fingerId,
270
271
event.tfinger.x,event.tfinger.y);
#endif
272
273
274
275
{
SDL_Touch* inTouch = SDL_GetTouch(event.tfinger.touchId);
SDL_Finger* inFinger = SDL_GetFinger(inTouch,event.tfinger.fingerId);
}
276
277
278
break;
case SDL_FINGERDOWN:
#if VERBOSE
279
SDL_Log("Finger: %"PRIs64" down - x: %i, y: %i",
280
281
282
283
284
event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
#endif
break;
case SDL_FINGERUP:
#if VERBOSE
285
SDL_Log("Finger: %"PRIs64" up - x: %i, y: %i",
286
287
288
289
290
event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
#endif
break;
case SDL_MULTIGESTURE:
#if VERBOSE
291
SDL_Log("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f",
292
293
294
295
event.mgesture.x,
event.mgesture.y,
event.mgesture.dTheta,
event.mgesture.dDist);
296
SDL_Log("MG: numDownTouch = %i",event.mgesture.numFingers);
297
298
299
300
301
302
303
#endif
knob.p.x = event.mgesture.x;
knob.p.y = event.mgesture.y;
knob.ang += event.mgesture.dTheta;
knob.r += event.mgesture.dDist;
break;
case SDL_DOLLARGESTURE:
304
SDL_Log("Gesture %"PRIs64" performed, error: %f",
305
306
307
308
event.dgesture.gestureId,
event.dgesture.error);
break;
case SDL_DOLLARRECORD:
309
SDL_Log("Recorded gesture: %"PRIs64"",event.dgesture.gestureId);
310
311
312
313
314
315
316
317
break;
}
}
DrawScreen(screen);
}
SDL_Quit();
return 0;
}