testgesture.c
Go to the documentation of this file.
/*
Copyright (C) 1997-2019 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
/* Usage:
* Spacebar to begin recording a gesture on all touches.
* s to save all touches into "./gestureSave"
* l to load all touches from "./gestureSave"
*/
#include "SDL.h"
#include <stdlib.h> /* for exit() */
#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif
#include "SDL_test.h"
#include "SDL_test_common.h"
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
/* MUST BE A POWER OF 2! */
#define EVENT_BUF_SIZE 256
#define VERBOSE 0
static SDLTest_CommonState *state;
static SDL_Event events[EVENT_BUF_SIZE];
static int eventWrite;
static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
static int quitting = 0;
typedef struct
{
float x, y;
} Point;
typedef struct
{
float ang, r;
Point p;
} Knob;
static Knob knob = { 0.0f, 0.1f, { 0.0f, 0.0f } };
static void
setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
{
Uint32 *pixmem32;
Uint32 colour;
Uint8 r, g, b;
const int x = (int)_x;
const int y = (int)_y;
float a;
if ( (x < 0) || (x >= screen->w) || (y < 0) || (y >= screen->h) ) {
return;
}
pixmem32 = (Uint32 *) screen->pixels + y * screen->pitch / BPP + x;
SDL_memcpy(&colour, pixmem32, screen->format->BytesPerPixel);
SDL_GetRGB(colour,screen->format,&r,&g,&b);
/* r = 0;g = 0; b = 0; */
a = (float) ((col >> 24) & 0xFF);
if (a == 0) {
a = 0xFF; /* Hack, to make things easier. */
}
a = (a == 0.0f) ? 1 : (a / 255.0f);
r = (Uint8) (r * (1 - a) + ((col >> 16) & 0xFF) * a);
g = (Uint8) (g * (1 - a) + ((col >> 8) & 0xFF) * a);
b = (Uint8) (b * (1 - a) + ((col >> 0) & 0xFF) * a);
colour = SDL_MapRGB(screen->format, r, g, b);
*pixmem32 = colour;
}
static void
drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col)
{
float t;
for (t = 0; t < 1; t += (float) (1.0f / SDL_max(SDL_fabs(x0 - x1), SDL_fabs(y0 - y1)))) {
setpix(screen, x1 + t * (x0 - x1), y1 + t * (y0 - y1), col);
}
}
static void
drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
{
float tx,ty, xr;
for (ty = (float) -SDL_fabs(r); ty <= (float) SDL_fabs((int) r); ty++) {
xr = (float) SDL_sqrt(r * r - ty * ty);
if (r > 0) { /* r > 0 ==> filled circle */
for(tx = -xr + 0.5f; tx <= xr - 0.5f; tx++) {
setpix(screen, x + tx, y + ty, c);
}
} else {
setpix(screen, x - xr + 0.5f, y + ty, c);
setpix(screen, x + xr - 0.5f, y + ty, c);
}
}
}
static void
drawKnob(SDL_Surface *screen, const Knob *k)
{
drawCircle(screen, k->p.x * screen->w, k->p.y * screen->h, k->r * screen->w, 0xFFFFFF);
drawCircle(screen, (k->p.x + k->r / 2 * SDL_cosf(k->ang)) * screen->w,
(k->p.y + k->r / 2 * SDL_sinf(k->ang)) * screen->h, k->r / 4 * screen->w, 0);
}
static void
DrawScreen(SDL_Window *window)
{
SDL_Surface *screen = SDL_GetWindowSurface(window);
int i;
if (!screen) {
return;
}
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 75, 75, 75));
/* draw Touch History */
for (i = eventWrite; i < eventWrite + EVENT_BUF_SIZE; ++i) {
const SDL_Event *event = &events[i & (EVENT_BUF_SIZE - 1)];
const float age = (float)(i - eventWrite) / EVENT_BUF_SIZE;
float x, y;
unsigned int c, col;
if ( (event->type == SDL_FINGERMOTION) ||
(event->type == SDL_FINGERDOWN) ||
(event->type == SDL_FINGERUP) ) {
x = event->tfinger.x;
y = event->tfinger.y;
/* draw the touch: */
c = colors[event->tfinger.fingerId % 7];
col = ((unsigned int) (c * (0.1f + 0.85f))) | (unsigned int) (0xFF * age) << 24;
if (event->type == SDL_FINGERMOTION) {
drawCircle(screen, x * screen->w, y * screen->h, 5, col);
} else if (event->type == SDL_FINGERDOWN) {
drawCircle(screen, x * screen->w, y * screen->h, -10, col);
}
}
}
if (knob.p.x > 0) {
drawKnob(screen, &knob);
}
SDL_UpdateWindowSurface(window);
}
static void
loop(void)
{
SDL_Event event;
SDL_RWops *stream;
int i;
while (SDL_PollEvent(&event)) {
SDLTest_CommonEvent(state, &event, &quitting);
/* Record _all_ events */
events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
eventWrite++;
switch (event.type) {
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case SDLK_i: {
for (i = 0; i < SDL_GetNumTouchDevices(); ++i) {
const SDL_TouchID id = SDL_GetTouchDevice(i);
SDL_Log("Fingers Down on device %"SDL_PRIs64": %d", id, SDL_GetNumTouchFingers(id));
}
break;
}
case SDLK_SPACE:
SDL_RecordGesture(-1);
break;
case SDLK_s:
stream = SDL_RWFromFile("gestureSave", "w");
SDL_Log("Wrote %i templates", SDL_SaveAllDollarTemplates(stream));
SDL_RWclose(stream);
break;
case SDLK_l:
stream = SDL_RWFromFile("gestureSave", "r");
SDL_Log("Loaded: %i", SDL_LoadDollarTemplates(-1, stream));
SDL_RWclose(stream);
break;
}
break;
#if VERBOSE
case SDL_FINGERMOTION:
SDL_Log("Finger: %"SDL_PRIs64",x: %f, y: %f",event.tfinger.fingerId,
event.tfinger.x,event.tfinger.y);
break;
case SDL_FINGERDOWN:
SDL_Log("Finger: %"SDL_PRIs64" down - x: %f, y: %f",
event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
break;
case SDL_FINGERUP:
SDL_Log("Finger: %"SDL_PRIs64" up - x: %f, y: %f",
event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
break;
#endif
case SDL_MULTIGESTURE:
#if VERBOSE
SDL_Log("Multi Gesture: x = %f, y = %f, dAng = %f, dR = %f",
event.mgesture.x, event.mgesture.y,
event.mgesture.dTheta, event.mgesture.dDist);
SDL_Log("MG: numDownTouch = %i",event.mgesture.numFingers);
#endif
knob.p.x = event.mgesture.x;
knob.p.y = event.mgesture.y;
knob.ang += event.mgesture.dTheta;
knob.r += event.mgesture.dDist;
break;
case SDL_DOLLARGESTURE:
SDL_Log("Gesture %"SDL_PRIs64" performed, error: %f",
event.dgesture.gestureId, event.dgesture.error);
break;
case SDL_DOLLARRECORD:
SDL_Log("Recorded gesture: %"SDL_PRIs64"",event.dgesture.gestureId);
break;
}
}
for (i = 0; i < state->num_windows; ++i) {
if (state->windows[i]) {
DrawScreen(state->windows[i]);
}
}
#ifdef __EMSCRIPTEN__
if (quitting) {
emscripten_cancel_main_loop();
}
#endif
}
int main(int argc, char* argv[])
{
state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
if (!state) {
return 1;
}
state->window_title = "Gesture Test";
state->window_w = WIDTH;
state->window_h = HEIGHT;
state->skip_renderer = SDL_TRUE;
if (!SDLTest_CommonDefaultArgs(state, argc, argv) || !SDLTest_CommonInit(state)) {
SDLTest_CommonQuit(state);
return 1;
}
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(loop, 0, 1);
#else
while (!quitting) {
loop();
}
#endif
SDLTest_CommonQuit(state);
return 0;
}
SDL.h
EVENT_BUF_SIZE
#define EVENT_BUF_SIZE
Definition: testgesture.c:34
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
SDLTest_CommonState::windows
SDL_Window ** windows
Definition: SDL_test_common.h:78
Knob::p
Point p
Definition: testgesture.c:52
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_sinf
#define SDL_sinf
Definition: SDL_dynapi_overrides.h:436
screen
SDL_Renderer * screen
Definition: testgamecontroller.c:64
knob
static Knob knob
Definition: testgesture.c:55
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:70
SDL_PollEvent
#define SDL_PollEvent
Definition: SDL_dynapi_overrides.h:122
SDL_test.h
SDL_fabs
#define SDL_fabs
Definition: SDL_dynapi_overrides.h:430
main
int main(int argc, char *argv[])
Definition: testgesture.c:269
NULL
#define NULL
Definition: begin_code.h:167
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1109
SDLTest_CommonState
Definition: SDL_test_common.h:51
SDL_DOLLARRECORD
@ SDL_DOLLARRECORD
Definition: SDL_events.h:134
drawCircle
static void drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
Definition: testgesture.c:103
Point::x
float x
Definition: testgesture.c:46
SDLTest_CommonState::skip_renderer
SDL_bool skip_renderer
Definition: SDL_test_common.h:83
ty
GLbyte ty
Definition: SDL_opengl_glext.h:5972
x0
GLuint GLfloat x0
Definition: SDL_opengl_glext.h:8583
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2079
Knob::ang
float ang
Definition: testgesture.c:51
WIDTH
#define WIDTH
Definition: testgesture.c:29
SDL_RecordGesture
#define SDL_RecordGesture
Definition: SDL_dynapi_overrides.h:155
SDL_TouchID
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
stream
GLuint GLuint stream
Definition: SDL_opengl_glext.h:1776
SDL_GetNumTouchDevices
#define SDL_GetNumTouchDevices
Definition: SDL_dynapi_overrides.h:489
y0
GLuint GLfloat GLfloat y0
Definition: SDL_opengl_glext.h:8583
x1
GLuint GLfloat GLfloat GLfloat x1
Definition: SDL_opengl_glext.h:8583
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
SDL_KEYDOWN
@ SDL_KEYDOWN
Definition: SDL_events.h:96
setpix
static void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
Definition: testgesture.c:59
SDLTest_CommonCreateState
SDLTest_CommonState * SDLTest_CommonCreateState(char **argv, Uint32 flags)
Parse command line parameters and create common state.
Definition: SDL_test_common.c:59
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:73
SDL_UpdateWindowSurface
#define SDL_UpdateWindowSurface
Definition: SDL_dynapi_overrides.h:541
SDLTest_CommonQuit
void SDLTest_CommonQuit(SDLTest_CommonState *state)
Close test window.
Definition: SDL_test_common.c:1832
SDLK_l
@ SDLK_l
Definition: SDL_keycode.h:111
drawLine
static void drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col)
Definition: testgesture.c:94
SDLTest_CommonState::window_w
int window_w
Definition: SDL_test_common.h:66
SDL_FINGERUP
@ SDL_FINGERUP
Definition: SDL_events.h:129
SDLTest_CommonState::num_windows
int num_windows
Definition: SDL_test_common.h:77
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDLTest_CommonDefaultArgs
SDL_bool SDLTest_CommonDefaultArgs(SDLTest_CommonState *state, const int argc, char **argv)
Easy argument handling when test app doesn't need any custom args.
Definition: SDL_test_common.c:516
SDL_FINGERDOWN
@ SDL_FINGERDOWN
Definition: SDL_events.h:128
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1574
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_Log
#define SDL_Log
Definition: SDL_dynapi_overrides.h:31
SDL_test_common.h
SDL_GetTouchDevice
#define SDL_GetTouchDevice
Definition: SDL_dynapi_overrides.h:490
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
t
GLdouble GLdouble t
Definition: SDL_opengl.h:2071
SDL_RWFromFile
#define SDL_RWFromFile
Definition: SDL_dynapi_overrides.h:351
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
DrawScreen
static void DrawScreen(SDL_Window *window)
Definition: testgesture.c:128
SDLK_SPACE
@ SDLK_SPACE
Definition: SDL_keycode.h:58
k
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
SDL_GetNumTouchFingers
#define SDL_GetNumTouchFingers
Definition: SDL_dynapi_overrides.h:491
SDL_FINGERMOTION
@ SDL_FINGERMOTION
Definition: SDL_events.h:130
Knob
Definition: testgesture.c:49
state
static SDLTest_CommonState * state
Definition: testgesture.c:38
loop
static void loop(void)
Definition: testgesture.c:172
SDL_SaveAllDollarTemplates
#define SDL_SaveAllDollarTemplates
Definition: SDL_dynapi_overrides.h:156
eventWrite
static int eventWrite
Definition: testgesture.c:40
SDL_GetWindowSurface
#define SDL_GetWindowSurface
Definition: SDL_dynapi_overrides.h:540
quitting
static int quitting
Definition: testgesture.c:42
SDL_cosf
#define SDL_cosf
Definition: SDL_dynapi_overrides.h:429
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1574
SDL_LoadDollarTemplates
#define SDL_LoadDollarTemplates
Definition: SDL_dynapi_overrides.h:158
HEIGHT
#define HEIGHT
Definition: testgesture.c:30
SDLTest_CommonInit
SDL_bool SDLTest_CommonInit(SDLTest_CommonState *state)
Open test window.
Definition: SDL_test_common.c:764
SDLK_i
@ SDLK_i
Definition: SDL_keycode.h:108
SDL_INIT_VIDEO
#define SDL_INIT_VIDEO
Definition: SDL.h:79
SDLTest_CommonState::window_title
const char * window_title
Definition: SDL_test_common.h:61
events
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:39
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
SDL_sqrt
#define SDL_sqrt
Definition: SDL_dynapi_overrides.h:437
Point::y
float y
Definition: testgesture.c:46
SDL_MULTIGESTURE
@ SDL_MULTIGESTURE
Definition: SDL_events.h:135
drawKnob
static void drawKnob(SDL_Surface *screen, const Knob *k)
Definition: testgesture.c:120
SDL_RWclose
#define SDL_RWclose
Definition: SDL_dynapi_overrides.h:725
y1
GLfixed y1
Definition: SDL_opengl_glext.h:4583
SDLTest_CommonState::window_h
int window_h
Definition: SDL_test_common.h:67
BPP
#define BPP
Definition: testgesture.c:31
SDL_FillRect
#define SDL_FillRect
Definition: SDL_dynapi_overrides.h:466
SDL_MapRGB
#define SDL_MapRGB
Definition: SDL_dynapi_overrides.h:286
SDL_Event
General event structure.
Definition: SDL_events.h:557
Knob::r
float r
Definition: testgesture.c:51
SDLTest_CommonEvent
void SDLTest_CommonEvent(SDLTest_CommonState *state, SDL_Event *event, int *done)
Common event handler for test windows.
Definition: SDL_test_common.c:1501
Point
Definition: testgesture.c:44
SDL_PRIs64
#define SDL_PRIs64
Definition: SDL_stdinc.h:227
SDL_RWops
Definition: SDL_rwops.h:52
SDLK_s
@ SDLK_s
Definition: SDL_keycode.h:118
i
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
SDL_DOLLARGESTURE
@ SDL_DOLLARGESTURE
Definition: SDL_events.h:133
SDL_GetRGB
#define SDL_GetRGB
Definition: SDL_dynapi_overrides.h:288
colors
static int colors[7]
Definition: testgesture.c:41
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179