SDL  2.0
testgesture.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997-2018 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 
29 /* MUST BE A POWER OF 2! */
30 #define EVENT_BUF_SIZE 256
31 
32 
33 #define VERBOSE 0
34 
36 static int eventWrite;
37 
38 
39 static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
40 
44 
45 typedef struct {
46  float x,y;
47 } Point;
48 
49 typedef struct {
50  float ang,r;
52 } Knob;
53 
54 static Knob knob;
55 
56 void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
57 {
58  Uint32 *pixmem32;
59  Uint32 colour;
60  Uint8 r,g,b;
61  int x = (int)_x;
62  int y = (int)_y;
63  float a;
64 
65  if(x < 0 || x >= screen->w) return;
66  if(y < 0 || y >= screen->h) return;
67 
68  pixmem32 = (Uint32*) screen->pixels + y*screen->pitch/BPP + x;
69 
70  SDL_memcpy(&colour,pixmem32,screen->format->BytesPerPixel);
71 
72  SDL_GetRGB(colour,screen->format,&r,&g,&b);
73  /* r = 0;g = 0; b = 0; */
74  a = (float)((col>>24)&0xFF);
75  if(a == 0) a = 0xFF; /* Hack, to make things easier. */
76  a /= 0xFF;
77  r = (Uint8)(r*(1-a) + ((col>>16)&0xFF)*(a));
78  g = (Uint8)(g*(1-a) + ((col>> 8)&0xFF)*(a));
79  b = (Uint8)(b*(1-a) + ((col>> 0)&0xFF)*(a));
80  colour = SDL_MapRGB( screen->format,r, g, b);
81 
82 
83  *pixmem32 = colour;
84 }
85 
86 void drawLine(SDL_Surface *screen,float x0,float y0,float x1,float y1,unsigned int col) {
87  float t;
88  for(t=0;t<1;t+=(float)(1.f/SDL_max(SDL_fabs(x0-x1),SDL_fabs(y0-y1))))
89  setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
90 }
91 
92 void drawCircle(SDL_Surface* screen,float x,float y,float r,unsigned int c)
93 {
94  float tx,ty;
95  float xr;
96  for(ty = (float)-SDL_fabs(r);ty <= (float)SDL_fabs((int)r);ty++) {
97  xr = (float)SDL_sqrt(r*r - ty*ty);
98  if(r > 0) { /* r > 0 ==> filled circle */
99  for(tx=-xr+.5f;tx<=xr-.5;tx++) {
100  setpix(screen,x+tx,y+ty,c);
101  }
102  }
103  else {
104  setpix(screen,x-xr+.5f,y+ty,c);
105  setpix(screen,x+xr-.5f,y+ty,c);
106  }
107  }
108 }
109 
110 void drawKnob(SDL_Surface* screen,Knob k) {
111  drawCircle(screen,k.p.x*screen->w,k.p.y*screen->h,k.r*screen->w,0xFFFFFF);
112  drawCircle(screen,(k.p.x+k.r/2*SDL_cosf(k.ang))*screen->w,
113  (k.p.y+k.r/2*SDL_sinf(k.ang))*screen->h,k.r/4*screen->w,0);
114 }
115 
116 void DrawScreen(SDL_Surface* screen, SDL_Window* window)
117 {
118  int i;
119 #if 1
120  SDL_FillRect(screen, NULL, 0);
121 #else
122  int x, y;
123  for(y = 0;y < screen->h;y++)
124  for(x = 0;x < screen->w;x++)
125  setpix(screen,(float)x,(float)y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
126 #endif
127 
128  /* draw Touch History */
129  for(i = eventWrite; i < eventWrite+EVENT_BUF_SIZE; ++i) {
130  const SDL_Event *event = &events[i&(EVENT_BUF_SIZE-1)];
131  float age = (float)(i - eventWrite) / EVENT_BUF_SIZE;
132  float x, y;
133  unsigned int c, col;
134 
135  if(event->type == SDL_FINGERMOTION ||
136  event->type == SDL_FINGERDOWN ||
137  event->type == SDL_FINGERUP) {
138  x = event->tfinger.x;
139  y = event->tfinger.y;
140 
141  /* draw the touch: */
142  c = colors[event->tfinger.fingerId%7];
143  col = ((unsigned int)(c*(.1+.85))) | (unsigned int)(0xFF*age)<<24;
144 
145  if(event->type == SDL_FINGERMOTION)
146  drawCircle(screen,x*screen->w,y*screen->h,5,col);
147  else if(event->type == SDL_FINGERDOWN)
148  drawCircle(screen,x*screen->w,y*screen->h,-10,col);
149  }
150  }
151 
152  if(knob.p.x > 0)
153  drawKnob(screen,knob);
154 
155  SDL_UpdateWindowSurface(window);
156 }
157 
158 /* Returns a new SDL_Window if window is NULL or window if not. */
160 {
161  if (!window) {
162  window = SDL_CreateWindow("Gesture Test",
164  width, height, SDL_WINDOW_RESIZABLE);
165  }
166  return window;
167 }
168 
169 void loop()
170 {
172  SDL_RWops *stream;
173 
174  while(SDL_PollEvent(&event))
175  {
176  /* Record _all_ events */
177  events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
178  eventWrite++;
179 
180  switch (event.type)
181  {
182  case SDL_QUIT:
183  quitting = SDL_TRUE;
184  break;
185  case SDL_KEYDOWN:
186  switch (event.key.keysym.sym)
187  {
188  case SDLK_i:
189  {
190  int i;
191  for (i = 0; i < SDL_GetNumTouchDevices(); ++i) {
193  SDL_Log("Fingers Down on device %"SDL_PRIs64": %d", id, SDL_GetNumTouchFingers(id));
194  }
195  break;
196  }
197  case SDLK_SPACE:
198  SDL_RecordGesture(-1);
199  break;
200  case SDLK_s:
201  stream = SDL_RWFromFile("gestureSave", "w");
202  SDL_Log("Wrote %i templates", SDL_SaveAllDollarTemplates(stream));
203  SDL_RWclose(stream);
204  break;
205  case SDLK_l:
206  stream = SDL_RWFromFile("gestureSave", "r");
207  SDL_Log("Loaded: %i", SDL_LoadDollarTemplates(-1, stream));
208  SDL_RWclose(stream);
209  break;
210  case SDLK_ESCAPE:
211  quitting = SDL_TRUE;
212  break;
213  }
214  break;
215  case SDL_WINDOWEVENT:
216  if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
217  if (!(window = initWindow(window, event.window.data1, event.window.data2)) ||
218  !(screen = SDL_GetWindowSurface(window)))
219  {
220  SDL_Quit();
221  exit(1);
222  }
223  }
224  break;
225  case SDL_FINGERMOTION:
226 #if VERBOSE
227  SDL_Log("Finger: %"SDL_PRIs64",x: %f, y: %f",event.tfinger.fingerId,
228  event.tfinger.x,event.tfinger.y);
229 #endif
230  break;
231  case SDL_FINGERDOWN:
232 #if VERBOSE
233  SDL_Log("Finger: %"SDL_PRIs64" down - x: %f, y: %f",
234  event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
235 #endif
236  break;
237  case SDL_FINGERUP:
238 #if VERBOSE
239  SDL_Log("Finger: %"SDL_PRIs64" up - x: %f, y: %f",
240  event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
241 #endif
242  break;
243  case SDL_MULTIGESTURE:
244 #if VERBOSE
245  SDL_Log("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f",
246  event.mgesture.x,
247  event.mgesture.y,
248  event.mgesture.dTheta,
249  event.mgesture.dDist);
250  SDL_Log("MG: numDownTouch = %i",event.mgesture.numFingers);
251 #endif
252  knob.p.x = event.mgesture.x;
253  knob.p.y = event.mgesture.y;
254  knob.ang += event.mgesture.dTheta;
255  knob.r += event.mgesture.dDist;
256  break;
257  case SDL_DOLLARGESTURE:
258  SDL_Log("Gesture %"SDL_PRIs64" performed, error: %f",
259  event.dgesture.gestureId,
260  event.dgesture.error);
261  break;
262  case SDL_DOLLARRECORD:
263  SDL_Log("Recorded gesture: %"SDL_PRIs64"",event.dgesture.gestureId);
264  break;
265  }
266  }
267  DrawScreen(screen, window);
268 
269 #ifdef __EMSCRIPTEN__
270  if (quitting) {
271  emscripten_cancel_main_loop();
272  }
273 #endif
274 }
275 
276 int main(int argc, char* argv[])
277 {
278  window = NULL;
279  screen = NULL;
281 
282  /* Enable standard application logging */
284 
285  /* gesture variables */
286  knob.r = .1f;
287  knob.ang = 0;
288 
289  if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
290 
291  if (!(window = initWindow(window, WIDTH, HEIGHT)) ||
292  !(screen = SDL_GetWindowSurface(window)))
293  {
294  SDL_Quit();
295  return 1;
296  }
297 
298 #ifdef __EMSCRIPTEN__
299  emscripten_set_main_loop(loop, 0, 1);
300 #else
301  while(!quitting) {
302  loop();
303  }
304 #endif
305 
306  SDL_Quit();
307  return 0;
308 }
309 
#define SDL_GetRGB
SDL_Window * initWindow(SDL_Window *window, int width, int height)
Definition: testgesture.c:159
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
#define SDL_WINDOWPOS_CENTERED
Definition: SDL_video.h:139
#define SDL_PollEvent
GLuint GLfloat GLfloat GLfloat x1
#define SDL_sinf
SDL_DollarGestureEvent dgesture
Definition: SDL_events.h:550
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
#define SDL_RecordGesture
SDL_Surface * screen
Definition: testgesture.c:41
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
#define SDL_fabs
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:35
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
SDL_bool quitting
Definition: testgesture.c:43
int main(int argc, char *argv[])
Definition: testgesture.c:276
static Knob knob
Definition: testgesture.c:54
void drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
Definition: testgesture.c:92
GLfloat f
#define SDL_CreateWindow
#define SDL_GetNumTouchDevices
uint32_t Uint32
Definition: SDL_stdinc.h:181
SDL_GestureID gestureId
Definition: SDL_events.h:452
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
GLint GLint GLsizei width
Definition: SDL_opengl.h:1572
float r
Definition: testgesture.c:50
GLfixed y1
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:205
static int eventWrite
Definition: testgesture.c:36
GLuint GLuint stream
void * pixels
Definition: SDL_surface.h:75
void loop()
Definition: testgesture.c:169
uint8_t Uint8
Definition: SDL_stdinc.h:157
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:86
#define SDL_SaveAllDollarTemplates
const GLubyte * c
#define SDL_GetWindowSurface
SDL_Window * window
Definition: testgesture.c:42
#define EVENT_BUF_SIZE
Definition: testgesture.c:30
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
#define WIDTH
Definition: testgesture.c:25
float x
Definition: testgesture.c:46
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
#define SDL_GetNumTouchFingers
Point p
Definition: testgesture.c:51
SDL_Keysym keysym
Definition: SDL_events.h:199
void drawKnob(SDL_Surface *screen, Knob k)
Definition: testgesture.c:110
void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
Definition: testgesture.c:56
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:164
SDL_bool
Definition: SDL_stdinc.h:139
SDL_PixelFormat * format
Definition: SDL_surface.h:72
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
#define SDL_LoadDollarTemplates
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1572
#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:73
#define SDL_FillRect
#define SDL_MapRGB
float y
Definition: testgesture.c:46
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:213
#define SDL_Init
General event structure.
Definition: SDL_events.h:525
float ang
Definition: testgesture.c:50
static int colors[7]
Definition: testgesture.c:39
GLboolean GLboolean GLboolean GLboolean a
void DrawScreen(SDL_Surface *screen, SDL_Window *window)
Definition: testgesture.c:116
GLboolean GLboolean g
GLboolean GLboolean GLboolean b
#define SDL_INIT_VIDEO
Definition: SDL.h:78
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
Uint32 type
Definition: SDL_events.h:527
GLbyte ty
SDL_TouchFingerEvent tfinger
Definition: SDL_events.h:548