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
40static int eventWrite;
41static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
42static int quitting = 0;
43
44typedef struct
45{
46 float x, y;
47} Point;
48
49typedef struct
50{
51 float ang, r;
53} Knob;
54
55static Knob knob = { 0.0f, 0.1f, { 0.0f, 0.0f } };
56
57
58static void
59setpix(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
93static void
94drawLine(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
102static void
103drawCircle(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
119static 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
127static 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) {
166 }
167
169}
170
171static void
172loop(void)
173{
176 int i;
177
178 while (SDL_PollEvent(&event)) {
180
181 /* Record _all_ events */
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:
198 break;
199
200 case SDLK_s:
201 stream = SDL_RWFromFile("gestureSave", "w");
202 SDL_Log("Wrote %i templates", SDL_SaveAllDollarTemplates(stream));
204 break;
205
206 case SDLK_l:
207 stream = SDL_RWFromFile("gestureSave", "r");
208 SDL_Log("Loaded: %i", SDL_LoadDollarTemplates(-1, 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
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]) {
259 }
260 }
261
262#ifdef __EMSCRIPTEN__
263 if (quitting) {
264 emscripten_cancel_main_loop();
265 }
266#endif
267}
268
269int main(int argc, char* argv[])
270{
272 if (!state) {
273 return 1;
274 }
275
276 state->window_title = "Gesture Test";
280
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
295 return 0;
296}
297
#define SDL_INIT_VIDEO
Definition: SDL.h:79
#define SDL_sqrt
#define SDL_cosf
#define SDL_GetNumTouchDevices
#define SDL_PollEvent
#define SDL_GetNumTouchFingers
#define SDL_GetRGB
#define SDL_GetTouchDevice
#define SDL_LoadDollarTemplates
#define SDL_MapRGB
#define SDL_RecordGesture
#define SDL_fabs
#define SDL_UpdateWindowSurface
#define SDL_SaveAllDollarTemplates
#define SDL_RWFromFile
#define SDL_sinf
#define SDL_memcpy
#define SDL_GetWindowSurface
#define SDL_Log
#define SDL_RWclose
#define SDL_FillRect
@ SDL_FINGERMOTION
Definition: SDL_events.h:130
@ SDL_FINGERUP
Definition: SDL_events.h:129
@ SDL_DOLLARRECORD
Definition: SDL_events.h:134
@ SDL_MULTIGESTURE
Definition: SDL_events.h:135
@ SDL_FINGERDOWN
Definition: SDL_events.h:128
@ SDL_DOLLARGESTURE
Definition: SDL_events.h:133
@ SDL_KEYDOWN
Definition: SDL_events.h:96
@ SDLK_i
Definition: SDL_keycode.h:108
@ SDLK_s
Definition: SDL_keycode.h:118
@ SDLK_SPACE
Definition: SDL_keycode.h:58
@ SDLK_l
Definition: SDL_keycode.h:111
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
GLboolean GLboolean GLboolean b
GLuint GLuint stream
struct _cl_event * event
GLfixed y1
GLuint GLfloat GLfloat GLfloat x1
GLboolean GLboolean GLboolean GLboolean a
const GLubyte * c
GLuint GLfloat x0
GLboolean GLboolean g
GLbyte ty
GLuint GLfloat GLfloat y0
@ SDL_TRUE
Definition: SDL_stdinc.h:164
uint32_t Uint32
Definition: SDL_stdinc.h:203
#define SDL_PRIs64
Definition: SDL_stdinc.h:227
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
uint8_t Uint8
Definition: SDL_stdinc.h:179
void SDLTest_CommonQuit(SDLTest_CommonState *state)
Close test window.
SDL_bool SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **argv)
Easy argument handling when test app doesn't need any custom args.
SDLTest_CommonState * SDLTest_CommonCreateState(char **argv, Uint32 flags)
Parse command line parameters and create common state.
void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
Common event handler for test windows.
SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
Open test window.
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
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
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 NULL
Definition: begin_code.h:167
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
float ang
Definition: testgesture.c:51
float r
Definition: testgesture.c:51
Point p
Definition: testgesture.c:52
float x
Definition: testgesture.c:46
float y
Definition: testgesture.c:46
A collection of pixels used in software blitting.
Definition: SDL_surface.h:71
The type used to identify a window.
Definition: SDL_sysvideo.h:74
SDL_Window ** windows
const char * window_title
SDL_Renderer * screen
static void drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col)
Definition: testgesture.c:94
static int eventWrite
Definition: testgesture.c:40
int main(int argc, char *argv[])
Definition: testgesture.c:269
#define WIDTH
Definition: testgesture.c:29
#define EVENT_BUF_SIZE
Definition: testgesture.c:34
static void drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
Definition: testgesture.c:103
static void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
Definition: testgesture.c:59
#define BPP
Definition: testgesture.c:31
static int colors[7]
Definition: testgesture.c:41
static void drawKnob(SDL_Surface *screen, const Knob *k)
Definition: testgesture.c:120
static SDLTest_CommonState * state
Definition: testgesture.c:38
static void DrawScreen(SDL_Window *window)
Definition: testgesture.c:128
static Knob knob
Definition: testgesture.c:55
static int quitting
Definition: testgesture.c:42
static void loop(void)
Definition: testgesture.c:172
#define HEIGHT
Definition: testgesture.c:30
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:39
General event structure.
Definition: SDL_events.h:558