testgesture.c
Go to the documentation of this file.
/*
Copyright (C) 1997-2016 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
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
#define DEPTH 32
/* MUST BE A POWER OF 2! */
#define EVENT_BUF_SIZE 256
#define VERBOSE 0
static SDL_Event events[EVENT_BUF_SIZE];
static int eventWrite;
static int colors[7] = {0xFF,0xFF00,0xFF0000,0xFFFF00,0x00FFFF,0xFF00FF,0xFFFFFF};
SDL_Surface *screen;
SDL_Window *window;
SDL_bool quitting = SDL_FALSE;
typedef struct {
float x,y;
} Point;
typedef struct {
float ang,r;
Point p;
} Knob;
static Knob knob;
void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
{
Uint32 *pixmem32;
Uint32 colour;
Uint8 r,g,b;
int x = (int)_x;
int y = (int)_y;
float a;
if(x < 0 || x >= screen->w) return;
if(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 /= 0xFF;
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;
}
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.f/SDL_max(SDL_fabs(x0-x1),SDL_fabs(y0-y1))))
setpix(screen,x1+t*(x0-x1),y1+t*(y0-y1),col);
}
void drawCircle(SDL_Surface* screen,float x,float y,float r,unsigned int c)
{
float tx,ty;
float 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+.5f;tx<=xr-.5;tx++) {
setpix(screen,x+tx,y+ty,c);
}
}
else {
setpix(screen,x-xr+.5f,y+ty,c);
setpix(screen,x+xr-.5f,y+ty,c);
}
}
}
void drawKnob(SDL_Surface* screen,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);
}
void DrawScreen(SDL_Surface* screen, SDL_Window* window)
{
int i;
#if 1
SDL_FillRect(screen, NULL, 0);
#else
int x, y;
for(y = 0;y < screen->h;y++)
for(x = 0;x < screen->w;x++)
setpix(screen,(float)x,(float)y,((x%255)<<16) + ((y%255)<<8) + (x+y)%255);
#endif
/* draw Touch History */
for(i = eventWrite; i < eventWrite+EVENT_BUF_SIZE; ++i) {
const SDL_Event *event = &events[i&(EVENT_BUF_SIZE-1)];
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*(.1+.85))) | (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);
}
/* Returns a new SDL_Window if window is NULL or window if not. */
SDL_Window* initWindow(SDL_Window *window, int width,int height)
{
if (!window) {
window = SDL_CreateWindow("Gesture Test",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
width, height, SDL_WINDOW_RESIZABLE);
}
return window;
}
void loop()
{
SDL_Event event;
SDL_RWops *stream;
while(SDL_PollEvent(&event))
{
/* Record _all_ events */
events[eventWrite & (EVENT_BUF_SIZE-1)] = event;
eventWrite++;
switch (event.type)
{
case SDL_QUIT:
quitting = SDL_TRUE;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_i:
{
int i;
for (i = 0; i < SDL_GetNumTouchDevices(); ++i) {
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;
case SDLK_ESCAPE:
quitting = SDL_TRUE;
break;
}
break;
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
if (!(window = initWindow(window, event.window.data1, event.window.data2)) ||
!(screen = SDL_GetWindowSurface(window)))
{
SDL_Quit();
exit(1);
}
}
break;
case SDL_FINGERMOTION:
#if VERBOSE
SDL_Log("Finger: %"SDL_PRIs64",x: %f, y: %f",event.tfinger.fingerId,
event.tfinger.x,event.tfinger.y);
#endif
break;
case SDL_FINGERDOWN:
#if VERBOSE
SDL_Log("Finger: %"SDL_PRIs64" down - x: %f, y: %f",
event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
#endif
break;
case SDL_FINGERUP:
#if VERBOSE
SDL_Log("Finger: %"SDL_PRIs64" up - x: %f, y: %f",
event.tfinger.fingerId,event.tfinger.x,event.tfinger.y);
#endif
break;
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;
}
}
DrawScreen(screen, window);
#ifdef __EMSCRIPTEN__
if (quitting) {
emscripten_cancel_main_loop();
}
#endif
}
int main(int argc, char* argv[])
{
window = NULL;
screen = NULL;
quitting = SDL_FALSE;
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
/* gesture variables */
knob.r = .1f;
knob.ang = 0;
if (SDL_Init(SDL_INIT_VIDEO) < 0 ) return 1;
if (!(window = initWindow(window, WIDTH, HEIGHT)) ||
!(screen = SDL_GetWindowSurface(window)))
{
SDL_Quit();
return 1;
}
#ifdef __EMSCRIPTEN__
emscripten_set_main_loop(loop, 0, 1);
#else
while(!quitting) {
loop();
}
#endif
SDL_Quit();
return 0;
}
SDL_GetRGB
#define SDL_GetRGB
Definition: SDL_dynapi_overrides.h:294
initWindow
SDL_Window * initWindow(SDL_Window *window, int width, int height)
Definition: testgesture.c:160
SDL_WINDOWPOS_CENTERED
#define SDL_WINDOWPOS_CENTERED
Definition: SDL_video.h:129
SDL_PollEvent
#define SDL_PollEvent
Definition: SDL_dynapi_overrides.h:128
SDL_KEYDOWN
Definition: SDL_events.h:93
x1
GLuint GLfloat GLfloat GLfloat x1
Definition: SDL_opengl_glext.h:8583
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2072
SDL_sinf
#define SDL_sinf
Definition: SDL_dynapi_overrides.h:442
SDL_Event::dgesture
SDL_DollarGestureEvent dgesture
Definition: SDL_events.h:546
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1565
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:157
SDL_Surface::h
int h
Definition: SDL_surface.h:73
stream
GLuint GLuint stream
Definition: SDL_opengl_glext.h:1776
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1567
SDL_RecordGesture
#define SDL_RecordGesture
Definition: SDL_dynapi_overrides.h:161
screen
SDL_Surface * screen
Definition: testgesture.c:42
SDL_PixelFormat::BytesPerPixel
Uint8 BytesPerPixel
Definition: SDL_pixels.h:304
SDL_RWops
Definition: SDL_rwops.h:52
SDL_fabs
#define SDL_fabs
Definition: SDL_dynapi_overrides.h:436
events
static SDL_Event events[EVENT_BUF_SIZE]
Definition: testgesture.c:36
SDL_Surface
A collection of pixels used in software blitting.
Definition: SDL_surface.h:69
SDL_QUIT
Definition: SDL_events.h:60
quitting
SDL_bool quitting
Definition: testgesture.c:44
main
int main(int argc, char *argv[])
Definition: testgesture.c:277
knob
static Knob knob
Definition: testgesture.c:55
drawCircle
void drawCircle(SDL_Surface *screen, float x, float y, float r, unsigned int c)
Definition: testgesture.c:93
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
Point
Definition: testgesture.c:46
SDL_MultiGestureEvent::dDist
float dDist
Definition: SDL_events.h:433
SDL_CreateWindow
#define SDL_CreateWindow
Definition: SDL_dynapi_overrides.h:518
SDL_MultiGestureEvent::y
float y
Definition: SDL_events.h:435
SDL_GetNumTouchDevices
#define SDL_GetNumTouchDevices
Definition: SDL_dynapi_overrides.h:493
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1565
SDL_Surface::w
int w
Definition: SDL_surface.h:73
SDL_DollarGestureEvent::gestureId
SDL_GestureID gestureId
Definition: SDL_events.h:449
SDL_DollarGestureEvent::error
float error
Definition: SDL_events.h:451
SDLK_i
Definition: SDL_keycode.h:105
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:348
Knob::r
float r
Definition: testgesture.c:51
y1
GLfixed y1
Definition: SDL_opengl_glext.h:4583
SDLK_s
Definition: SDL_keycode.h:115
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:126
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1109
SDL_DOLLARGESTURE
Definition: SDL_events.h:130
SDL_Event::window
SDL_WindowEvent window
Definition: SDL_events.h:525
SDL_UpdateWindowSurface
#define SDL_UpdateWindowSurface
Definition: SDL_dynapi_overrides.h:545
SDL_GetTouchDevice
#define SDL_GetTouchDevice
Definition: SDL_dynapi_overrides.h:494
BPP
#define BPP
Definition: testgesture.c:27
SDL_Log
#define SDL_Log
Definition: SDL_dynapi_overrides.h:37
SDL_RWFromFile
#define SDL_RWFromFile
Definition: SDL_dynapi_overrides.h:357
SDL_FINGERDOWN
Definition: SDL_events.h:125
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:393
SDL_PRIs64
#define SDL_PRIs64
Definition: SDL_stdinc.h:177
eventWrite
static int eventWrite
Definition: testgesture.c:37
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1567
SDL_Surface::pixels
void * pixels
Definition: SDL_surface.h:75
SDL_TouchFingerEvent::x
float x
Definition: SDL_events.h:416
loop
void loop()
Definition: testgesture.c:170
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:139
SDL_MultiGestureEvent::numFingers
Uint16 numFingers
Definition: SDL_events.h:436
SDL_Event::mgesture
SDL_MultiGestureEvent mgesture
Definition: SDL_events.h:545
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_Quit
#define SDL_Quit
Definition: SDL_dynapi_overrides.h:64
drawLine
void drawLine(SDL_Surface *screen, float x0, float y0, float x1, float y1, unsigned int col)
Definition: testgesture.c:87
SDL_SaveAllDollarTemplates
#define SDL_SaveAllDollarTemplates
Definition: SDL_dynapi_overrides.h:162
SDL_WindowEvent::data2
Sint32 data2
Definition: SDL_events.h:181
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
SDL_WINDOWEVENT
Definition: SDL_events.h:89
SDL_GetWindowSurface
#define SDL_GetWindowSurface
Definition: SDL_dynapi_overrides.h:544
window
SDL_Window * window
Definition: testgesture.c:43
EVENT_BUF_SIZE
#define EVENT_BUF_SIZE
Definition: testgesture.c:31
SDL_TouchID
Sint64 SDL_TouchID
Definition: SDL_touch.h:41
WIDTH
#define WIDTH
Definition: testgesture.c:25
Point::x
float x
Definition: testgesture.c:47
SDL_LOG_PRIORITY_INFO
Definition: SDL_log.h:106
SDL_GetNumTouchFingers
#define SDL_GetNumTouchFingers
Definition: SDL_dynapi_overrides.h:495
Knob::p
Point p
Definition: testgesture.c:52
SDL_WindowEvent::event
Uint8 event
Definition: SDL_events.h:176
SDL_KeyboardEvent::keysym
SDL_Keysym keysym
Definition: SDL_events.h:196
drawKnob
void drawKnob(SDL_Surface *screen, Knob k)
Definition: testgesture.c:111
SDL_TRUE
Definition: SDL_stdinc.h:129
SDL_FINGERMOTION
Definition: SDL_events.h:127
setpix
void setpix(SDL_Surface *screen, float _x, float _y, unsigned int col)
Definition: testgesture.c:57
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:42
SDL_cosf
#define SDL_cosf
Definition: SDL_dynapi_overrides.h:435
SDL_LogSetPriority
#define SDL_LogSetPriority
Definition: SDL_dynapi_overrides.h:242
y0
GLuint GLfloat GLfloat y0
Definition: SDL_opengl_glext.h:8583
NULL
#define NULL
Definition: begin_code.h:143
SDL_MultiGestureEvent::dTheta
float dTheta
Definition: SDL_events.h:432
SDL_WINDOW_RESIZABLE
Definition: SDL_video.h:103
SDL_Surface::format
SDL_PixelFormat * format
Definition: SDL_surface.h:72
SDL_RWclose
#define SDL_RWclose(ctx)
Definition: SDL_rwops.h:189
SDL_FINGERUP
Definition: SDL_events.h:126
SDL_LoadDollarTemplates
#define SDL_LoadDollarTemplates
Definition: SDL_dynapi_overrides.h:164
HEIGHT
#define HEIGHT
Definition: testgesture.c:26
SDL_Event::key
SDL_KeyboardEvent key
Definition: SDL_events.h:526
SDL_MultiGestureEvent::x
float x
Definition: SDL_events.h:434
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:71
SDL_TouchFingerEvent::y
float y
Definition: SDL_events.h:417
SDL_FillRect
#define SDL_FillRect
Definition: SDL_dynapi_overrides.h:470
SDL_FALSE
Definition: SDL_stdinc.h:128
SDL_MapRGB
#define SDL_MapRGB
Definition: SDL_dynapi_overrides.h:292
Point::y
float y
Definition: testgesture.c:47
SDL_TouchFingerEvent::fingerId
SDL_FingerID fingerId
Definition: SDL_events.h:415
SDL_Keysym::sym
SDL_Keycode sym
Definition: SDL_keyboard.h:50
SDL_Surface::pitch
int pitch
Definition: SDL_surface.h:74
SDL_sqrt
#define SDL_sqrt
Definition: SDL_dynapi_overrides.h:443
x0
GLuint GLfloat x0
Definition: SDL_opengl_glext.h:8583
Knob
Definition: testgesture.c:50
SDL_Init
#define SDL_Init
Definition: SDL_dynapi_overrides.h:60
SDL_Event
General event structure.
Definition: SDL_events.h:521
SDL_WINDOWEVENT_RESIZED
Definition: SDL_video.h:145
Knob::ang
float ang
Definition: testgesture.c:51
colors
static int colors[7]
Definition: testgesture.c:40
SDLK_ESCAPE
Definition: SDL_keycode.h:52
SDL_WindowEvent::data1
Sint32 data1
Definition: SDL_events.h:180
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
SDL.h
DrawScreen
void DrawScreen(SDL_Surface *screen, SDL_Window *window)
Definition: testgesture.c:117
SDLK_l
Definition: SDL_keycode.h:108
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
SDL_LOG_CATEGORY_APPLICATION
Definition: SDL_log.h:66
SDLK_SPACE
Definition: SDL_keycode.h:55
SDL_DOLLARRECORD
Definition: SDL_events.h:131
SDL_INIT_VIDEO
#define SDL_INIT_VIDEO
Definition: SDL.h:77
t
GLdouble GLdouble t
Definition: SDL_opengl.h:2064
SDL_Event::type
Uint32 type
Definition: SDL_events.h:523
ty
GLbyte ty
Definition: SDL_opengl_glext.h:5972
SDL_MULTIGESTURE
Definition: SDL_events.h:132
SDL_Event::tfinger
SDL_TouchFingerEvent tfinger
Definition: SDL_events.h:544