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:129
#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:546
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:155
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:304
#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
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
SDL_GestureID gestureId
Definition: SDL_events.h:449
#define SDL_max(x, y)
Definition: SDL_stdinc.h:346
float r
Definition: testgesture.c:51
GLfixed y1
SDL_bool
Definition: SDL_stdinc.h:126
GLboolean GLboolean g
SDL_WindowEvent window
Definition: SDL_events.h:525
#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:175
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:139
SDL_MultiGestureEvent mgesture
Definition: SDL_events.h:545
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:196
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:42
#define SDL_cosf
#define SDL_LogSetPriority
GLuint GLfloat GLfloat y0
#define NULL
Definition: begin_code.h:143
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:526
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:415
SDL_Keycode sym
Definition: SDL_keyboard.h:50
#define SDL_sqrt
GLuint GLfloat x0
#define SDL_Init
General event structure.
Definition: SDL_events.h:521
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:523
GLbyte ty
SDL_TouchFingerEvent tfinger
Definition: SDL_events.h:544