SDL  2.0
testgesture.c
Go to the documentation of this file.
1 /*
2  Copyright (C) 1997-2019 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 
13 /* Usage:
14  * Spacebar to begin recording a gesture on all touches.
15  * s to save all touches into "./gestureSave"
16  * l to load all touches from "./gestureSave"
17  */
18 
19 #include "SDL.h"
20 #include <stdlib.h> /* for exit() */
21 
22 #ifdef __EMSCRIPTEN__
23 #include <emscripten/emscripten.h>
24 #endif
25 
26 #include "SDL_test.h"
27 #include "SDL_test_common.h"
28 
29 #define WIDTH 640
30 #define HEIGHT 480
31 #define BPP 4
32 
33 /* MUST BE A POWER OF 2! */
34 #define EVENT_BUF_SIZE 256
35 
36 #define VERBOSE 0
37 
40 static int eventWrite;
41 static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
42 static int quitting = 0;
43 
44 typedef struct
45 {
46  float x, y;
47 } Point;
48 
49 typedef struct
50 {
51  float ang, r;
53 } Knob;
54 
55 static Knob knob = { 0.0f, 0.1f, { 0.0f, 0.0f } };
56 
57 
58 static void
59 setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
60 {
61  Uint32 *pixmem32;
62  Uint32 colour;
63  Uint8 r, g, b;
64  const int x = (int)_x;
65  const int y = (int)_y;
66  float a;
67 
68  if ( (x < 0) || (x >= screen->w) || (y < 0) || (y >= screen->h) ) {
69  return;
70  }
71 
72  pixmem32 = (Uint32 *) screen->pixels + y * screen->pitch / BPP + x;
73 
74  SDL_memcpy(&colour, pixmem32, screen->format->BytesPerPixel);
75 
76  SDL_GetRGB(colour,screen->format,&r,&g,&b);
77 
78  /* r = 0;g = 0; b = 0; */
79  a = (float) ((col >> 24) & 0xFF);
80  if (a == 0) {
81  a = 0xFF; /* Hack, to make things easier. */
82  }
83 
84  a = (a == 0.0f) ? 1 : (a / 255.0f);
85  r = (Uint8) (r * (1 - a) + ((col >> 16) & 0xFF) * a);
86  g = (Uint8) (g * (1 - a) + ((col >> 8) & 0xFF) * a);
87  b = (Uint8) (b * (1 - a) + ((col >> 0) & 0xFF) * a);
88  colour = SDL_MapRGB(screen->format, r, g, b);
89 
90  *pixmem32 = colour;
91 }
92 
93 static void
94 drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col)
95 {
96  float t;
97  for (t = 0; t < 1; t += (float) (1.0f / SDL_max(SDL_fabs(x0 - x1), SDL_fabs(y0 - y1)))) {
98  setpix(screen, x1 + t * (x0 - x1), y1 + t * (y0 - y1), col);
99  }
100 }
101 
102 static void
103 drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
104 {
105  float tx,ty, xr;
106  for (ty = (float) -SDL_fabs(r); ty <= (float) SDL_fabs((int) r); ty++) {
107  xr = (float) SDL_sqrt(r * r - ty * ty);
108  if (r > 0) { /* r > 0 ==> filled circle */
109  for(tx = -xr + 0.5f; tx <= xr - 0.5f; tx++) {
110  setpix(screen, x + tx, y + ty, c);
111  }
112  } else {
113  setpix(screen, x - xr + 0.5f, y + ty, c);
114  setpix(screen, x + xr - 0.5f, y + ty, c);
115  }
116  }
117 }
118 
119 static void
121 {
122  drawCircle(screen, k->p.x * screen->w, k->p.y * screen->h, k->r * screen->w, 0xFFFFFF);
123  drawCircle(screen, (k->p.x + k->r / 2 * SDL_cosf(k->ang)) * screen->w,
124  (k->p.y + k->r / 2 * SDL_sinf(k->ang)) * screen->h, k->r / 4 * screen->w, 0);
125 }
126 
127 static void
129 {
131  int i;
132 
133  if (!screen) {
134  return;
135  }
136 
137  SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 75, 75, 75));
138 
139  /* draw Touch History */
140  for (i = eventWrite; i < eventWrite + EVENT_BUF_SIZE; ++i) {
141  const SDL_Event *event = &events[i & (EVENT_BUF_SIZE - 1)];
142  const float age = (float)(i - eventWrite) / EVENT_BUF_SIZE;
143  float x, y;
144  unsigned int c, col;
145 
146  if ( (event->type == SDL_FINGERMOTION) ||
147  (event->type == SDL_FINGERDOWN) ||
148  (event->type == SDL_FINGERUP) ) {
149  x = event->tfinger.x;
150  y = event->tfinger.y;
151 
152  /* draw the touch: */
153  c = colors[event->tfinger.fingerId % 7];
154  col = ((unsigned int) (c * (0.1f + 0.85f))) | (unsigned int) (0xFF * age) << 24;
155 
156  if (event->type == SDL_FINGERMOTION) {
157  drawCircle(screen, x * screen->w, y * screen->h, 5, col);
158  } else if (event->type == SDL_FINGERDOWN) {
159  drawCircle(screen, x * screen->w, y * screen->h, -10, col);
160  }
161  }
162  }
163 
164  if (knob.p.x > 0) {
165  drawKnob(screen, &knob);
166  }
167 
168  SDL_UpdateWindowSurface(window);
169 }
170 
171 static void
172 loop(void)
173 {
175  SDL_RWops *stream;
176  int i;
177 
178  while (SDL_PollEvent(&event)) {
179  SDLTest_CommonEvent(state, &event, &quitting);
180 
181  /* Record _all_ events */
182  events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
183  eventWrite++;
184 
185  switch (event.type) {
186  case SDL_KEYDOWN:
187  switch (event.key.keysym.sym) {
188  case SDLK_i: {
189  for (i = 0; i < SDL_GetNumTouchDevices(); ++i) {
190  const SDL_TouchID id = SDL_GetTouchDevice(i);
191  SDL_Log("Fingers Down on device %"SDL_PRIs64": %d", id, SDL_GetNumTouchFingers(id));
192  }
193  break;
194  }
195 
196  case SDLK_SPACE:
197  SDL_RecordGesture(-1);
198  break;
199 
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 
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  }
212  break;
213 
214 #if VERBOSE
215  case SDL_FINGERMOTION:
216  SDL_Log("Finger: %"SDL_PRIs64",x: %f, y: %f",event.tfinger.fingerId,
217  event.tfinger.x,event.tfinger.y);
218  break;
219 
220  case SDL_FINGERDOWN:
221  SDL_Log("Finger: %"SDL_PRIs64" down - x: %f, y: %f",
222  event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
223  break;
224 
225  case SDL_FINGERUP:
226  SDL_Log("Finger: %"SDL_PRIs64" up - x: %f, y: %f",
227  event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
228  break;
229 #endif
230 
231  case SDL_MULTIGESTURE:
232 #if VERBOSE
233  SDL_Log("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f",
234  event.mgesture.x, event.mgesture.y,
235  event.mgesture.dTheta, event.mgesture.dDist);
236  SDL_Log("MG: numDownTouch = %i",event.mgesture.numFingers);
237 #endif
238 
239  knob.p.x = event.mgesture.x;
240  knob.p.y = event.mgesture.y;
241  knob.ang += event.mgesture.dTheta;
242  knob.r += event.mgesture.dDist;
243  break;
244 
245  case SDL_DOLLARGESTURE:
246  SDL_Log("Gesture %"SDL_PRIs64" performed, error: %f",
247  event.dgesture.gestureId, event.dgesture.error);
248  break;
249 
250  case SDL_DOLLARRECORD:
251  SDL_Log("Recorded gesture: %"SDL_PRIs64"",event.dgesture.gestureId);
252  break;
253  }
254  }
255 
256  for (i = 0; i < state->num_windows; ++i) {
257  if (state->windows[i]) {
258  DrawScreen(state->windows[i]);
259  }
260  }
261 
262 #ifdef __EMSCRIPTEN__
263  if (quitting) {
264  emscripten_cancel_main_loop();
265  }
266 #endif
267 }
268 
269 int main(int argc, char* argv[])
270 {
272  if (!state) {
273  return 1;
274  }
275 
276  state->window_title = "Gesture Test";
277  state->window_w = WIDTH;
278  state->window_h = HEIGHT;
279  state->skip_renderer = SDL_TRUE;
280 
281  if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) {
282  SDLTest_CommonQuit(state);
283  return 1;
284  }
285 
286 #ifdef __EMSCRIPTEN__
287  emscripten_set_main_loop(loop, 0, 1);
288 #else
289  while (!quitting) {
290  loop();
291  }
292 #endif
293 
294  SDLTest_CommonQuit(state);
295  return 0;
296 }
297 
#define SDL_GetRGB
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
#define SDL_PollEvent
GLuint GLfloat GLfloat GLfloat x1
#define SDL_sinf
SDL_DollarGestureEvent dgesture
Definition: SDL_events.h:584
SDL_bool SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **argv)
Easy argument handling when test app doesn&#39;t need any custom args.
static void drawKnob(SDL_Surface *screen, const Knob *k)
Definition: testgesture.c:120
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
#define SDL_RecordGesture
Uint8 BytesPerPixel
Definition: SDL_pixels.h:320
SDLTest_CommonState * SDLTest_CommonCreateState(char **argv, Uint32 flags)
Parse command line parameters and create common state.
#define SDL_fabs
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:39
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
int main(int argc, char *argv[])
Definition: testgesture.c:269
static Knob knob
Definition: testgesture.c:55
static int quitting
Definition: testgesture.c:42
GLfloat f
#define SDL_GetNumTouchDevices
static void drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col)
Definition: testgesture.c:94
SDL_GestureID gestureId
Definition: SDL_events.h:473
SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
Open test window.
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
static void drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
Definition: testgesture.c:103
float r
Definition: testgesture.c:51
SDL_Window ** windows
GLfixed y1
static void DrawScreen(SDL_Window *window)
Definition: testgesture.c:128
#define SDL_UpdateWindowSurface
#define SDL_GetTouchDevice
#define BPP
Definition: testgesture.c:31
#define SDL_Log
#define SDL_RWFromFile
#define SDL_memcpy
#define SDL_PRIs64
Definition: SDL_stdinc.h:227
static int eventWrite
Definition: testgesture.c:40
void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
Common event handler for test windows.
GLuint GLuint stream
void * pixels
Definition: SDL_surface.h:76
uint8_t Uint8
Definition: SDL_stdinc.h:179
SDL_MultiGestureEvent mgesture
Definition: SDL_events.h:583
struct _cl_event * event
#define SDL_SaveAllDollarTemplates
const GLubyte * c
#define SDL_GetWindowSurface
#define EVENT_BUF_SIZE
Definition: testgesture.c:34
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
#define WIDTH
Definition: testgesture.c:29
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:52
SDL_Keysym keysym
Definition: SDL_events.h:220
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
GLuint GLfloat GLfloat y0
#define NULL
Definition: begin_code.h:167
static void loop(void)
Definition: testgesture.c:172
SDL_PixelFormat * format
Definition: SDL_surface.h:73
static void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
Definition: testgesture.c:59
#define SDL_LoadDollarTemplates
#define HEIGHT
Definition: testgesture.c:30
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_KeyboardEvent key
Definition: SDL_events.h:563
The type used to identify a window.
Definition: SDL_sysvideo.h:73
uint32_t Uint32
Definition: SDL_stdinc.h:203
#define SDL_FillRect
#define SDL_MapRGB
float y
Definition: testgesture.c:46
SDL_FingerID fingerId
Definition: SDL_events.h:439
SDL_Keycode sym
Definition: SDL_keyboard.h:50
#define SDL_sqrt
GLuint GLfloat x0
#define SDL_RWclose
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
General event structure.
Definition: SDL_events.h:557
float ang
Definition: testgesture.c:51
static int colors[7]
Definition: testgesture.c:41
GLboolean GLboolean GLboolean GLboolean a
SDL_Renderer * screen
GLboolean GLboolean g
GLboolean GLboolean GLboolean b
void SDLTest_CommonQuit(SDLTest_CommonState *state)
Close test window.
#define SDL_INIT_VIDEO
Definition: SDL.h:79
static SDLTest_CommonState * state
Definition: testgesture.c:38
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
Uint32 type
Definition: SDL_events.h:559
GLbyte ty
SDL_TouchFingerEvent tfinger
Definition: SDL_events.h:582
const char * window_title