SDL  2.0
testgesture.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
3 
4  This software is provided 'as-is', without any express or implied
5  warranty. In no event will the authors be held liable for any damages
6  arising from the use of this software.
7 
8  Permission is granted to anyone to use this software for any purpose,
9  including commercial applications, and to alter it and redistribute it
10  freely.
11 */
12 /* Usage:
13  * Spacebar to begin recording a gesture on all touches.
14  * s to save all touches into "./gestureSave"
15  * l to load all touches from "./gestureSave"
16  */
17 
18 #include "SDL.h"
19 #include <stdlib.h> /* for exit() */
20 
21 #ifdef __EMSCRIPTEN__
22 #include <emscripten/emscripten.h>
23 #endif
24 
25 #define WIDTH 640
26 #define HEIGHT 480
27 #define BPP 4
28 #define DEPTH 32
29 
30 /* MUST BE A POWER OF 2! */
31 #define EVENT_BUF_SIZE 256
32 
33 
34 #define VERBOSE 0
35 
37 static int eventWrite;
38 
39 
40 static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
41 
45 
46 typedef struct {
47  float x,y;
48 } Point;
49 
50 typedef struct {
51  float ang,r;
53 } Knob;
54 
55 static Knob knob;
56 
57 void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
58 {
59  Uint32 *pixmem32;
60  Uint32 colour;
61  Uint8 r,g,b;
62  int x = (int)_x;
63  int y = (int)_y;
64  float a;
65 
66  if(x < 0 || x >= screen->w) return;
67  if(y < 0 || y >= screen->h) return;
68 
69  pixmem32 = (Uint32*) screen->pixels + y*screen->pitch/BPP + x;
70 
71  SDL_memcpy(&colour,pixmem32,screen->format->BytesPerPixel);
72 
73  SDL_GetRGB(colour,screen->format,&r,&g,&b);
74  /* r = 0;g = 0; b = 0; */
75  a = (float)((col>>24)&0xFF);
76  if(a == 0) a = 0xFF; /* Hack, to make things easier. */
77  a /= 0xFF;
78  r = (Uint8)(r*(1-a) + ((col>>16)&0xFF)*(a));
79  g = (Uint8)(g*(1-a) + ((col>> 8)&0xFF)*(a));
80  b = (Uint8)(b*(1-a) + ((col>> 0)&0xFF)*(a));
81  colour = SDL_MapRGB( screen->format,r, g, b);
82 
83 
84  *pixmem32 = colour;
85 }
86 
87 void drawLine(SDL_Surface *screen,float x0,float y0,float x1,float y1,unsigned int col) {
88  float t;
89  for(t=0;t<1;t+=(float)(1.f/SDL_max(SDL_fabs(x0-x1),SDL_fabs(y0-y1))))
90  setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
91 }
92 
93 void drawCircle(SDL_Surface* screen,float x,float y,float r,unsigned int c)
94 {
95  float tx,ty;
96  float xr;
97  for(ty = (float)-SDL_fabs(r);ty <= (float)SDL_fabs((int)r);ty++) {
98  xr = (float)SDL_sqrt(r*r - ty*ty);
99  if(r > 0) { /* r > 0 ==> filled circle */
100  for(tx=-xr+.5f;tx<=xr-.5;tx++) {
101  setpix(screen,x+tx,y+ty,c);
102  }
103  }
104  else {
105  setpix(screen,x-xr+.5f,y+ty,c);
106  setpix(screen,x+xr-.5f,y+ty,c);
107  }
108  }
109 }
110 
111 void drawKnob(SDL_Surface* screen,Knob k) {
112  drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF);
113  drawCircle(screen,(k.p.x+k.r/2*SDL_cosf(k.ang))*screen->w,
114  (k.p.y+k.r/2*SDL_sinf(k.ang))*screen->h,k.r/4*screen->w,0);
115 }
116 
117 void DrawScreen(SDL_Surface* screen, SDL_Window* window)
118 {
119  int i;
120 #if 1
121  SDL_FillRect(screen, NULL, 0);
122 #else
123  int x, y;
124  for(y = 0;y < screen->h;y++)
125  for(x = 0;x < screen->w;x++)
126  setpix(screen,(float)x,(float)y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
127 #endif
128 
129  /* draw Touch History */
130  for(i = eventWrite; i < eventWrite+EVENT_BUF_SIZE; ++i) {
131  const SDL_Event *event = &events[i&(EVENT_BUF_SIZE-1)];
132  float age = (float)(i - eventWrite) / EVENT_BUF_SIZE;
133  float x, y;
134  unsigned int c, col;
135 
136  if(event->type == SDL_FINGERMOTION ||
137  event->type == SDL_FINGERDOWN ||
138  event->type == SDL_FINGERUP) {
139  x = event->tfinger.x;
140  y = event->tfinger.y;
141 
142  /* draw the touch: */
143  c = colors[event->tfinger.fingerId%7];
144  col = ((unsigned int)(c*(.1+.85))) | (unsigned int)(0xFF*age)<<24;
145 
146  if(event->type == SDL_FINGERMOTION)
147  drawCircle(screen,x*screen->w,y*screen->h,5,col);
148  else if(event->type == SDL_FINGERDOWN)
149  drawCircle(screen,x*screen->w,y*screen->h,-10,col);
150  }
151  }
152 
153  if(knob.p.x > 0)
154  drawKnob(screen,knob);
155 
156  SDL_UpdateWindowSurface(window);
157 }
158 
159 /* Returns a new SDL_Window if window is NULL or window if not. */
161 {
162  if (!window) {
163  window = SDL_CreateWindow("Gesture Test",
165  width, height, SDL_WINDOW_RESIZABLE);
166  }
167  return window;
168 }
169 
170 void loop()
171 {
173  SDL_RWops *stream;
174 
175  while(SDL_PollEvent(&event))
176  {
177  /* Record _all_ events */
178  events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
179  eventWrite++;
180 
181  switch (event.type)
182  {
183  case SDL_QUIT:
184  quitting = SDL_TRUE;
185  break;
186  case SDL_KEYDOWN:
187  switch (event.key.keysym.sym)
188  {
189  case SDLK_i:
190  {
191  int i;
192  for (i = 0; i < SDL_GetNumTouchDevices(); ++i) {
194  SDL_Log("Fingers Down on device %"SDL_PRIs64": %d", id, SDL_GetNumTouchFingers(id));
195  }
196  break;
197  }
198  case SDLK_SPACE:
199  SDL_RecordGesture(-1);
200  break;
201  case SDLK_s:
202  stream = SDL_RWFromFile("gestureSave", "w");
203  SDL_Log("Wrote %i templates", SDL_SaveAllDollarTemplates(stream));
204  SDL_RWclose(stream);
205  break;
206  case SDLK_l:
207  stream = SDL_RWFromFile("gestureSave", "r");
208  SDL_Log("Loaded: %i", SDL_LoadDollarTemplates(-1, stream));
209  SDL_RWclose(stream);
210  break;
211  case SDLK_ESCAPE:
212  quitting = SDL_TRUE;
213  break;
214  }
215  break;
216  case SDL_WINDOWEVENT:
217  if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
218  if (!(window = initWindow(window, event.window.data1, event.window.data2)) ||
219  !(screen = SDL_GetWindowSurface(window)))
220  {
221  SDL_Quit();
222  exit(1);
223  }
224  }
225  break;
226  case SDL_FINGERMOTION:
227 #if VERBOSE
228  SDL_Log("Finger: %"SDL_PRIs64",x: %f, y: %f",event.tfinger.fingerId,
229  event.tfinger.x,event.tfinger.y);
230 #endif
231  break;
232  case SDL_FINGERDOWN:
233 #if VERBOSE
234  SDL_Log("Finger: %"SDL_PRIs64" down - x: %f, y: %f",
235  event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
236 #endif
237  break;
238  case SDL_FINGERUP:
239 #if VERBOSE
240  SDL_Log("Finger: %"SDL_PRIs64" up - x: %f, y: %f",
241  event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
242 #endif
243  break;
244  case SDL_MULTIGESTURE:
245 #if VERBOSE
246  SDL_Log("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f",
247  event.mgesture.x,
248  event.mgesture.y,
249  event.mgesture.dTheta,
250  event.mgesture.dDist);
251  SDL_Log("MG: numDownTouch = %i",event.mgesture.numFingers);
252 #endif
253  knob.p.x = event.mgesture.x;
254  knob.p.y = event.mgesture.y;
255  knob.ang += event.mgesture.dTheta;
256  knob.r += event.mgesture.dDist;
257  break;
258  case SDL_DOLLARGESTURE:
259  SDL_Log("Gesture %"SDL_PRIs64" performed, error: %f",
260  event.dgesture.gestureId,
261  event.dgesture.error);
262  break;
263  case SDL_DOLLARRECORD:
264  SDL_Log("Recorded gesture: %"SDL_PRIs64"",event.dgesture.gestureId);
265  break;
266  }
267  }
268  DrawScreen(screen, window);
269 
270 #ifdef __EMSCRIPTEN__
271  if (quitting) {
272  emscripten_cancel_main_loop();
273  }
274 #endif
275 }
276 
277 int main(int argc, char* argv[])
278 {
279  window = NULL;
280  screen = NULL;
282 
283  /* Enable standard application logging */
285 
286  /* gesture variables */
287  knob.r = .1f;
288  knob.ang = 0;
289 
290  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
291 
292  if (!(window = initWindow(window, WIDTH, HEIGHT)) ||
293  !(screen = SDL_GetWindowSurface(window)))
294  {
295  SDL_Quit();
296  return 1;
297  }
298 
299 #ifdef __EMSCRIPTEN__
300  emscripten_set_main_loop(loop, 0, 1);
301 #else
302  while(!quitting) {
303  loop();
304  }
305 #endif
306 
307  SDL_Quit();
308  return 0;
309 }
310 
#define SDL_GetRGB
SDL_Window * initWindow(SDL_Window *window, int width, int height)
Definition: testgesture.c:160
#define SDL_WINDOWPOS_CENTERED
Definition: SDL_video.h:136
#define SDL_PollEvent
GLuint GLfloat GLfloat GLfloat x1
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
#define SDL_sinf
SDL_DollarGestureEvent dgesture
Definition: SDL_events.h:550
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
GLuint GLuint stream
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
#define SDL_RecordGesture
SDL_Surface * screen
Definition: testgesture.c:42
Uint8 BytesPerPixel
Definition: SDL_pixels.h:318
#define SDL_fabs
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:36
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
SDL_bool quitting
Definition: testgesture.c:44
int main(int argc, char *argv[])
Definition: testgesture.c:277
static Knob knob
Definition: testgesture.c:55
void drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
Definition: testgesture.c:93
GLfloat f
#define SDL_CreateWindow
#define SDL_GetNumTouchDevices
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:161
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
SDL_GestureID gestureId
Definition: SDL_events.h:452
#define SDL_max(x, y)
Definition: SDL_stdinc.h:352
float r
Definition: testgesture.c:51
GLfixed y1
GLboolean GLboolean g
SDL_WindowEvent window
Definition: SDL_events.h:529
#define SDL_UpdateWindowSurface
#define SDL_GetTouchDevice
#define BPP
Definition: testgesture.c:27
#define SDL_Log
#define SDL_RWFromFile
#define SDL_memcpy
#define SDL_PRIs64
Definition: SDL_stdinc.h:181
static int eventWrite
Definition: testgesture.c:37
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
void * pixels
Definition: SDL_surface.h:75
void loop()
Definition: testgesture.c:170
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:143
SDL_MultiGestureEvent mgesture
Definition: SDL_events.h:549
struct _cl_event * event
#define SDL_Quit
void drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col)
Definition: testgesture.c:87
#define SDL_SaveAllDollarTemplates
const GLubyte * c
#define SDL_GetWindowSurface
SDL_Window * window
Definition: testgesture.c:43
#define EVENT_BUF_SIZE
Definition: testgesture.c:31
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
#define WIDTH
Definition: testgesture.c:25
float x
Definition: testgesture.c:47
#define SDL_GetNumTouchFingers
Point p
Definition: testgesture.c:52
SDL_Keysym keysym
Definition: SDL_events.h:199
void drawKnob(SDL_Surface *screen, Knob k)
Definition: testgesture.c:111
void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
Definition: testgesture.c:57
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define SDL_cosf
#define SDL_LogSetPriority
GLuint GLfloat GLfloat y0
#define NULL
Definition: begin_code.h:143
SDL_bool
Definition: SDL_stdinc.h:130
SDL_PixelFormat * format
Definition: SDL_surface.h:72
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
#define SDL_LoadDollarTemplates
#define HEIGHT
Definition: testgesture.c:26
SDL_KeyboardEvent key
Definition: SDL_events.h:530
The type used to identify a window.
Definition: SDL_sysvideo.h:71
#define SDL_FillRect
#define SDL_MapRGB
float y
Definition: testgesture.c:47
SDL_FingerID fingerId
Definition: SDL_events.h:418
SDL_Keycode sym
Definition: SDL_keyboard.h:50
#define SDL_sqrt
GLuint GLfloat x0
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int int return Display Window Cursor return Display Window return Display Drawable GC int int unsigned int unsigned int return Display Drawable GC int int _Xconst char int return Display Drawable GC int int unsigned int unsigned int return Display return Display Cursor return Display GC return XModifierKeymap return char Display Window int return Display return Display Atom return Display Window XWindowAttributes return Display Window return Display XEvent Bool(*) XPointer return Display Window Bool unsigned int int int Window Cursor Time return Display Window int return KeySym return Display _Xconst char Bool return Display _Xconst char return XKeyEvent char int KeySym XComposeStatus return Display int int int XVisualInfo return Display Window int int return _Xconst char return Display XEvent return Display Drawable GC XImage int int int int unsigned int unsigned int return Display Window Window Window int int int int unsigned int return Display Window Window int int return Display Window unsigned int unsigned int return Display Window Bool long XEvent return Display GC unsigned long return Display Window int Time return Display Window Window return Display Window unsigned long return Display Window XSizeHints Display Colormap XColor int return char int XTextProperty return XFontStruct _Xconst char int int int int XCharStruct return Display Window return Display Time return Display Colormap return Display Window Window int int unsigned int unsigned int int int return Display Window int return XExtensionInfo Display char XExtensionHooks int XPointer return XExtensionInfo XExtensionInfo Display return Display return Display unsigned long Display GC Display char long Display xReply int Bool return Display Bool return Display int SDL_X11_XESetEventToWireRetType return Display Window Window Window Window unsigned int return Display XShmSegmentInfo return Display Drawable GC XImage int int int int unsigned int unsigned int Boo k)
Definition: SDL_x11sym.h:211
#define SDL_Init
General event structure.
Definition: SDL_events.h:525
float ang
Definition: testgesture.c:51
static int colors[7]
Definition: testgesture.c:40
GLboolean GLboolean GLboolean GLboolean a
void DrawScreen(SDL_Surface *screen, SDL_Window *window)
Definition: testgesture.c:117
GLboolean GLboolean GLboolean b
#define SDL_INIT_VIDEO
Definition: SDL.h:77
GLdouble GLdouble t
Definition: SDL_opengl.h:2064
Uint32 type
Definition: SDL_events.h:527
GLbyte ty
SDL_TouchFingerEvent tfinger
Definition: SDL_events.h:548