src/events/SDL_gesture.c
changeset 6065 fcd144b830ce
parent 5981 75caa8a7d559
child 6066 1d66a8dce3ef
     1.1 --- a/src/events/SDL_gesture.c	Wed Oct 26 12:04:05 2011 -0400
     1.2 +++ b/src/events/SDL_gesture.c	Thu Oct 27 21:26:44 2011 +0200
     1.3 @@ -11,11 +11,11 @@
     1.4    freely, subject to the following restrictions:
     1.5  
     1.6    1. The origin of this software must not be misrepresented; you must not
     1.7 -     claim that you wrote the original software. If you use this software
     1.8 -     in a product, an acknowledgment in the product documentation would be
     1.9 -     appreciated but is not required.
    1.10 +  claim that you wrote the original software. If you use this software
    1.11 +  in a product, an acknowledgment in the product documentation would be
    1.12 +  appreciated but is not required.
    1.13    2. Altered source versions must be plainly marked as such, and must not be
    1.14 -     misrepresented as being the original software.
    1.15 +  misrepresented as being the original software.
    1.16    3. This notice may not be removed or altered from any source distribution.
    1.17  */
    1.18  
    1.19 @@ -36,7 +36,7 @@
    1.20  
    1.21  #define MAXPATHSIZE 1024
    1.22  
    1.23 - 
    1.24 +
    1.25  
    1.26  
    1.27  #define DOLLARNPOINTS 64
    1.28 @@ -44,35 +44,35 @@
    1.29  
    1.30  #define ENABLE_DOLLAR
    1.31  
    1.32 -#define PHI 0.618033989 
    1.33 +#define PHI 0.618033989
    1.34  
    1.35  typedef struct {
    1.36 -  float x,y;
    1.37 +    float x,y;
    1.38  } SDL_FloatPoint;
    1.39  
    1.40  typedef struct {
    1.41 -  float length;
    1.42 -  
    1.43 -  int numPoints;
    1.44 -  SDL_FloatPoint p[MAXPATHSIZE];
    1.45 +    float length;
    1.46 +
    1.47 +    int numPoints;
    1.48 +    SDL_FloatPoint p[MAXPATHSIZE];
    1.49  } SDL_DollarPath;
    1.50  
    1.51  typedef struct {
    1.52 -  SDL_FloatPoint path[DOLLARNPOINTS];
    1.53 -  unsigned long hash;
    1.54 +    SDL_FloatPoint path[DOLLARNPOINTS];
    1.55 +    unsigned long hash;
    1.56  } SDL_DollarTemplate;
    1.57  
    1.58  typedef struct {
    1.59 -  SDL_GestureID id;
    1.60 -  SDL_FloatPoint res;
    1.61 -  SDL_FloatPoint centroid;
    1.62 -  SDL_DollarPath dollarPath;
    1.63 -  Uint16 numDownFingers;
    1.64 +    SDL_GestureID id;
    1.65 +    SDL_FloatPoint res;
    1.66 +    SDL_FloatPoint centroid;
    1.67 +    SDL_DollarPath dollarPath;
    1.68 +    Uint16 numDownFingers;
    1.69  
    1.70 -  int numDollarTemplates;
    1.71 -  SDL_DollarTemplate *dollarTemplate;
    1.72 +    int numDollarTemplates;
    1.73 +    SDL_DollarTemplate *dollarTemplate;
    1.74  
    1.75 -  SDL_bool recording;
    1.76 +    SDL_bool recording;
    1.77  } SDL_GestureTouch;
    1.78  
    1.79  SDL_GestureTouch *SDL_gestureTouch;
    1.80 @@ -80,586 +80,603 @@
    1.81  SDL_bool recordAll;
    1.82  
    1.83  #if 0
    1.84 -static void PrintPath(SDL_FloatPoint *path) {
    1.85 -  int i;
    1.86 -  printf("Path:");
    1.87 -  for(i=0;i<DOLLARNPOINTS;i++) {
    1.88 -    printf(" (%f,%f)",path[i].x,path[i].y);
    1.89 -  }
    1.90 -  printf("\n");
    1.91 +static void PrintPath(SDL_FloatPoint *path)
    1.92 +{
    1.93 +    int i;
    1.94 +    printf("Path:");
    1.95 +    for(i=0;i<DOLLARNPOINTS;i++) {
    1.96 +        printf(" (%f,%f)",path[i].x,path[i].y);
    1.97 +    }
    1.98 +    printf("\n");
    1.99  }
   1.100  #endif
   1.101  
   1.102 -int SDL_RecordGesture(SDL_TouchID touchId) {
   1.103 -  int i;
   1.104 -  if(touchId < 0) recordAll = SDL_TRUE;
   1.105 -  for(i = 0;i < SDL_numGestureTouches; i++) {
   1.106 -    if((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) {
   1.107 -      SDL_gestureTouch[i].recording = SDL_TRUE;
   1.108 -      if(touchId >= 0)
   1.109 -        return 1;
   1.110 -    }      
   1.111 -  }
   1.112 -  return (touchId < 0);
   1.113 +int SDL_RecordGesture(SDL_TouchID touchId)
   1.114 +{
   1.115 +    int i;
   1.116 +    if(touchId < 0) recordAll = SDL_TRUE;
   1.117 +    for(i = 0;i < SDL_numGestureTouches; i++) {
   1.118 +        if((touchId < 0) || (SDL_gestureTouch[i].id == touchId)) {
   1.119 +            SDL_gestureTouch[i].recording = SDL_TRUE;
   1.120 +            if(touchId >= 0)
   1.121 +                return 1;
   1.122 +        }
   1.123 +    }
   1.124 +    return (touchId < 0);
   1.125  }
   1.126  
   1.127 -unsigned long SDL_HashDollar(SDL_FloatPoint* points) {
   1.128 -  unsigned long hash = 5381;
   1.129 -  int i;
   1.130 -  for(i = 0;i < DOLLARNPOINTS; i++) { 
   1.131 -    hash = ((hash<<5) + hash) + (unsigned long)points[i].x;
   1.132 -    hash = ((hash<<5) + hash) + (unsigned long)points[i].y;
   1.133 -  }
   1.134 -  return hash;
   1.135 +unsigned long SDL_HashDollar(SDL_FloatPoint* points)
   1.136 +{
   1.137 +    unsigned long hash = 5381;
   1.138 +    int i;
   1.139 +    for(i = 0;i < DOLLARNPOINTS; i++) {
   1.140 +        hash = ((hash<<5) + hash) + (unsigned long)points[i].x;
   1.141 +        hash = ((hash<<5) + hash) + (unsigned long)points[i].y;
   1.142 +    }
   1.143 +    return hash;
   1.144  }
   1.145  
   1.146  
   1.147 -static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops * src) {
   1.148 -  if(src == NULL) return 0;
   1.149 +static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops * src)
   1.150 +{
   1.151 +    if(src == NULL) return 0;
   1.152  
   1.153 -  
   1.154 -  //No Longer storing the Hash, rehash on load
   1.155 -  //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0;
   1.156 -  
   1.157 -  if(SDL_RWwrite(src,templ->path,
   1.158 -                 sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS) 
   1.159 -    return 0;
   1.160  
   1.161 -  return 1;
   1.162 +    //No Longer storing the Hash, rehash on load
   1.163 +    //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0;
   1.164 +
   1.165 +    if(SDL_RWwrite(src,templ->path,
   1.166 +                   sizeof(templ->path[0]),DOLLARNPOINTS) != DOLLARNPOINTS)
   1.167 +        return 0;
   1.168 +
   1.169 +    return 1;
   1.170  }
   1.171  
   1.172  
   1.173 -int SDL_SaveAllDollarTemplates(SDL_RWops *src) {  
   1.174 -  int i,j,rtrn = 0;
   1.175 -  for(i = 0; i < SDL_numGestureTouches; i++) {
   1.176 -    SDL_GestureTouch* touch = &SDL_gestureTouch[i];
   1.177 -    for(j = 0;j < touch->numDollarTemplates; j++) {
   1.178 -        rtrn += SaveTemplate(&touch->dollarTemplate[i],src);
   1.179 +int SDL_SaveAllDollarTemplates(SDL_RWops *src)
   1.180 +{
   1.181 +    int i,j,rtrn = 0;
   1.182 +    for(i = 0; i < SDL_numGestureTouches; i++) {
   1.183 +        SDL_GestureTouch* touch = &SDL_gestureTouch[i];
   1.184 +        for(j = 0;j < touch->numDollarTemplates; j++) {
   1.185 +            rtrn += SaveTemplate(&touch->dollarTemplate[i],src);
   1.186 +        }
   1.187      }
   1.188 -  }
   1.189 -  return rtrn;  
   1.190 +    return rtrn;
   1.191  }
   1.192  
   1.193 -int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src) {
   1.194 -  int i,j;
   1.195 -  for(i = 0; i < SDL_numGestureTouches; i++) {
   1.196 -    SDL_GestureTouch* touch = &SDL_gestureTouch[i];
   1.197 -    for(j = 0;j < touch->numDollarTemplates; j++) {
   1.198 -      if(touch->dollarTemplate[i].hash == gestureId) {
   1.199 -        return SaveTemplate(&touch->dollarTemplate[i],src);
   1.200 -      }
   1.201 +int SDL_SaveDollarTemplate(SDL_GestureID gestureId, SDL_RWops *src)
   1.202 +{
   1.203 +    int i,j;
   1.204 +    for(i = 0; i < SDL_numGestureTouches; i++) {
   1.205 +        SDL_GestureTouch* touch = &SDL_gestureTouch[i];
   1.206 +        for(j = 0;j < touch->numDollarTemplates; j++) {
   1.207 +            if(touch->dollarTemplate[i].hash == gestureId) {
   1.208 +                return SaveTemplate(&touch->dollarTemplate[i],src);
   1.209 +            }
   1.210 +        }
   1.211      }
   1.212 -  }
   1.213 -  SDL_SetError("Unknown gestureId");
   1.214 -  return -1;
   1.215 +    SDL_SetError("Unknown gestureId");
   1.216 +    return -1;
   1.217  }
   1.218  
   1.219  //path is an already sampled set of points
   1.220  //Returns the index of the gesture on success, or -1
   1.221 -static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch,SDL_FloatPoint* path) {
   1.222 -  SDL_DollarTemplate* dollarTemplate;
   1.223 -  SDL_DollarTemplate *templ;
   1.224 -  int i = 0;
   1.225 -  if(inTouch == NULL) {
   1.226 -    if(SDL_numGestureTouches == 0) return -1;
   1.227 -    for(i = 0;i < SDL_numGestureTouches; i++) {
   1.228 -      inTouch = &SDL_gestureTouch[i];
   1.229 +static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch,SDL_FloatPoint* path)
   1.230 +{
   1.231 +    SDL_DollarTemplate* dollarTemplate;
   1.232 +    SDL_DollarTemplate *templ;
   1.233 +    int i = 0;
   1.234 +    if(inTouch == NULL) {
   1.235 +        if(SDL_numGestureTouches == 0) return -1;
   1.236 +        for(i = 0;i < SDL_numGestureTouches; i++) {
   1.237 +            inTouch = &SDL_gestureTouch[i];
   1.238  
   1.239 -    dollarTemplate = 
   1.240 -        (SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
   1.241 -                    (inTouch->numDollarTemplates + 1) * 
   1.242 -                    sizeof(SDL_DollarTemplate));
   1.243 -      if(!dollarTemplate) {
   1.244 -        SDL_OutOfMemory();
   1.245 -        return -1;
   1.246 -      }
   1.247 -        
   1.248 -      inTouch->dollarTemplate = dollarTemplate;
   1.249 +            dollarTemplate =
   1.250 +                (SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
   1.251 +                                                  (inTouch->numDollarTemplates + 1) *
   1.252 +                                                  sizeof(SDL_DollarTemplate));
   1.253 +            if(!dollarTemplate) {
   1.254 +                SDL_OutOfMemory();
   1.255 +                return -1;
   1.256 +            }
   1.257  
   1.258 -    templ = 
   1.259 -        &inTouch->dollarTemplate[inTouch->numDollarTemplates];
   1.260 -      SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   1.261 -      templ->hash = SDL_HashDollar(templ->path);
   1.262 -      inTouch->numDollarTemplates++;    
   1.263 +            inTouch->dollarTemplate = dollarTemplate;
   1.264 +
   1.265 +            templ =
   1.266 +                &inTouch->dollarTemplate[inTouch->numDollarTemplates];
   1.267 +            SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   1.268 +            templ->hash = SDL_HashDollar(templ->path);
   1.269 +            inTouch->numDollarTemplates++;
   1.270 +        }
   1.271 +        return inTouch->numDollarTemplates - 1;
   1.272 +    } else {
   1.273 +        SDL_DollarTemplate* dollarTemplate =
   1.274 +            ( SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
   1.275 +                                               (inTouch->numDollarTemplates + 1) *
   1.276 +                                               sizeof(SDL_DollarTemplate));
   1.277 +        if(!dollarTemplate) {
   1.278 +            SDL_OutOfMemory();
   1.279 +            return -1;
   1.280 +        }
   1.281 +
   1.282 +        inTouch->dollarTemplate = dollarTemplate;
   1.283 +
   1.284 +        templ =
   1.285 +            &inTouch->dollarTemplate[inTouch->numDollarTemplates];
   1.286 +        SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   1.287 +        templ->hash = SDL_HashDollar(templ->path);
   1.288 +        inTouch->numDollarTemplates++;
   1.289 +        return inTouch->numDollarTemplates - 1;
   1.290      }
   1.291 -    return inTouch->numDollarTemplates - 1;
   1.292 -  } else {
   1.293 -    SDL_DollarTemplate* dollarTemplate = 
   1.294 -      ( SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
   1.295 -                  (inTouch->numDollarTemplates + 1) * 
   1.296 -                  sizeof(SDL_DollarTemplate));
   1.297 -    if(!dollarTemplate) {
   1.298 -      SDL_OutOfMemory();
   1.299 -      return -1;
   1.300 -    }
   1.301 -    
   1.302 -    inTouch->dollarTemplate = dollarTemplate;
   1.303 -
   1.304 -    templ = 
   1.305 -      &inTouch->dollarTemplate[inTouch->numDollarTemplates];
   1.306 -    SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   1.307 -    templ->hash = SDL_HashDollar(templ->path);
   1.308 -    inTouch->numDollarTemplates++;
   1.309 -    return inTouch->numDollarTemplates - 1;
   1.310 -  }
   1.311 -  return -1;
   1.312 +    return -1;
   1.313  }
   1.314  
   1.315 -int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) {
   1.316 -  int i,loaded = 0;
   1.317 -  SDL_GestureTouch *touch = NULL;
   1.318 -  if(src == NULL) return 0;
   1.319 -  if(touchId >= 0) {
   1.320 -    for(i = 0;i < SDL_numGestureTouches; i++)
   1.321 -      if(SDL_gestureTouch[i].id == touchId)
   1.322 -        touch = &SDL_gestureTouch[i];
   1.323 -    if(touch == NULL) return -1;
   1.324 -  }
   1.325 +int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
   1.326 +{
   1.327 +    int i,loaded = 0;
   1.328 +    SDL_GestureTouch *touch = NULL;
   1.329 +    if(src == NULL) return 0;
   1.330 +    if(touchId >= 0) {
   1.331 +        for(i = 0;i < SDL_numGestureTouches; i++)
   1.332 +            if(SDL_gestureTouch[i].id == touchId)
   1.333 +                touch = &SDL_gestureTouch[i];
   1.334 +        if(touch == NULL) return -1;
   1.335 +    }
   1.336  
   1.337 -  while(1) {
   1.338 -    SDL_DollarTemplate templ;
   1.339 +    while(1) {
   1.340 +        SDL_DollarTemplate templ;
   1.341  
   1.342 -    if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < 
   1.343 -       DOLLARNPOINTS) break;
   1.344 +        if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) <
   1.345 +           DOLLARNPOINTS) break;
   1.346  
   1.347 -    if(touchId >= 0) {
   1.348 -      //printf("Adding loaded gesture to 1 touch\n");
   1.349 -      if(SDL_AddDollarGesture(touch,templ.path)) loaded++;
   1.350 +        if(touchId >= 0) {
   1.351 +            //printf("Adding loaded gesture to 1 touch\n");
   1.352 +            if(SDL_AddDollarGesture(touch,templ.path)) loaded++;
   1.353 +        }
   1.354 +        else {
   1.355 +            //printf("Adding to: %i touches\n",SDL_numGestureTouches);
   1.356 +            for(i = 0;i < SDL_numGestureTouches; i++) {
   1.357 +                touch = &SDL_gestureTouch[i];
   1.358 +                //printf("Adding loaded gesture to + touches\n");
   1.359 +                //TODO: What if this fails?
   1.360 +                SDL_AddDollarGesture(touch,templ.path);
   1.361 +            }
   1.362 +            loaded++;
   1.363 +        }
   1.364      }
   1.365 -    else {
   1.366 -      //printf("Adding to: %i touches\n",SDL_numGestureTouches);
   1.367 -      for(i = 0;i < SDL_numGestureTouches; i++) {
   1.368 -        touch = &SDL_gestureTouch[i];
   1.369 -        //printf("Adding loaded gesture to + touches\n");
   1.370 -        //TODO: What if this fails?
   1.371 -        SDL_AddDollarGesture(touch,templ.path);        
   1.372 -      }
   1.373 -      loaded++;
   1.374 -    }
   1.375 -  }
   1.376  
   1.377 -  return loaded; 
   1.378 +    return loaded;
   1.379  }
   1.380  
   1.381  
   1.382 -float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang) {
   1.383 -  //  SDL_FloatPoint p[DOLLARNPOINTS];
   1.384 -  float dist = 0;
   1.385 -  SDL_FloatPoint p;
   1.386 -  int i;
   1.387 -  for(i = 0; i < DOLLARNPOINTS; i++) {
   1.388 -    p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang));
   1.389 -    p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang));
   1.390 -    dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
   1.391 -                 (p.y-templ[i].y)*(p.y-templ[i].y)));
   1.392 -  }
   1.393 -  return dist/DOLLARNPOINTS;
   1.394 -  
   1.395 +float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang)
   1.396 +{
   1.397 +    //  SDL_FloatPoint p[DOLLARNPOINTS];
   1.398 +    float dist = 0;
   1.399 +    SDL_FloatPoint p;
   1.400 +    int i;
   1.401 +    for(i = 0; i < DOLLARNPOINTS; i++) {
   1.402 +        p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang));
   1.403 +        p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang));
   1.404 +        dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
   1.405 +                                 (p.y-templ[i].y)*(p.y-templ[i].y)));
   1.406 +    }
   1.407 +    return dist/DOLLARNPOINTS;
   1.408 +
   1.409  }
   1.410  
   1.411 -float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) {
   1.412 -  //------------BEGIN DOLLAR BLACKBOX----------------//
   1.413 -  //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
   1.414 -  //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
   1.415 -  double ta = -M_PI/4;
   1.416 -  double tb = M_PI/4;
   1.417 -  double dt = M_PI/90;
   1.418 -  float x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.419 -  float f1 = dollarDifference(points,templ,x1);
   1.420 -  float x2 = (float)((1-PHI)*ta + PHI*tb);
   1.421 -  float f2 = dollarDifference(points,templ,x2);
   1.422 -  while(SDL_fabs(ta-tb) > dt) {
   1.423 -    if(f1 < f2) {
   1.424 -      tb = x2;
   1.425 -      x2 = x1;
   1.426 -      f2 = f1;
   1.427 -      x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.428 -      f1 = dollarDifference(points,templ,x1);
   1.429 +float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ)
   1.430 +{
   1.431 +    //------------BEGIN DOLLAR BLACKBOX----------------//
   1.432 +    //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
   1.433 +    //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
   1.434 +    double ta = -M_PI/4;
   1.435 +    double tb = M_PI/4;
   1.436 +    double dt = M_PI/90;
   1.437 +    float x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.438 +    float f1 = dollarDifference(points,templ,x1);
   1.439 +    float x2 = (float)((1-PHI)*ta + PHI*tb);
   1.440 +    float f2 = dollarDifference(points,templ,x2);
   1.441 +    while(SDL_fabs(ta-tb) > dt) {
   1.442 +        if(f1 < f2) {
   1.443 +            tb = x2;
   1.444 +            x2 = x1;
   1.445 +            f2 = f1;
   1.446 +            x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.447 +            f1 = dollarDifference(points,templ,x1);
   1.448 +        }
   1.449 +        else {
   1.450 +            ta = x1;
   1.451 +            x1 = x2;
   1.452 +            f1 = f2;
   1.453 +            x2 = (float)((1-PHI)*ta + PHI*tb);
   1.454 +            f2 = dollarDifference(points,templ,x2);
   1.455 +        }
   1.456      }
   1.457 -    else {
   1.458 -      ta = x1;
   1.459 -      x1 = x2;
   1.460 -      f1 = f2;
   1.461 -      x2 = (float)((1-PHI)*ta + PHI*tb);
   1.462 -      f2 = dollarDifference(points,templ,x2);
   1.463 -    }
   1.464 -  }
   1.465 -  /*
   1.466 -  if(f1 <= f2)
   1.467 -    printf("Min angle (x1): %f\n",x1);
   1.468 -  else if(f1 >  f2)
   1.469 -    printf("Min angle (x2): %f\n",x2);
   1.470 -  */
   1.471 -  return SDL_min(f1,f2);  
   1.472 +    /*
   1.473 +      if(f1 <= f2)
   1.474 +      printf("Min angle (x1): %f\n",x1);
   1.475 +      else if(f1 >  f2)
   1.476 +      printf("Min angle (x2): %f\n",x2);
   1.477 +    */
   1.478 +    return SDL_min(f1,f2);
   1.479  }
   1.480  
   1.481  //DollarPath contains raw points, plus (possibly) the calculated length
   1.482 -int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points) {
   1.483 -  int i;
   1.484 -  float interval;
   1.485 -  float dist;
   1.486 -  int numPoints = 0;
   1.487 -  SDL_FloatPoint centroid; 
   1.488 -  float xmin,xmax,ymin,ymax;
   1.489 -  float ang;
   1.490 -  float w,h;
   1.491 -  float length = path->length;
   1.492 +int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points)
   1.493 +{
   1.494 +    int i;
   1.495 +    float interval;
   1.496 +    float dist;
   1.497 +    int numPoints = 0;
   1.498 +    SDL_FloatPoint centroid;
   1.499 +    float xmin,xmax,ymin,ymax;
   1.500 +    float ang;
   1.501 +    float w,h;
   1.502 +    float length = path->length;
   1.503  
   1.504 -  //Calculate length if it hasn't already been done
   1.505 -  if(length <= 0) {
   1.506 -    for(i=1;i<path->numPoints;i++) {
   1.507 -      float dx = path->p[i  ].x - 
   1.508 -                 path->p[i-1].x;
   1.509 -      float dy = path->p[i  ].y - 
   1.510 -                 path->p[i-1].y;
   1.511 -      length += (float)(SDL_sqrt(dx*dx+dy*dy));
   1.512 +    //Calculate length if it hasn't already been done
   1.513 +    if(length <= 0) {
   1.514 +        for(i=1;i<path->numPoints;i++) {
   1.515 +            float dx = path->p[i  ].x -
   1.516 +                path->p[i-1].x;
   1.517 +            float dy = path->p[i  ].y -
   1.518 +                path->p[i-1].y;
   1.519 +            length += (float)(SDL_sqrt(dx*dx+dy*dy));
   1.520 +        }
   1.521      }
   1.522 -  }
   1.523  
   1.524 -  //Resample
   1.525 -  interval = length/(DOLLARNPOINTS - 1);
   1.526 -  dist = interval;
   1.527 +    //Resample
   1.528 +    interval = length/(DOLLARNPOINTS - 1);
   1.529 +    dist = interval;
   1.530  
   1.531 -  centroid.x = 0;centroid.y = 0;
   1.532 -  
   1.533 -  //printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y);
   1.534 -  for(i = 1;i < path->numPoints;i++) {
   1.535 -    float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+
   1.536 -                             (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y)));
   1.537 -    //printf("d = %f dist = %f/%f\n",d,dist,interval);
   1.538 -    while(dist + d > interval) {
   1.539 -      points[numPoints].x = path->p[i-1].x + 
   1.540 -        ((interval-dist)/d)*(path->p[i].x-path->p[i-1].x);
   1.541 -      points[numPoints].y = path->p[i-1].y + 
   1.542 -        ((interval-dist)/d)*(path->p[i].y-path->p[i-1].y);
   1.543 -      centroid.x += points[numPoints].x;
   1.544 -      centroid.y += points[numPoints].y;
   1.545 -      numPoints++;
   1.546 +    centroid.x = 0;centroid.y = 0;
   1.547  
   1.548 -      dist -= interval;
   1.549 +    //printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y);
   1.550 +    for(i = 1;i < path->numPoints;i++) {
   1.551 +        float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+
   1.552 +                                   (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y)));
   1.553 +        //printf("d = %f dist = %f/%f\n",d,dist,interval);
   1.554 +        while(dist + d > interval) {
   1.555 +            points[numPoints].x = path->p[i-1].x +
   1.556 +                ((interval-dist)/d)*(path->p[i].x-path->p[i-1].x);
   1.557 +            points[numPoints].y = path->p[i-1].y +
   1.558 +                ((interval-dist)/d)*(path->p[i].y-path->p[i-1].y);
   1.559 +            centroid.x += points[numPoints].x;
   1.560 +            centroid.y += points[numPoints].y;
   1.561 +            numPoints++;
   1.562 +
   1.563 +            dist -= interval;
   1.564 +        }
   1.565 +        dist += d;
   1.566      }
   1.567 -    dist += d;
   1.568 -  }
   1.569 -  if(numPoints < DOLLARNPOINTS-1) {
   1.570 -    SDL_SetError("ERROR: NumPoints = %i\n",numPoints); 
   1.571 -    return 0;
   1.572 -  }
   1.573 -  //copy the last point
   1.574 -  points[DOLLARNPOINTS-1] = path->p[path->numPoints-1];
   1.575 -  numPoints = DOLLARNPOINTS;
   1.576 +    if(numPoints < DOLLARNPOINTS-1) {
   1.577 +        SDL_SetError("ERROR: NumPoints = %i\n",numPoints);
   1.578 +        return 0;
   1.579 +    }
   1.580 +    //copy the last point
   1.581 +    points[DOLLARNPOINTS-1] = path->p[path->numPoints-1];
   1.582 +    numPoints = DOLLARNPOINTS;
   1.583  
   1.584 -  centroid.x /= numPoints;
   1.585 -  centroid.y /= numPoints;
   1.586 - 
   1.587 -  //printf("Centroid (%f,%f)",centroid.x,centroid.y);
   1.588 -  //Rotate Points so point 0 is left of centroid and solve for the bounding box
   1.589 -  xmin = centroid.x;
   1.590 -  xmax = centroid.x;
   1.591 -  ymin = centroid.y;
   1.592 -  ymax = centroid.y;
   1.593 -  
   1.594 -  ang = (float)(SDL_atan2(centroid.y - points[0].y,
   1.595 -                    centroid.x - points[0].x));
   1.596 +    centroid.x /= numPoints;
   1.597 +    centroid.y /= numPoints;
   1.598  
   1.599 -  for(i = 0;i<numPoints;i++) {                                               
   1.600 -    float px = points[i].x;
   1.601 -    float py = points[i].y;
   1.602 -    points[i].x = (float)((px - centroid.x)*SDL_cos(ang) - 
   1.603 -                  (py - centroid.y)*SDL_sin(ang) + centroid.x);
   1.604 -    points[i].y = (float)((px - centroid.x)*SDL_sin(ang) + 
   1.605 -                  (py - centroid.y)*SDL_cos(ang) + centroid.y);
   1.606 +    //printf("Centroid (%f,%f)",centroid.x,centroid.y);
   1.607 +    //Rotate Points so point 0 is left of centroid and solve for the bounding box
   1.608 +    xmin = centroid.x;
   1.609 +    xmax = centroid.x;
   1.610 +    ymin = centroid.y;
   1.611 +    ymax = centroid.y;
   1.612  
   1.613 +    ang = (float)(SDL_atan2(centroid.y - points[0].y,
   1.614 +                            centroid.x - points[0].x));
   1.615  
   1.616 -    if(points[i].x < xmin) xmin = points[i].x;
   1.617 -    if(points[i].x > xmax) xmax = points[i].x; 
   1.618 -    if(points[i].y < ymin) ymin = points[i].y;
   1.619 -    if(points[i].y > ymax) ymax = points[i].y;
   1.620 -  }
   1.621 +    for(i = 0;i<numPoints;i++) {
   1.622 +        float px = points[i].x;
   1.623 +        float py = points[i].y;
   1.624 +        points[i].x = (float)((px - centroid.x)*SDL_cos(ang) -
   1.625 +                              (py - centroid.y)*SDL_sin(ang) + centroid.x);
   1.626 +        points[i].y = (float)((px - centroid.x)*SDL_sin(ang) +
   1.627 +                              (py - centroid.y)*SDL_cos(ang) + centroid.y);
   1.628  
   1.629 -  //Scale points to DOLLARSIZE, and translate to the origin
   1.630 -  w = xmax-xmin;
   1.631 -  h = ymax-ymin;
   1.632  
   1.633 -  for(i=0;i<numPoints;i++) {
   1.634 -    points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
   1.635 -    points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
   1.636 -  }  
   1.637 -  return numPoints;
   1.638 +        if(points[i].x < xmin) xmin = points[i].x;
   1.639 +        if(points[i].x > xmax) xmax = points[i].x;
   1.640 +        if(points[i].y < ymin) ymin = points[i].y;
   1.641 +        if(points[i].y > ymax) ymax = points[i].y;
   1.642 +    }
   1.643 +
   1.644 +    //Scale points to DOLLARSIZE, and translate to the origin
   1.645 +    w = xmax-xmin;
   1.646 +    h = ymax-ymin;
   1.647 +
   1.648 +    for(i=0;i<numPoints;i++) {
   1.649 +        points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
   1.650 +        points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
   1.651 +    }
   1.652 +    return numPoints;
   1.653  }
   1.654  
   1.655 -float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch) {
   1.656 -        
   1.657 -        SDL_FloatPoint points[DOLLARNPOINTS];
   1.658 -        int i;
   1.659 -        float bestDiff = 10000;
   1.660 +float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch)
   1.661 +{
   1.662  
   1.663 -        dollarNormalize(path,points);
   1.664 +    SDL_FloatPoint points[DOLLARNPOINTS];
   1.665 +    int i;
   1.666 +    float bestDiff = 10000;
   1.667  
   1.668 -        //PrintPath(points);
   1.669 -        *bestTempl = -1;
   1.670 -        for(i = 0;i < touch->numDollarTemplates;i++) {
   1.671 -                float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
   1.672 -                if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
   1.673 -        }
   1.674 -        return bestDiff;
   1.675 +    dollarNormalize(path,points);
   1.676 +
   1.677 +    //PrintPath(points);
   1.678 +    *bestTempl = -1;
   1.679 +    for(i = 0;i < touch->numDollarTemplates;i++) {
   1.680 +        float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
   1.681 +        if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
   1.682 +    }
   1.683 +    return bestDiff;
   1.684  }
   1.685  
   1.686 -int SDL_GestureAddTouch(SDL_Touch* touch) {  
   1.687 -  SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
   1.688 -                                               (SDL_numGestureTouches + 1) *
   1.689 -                                               sizeof(SDL_GestureTouch));
   1.690 +int SDL_GestureAddTouch(SDL_Touch* touch)
   1.691 +{
   1.692 +    SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
   1.693 +                                                                     (SDL_numGestureTouches + 1) *
   1.694 +                                                                     sizeof(SDL_GestureTouch));
   1.695  
   1.696 -  if(!gestureTouch) {
   1.697 -    SDL_OutOfMemory();
   1.698 -    return -1;
   1.699 -  }
   1.700 +    if(!gestureTouch) {
   1.701 +        SDL_OutOfMemory();
   1.702 +        return -1;
   1.703 +    }
   1.704  
   1.705 -  SDL_gestureTouch = gestureTouch;
   1.706 +    SDL_gestureTouch = gestureTouch;
   1.707  
   1.708 -  SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.709 -  SDL_gestureTouch[SDL_numGestureTouches].res.y = touch->yres;
   1.710 -  SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0;
   1.711 +    SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.712 +    SDL_gestureTouch[SDL_numGestureTouches].res.y = touch->yres;
   1.713 +    SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0;
   1.714  
   1.715 -  SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.716 -  SDL_gestureTouch[SDL_numGestureTouches].id = touch->id;
   1.717 +    SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.718 +    SDL_gestureTouch[SDL_numGestureTouches].id = touch->id;
   1.719  
   1.720 -  SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0;
   1.721 +    SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0;
   1.722  
   1.723 -  SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE;
   1.724 +    SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE;
   1.725  
   1.726 -  SDL_numGestureTouches++;
   1.727 -  return 0;
   1.728 +    SDL_numGestureTouches++;
   1.729 +    return 0;
   1.730  }
   1.731  
   1.732 -int SDL_GestureRemoveTouch(SDL_TouchID id) {
   1.733 -  int i;
   1.734 -  for (i = 0; i < SDL_numGestureTouches; i++) {
   1.735 -    if (SDL_gestureTouch[i].id == id) {
   1.736 -      SDL_numGestureTouches--;
   1.737 -      SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i]));
   1.738 -      return 1;
   1.739 +int SDL_GestureRemoveTouch(SDL_TouchID id)
   1.740 +{
   1.741 +    int i;
   1.742 +    for (i = 0; i < SDL_numGestureTouches; i++) {
   1.743 +        if (SDL_gestureTouch[i].id == id) {
   1.744 +            SDL_numGestureTouches--;
   1.745 +            SDL_memcpy(&SDL_gestureTouch[i], &SDL_gestureTouch[SDL_numGestureTouches], sizeof(SDL_gestureTouch[i]));
   1.746 +            return 1;
   1.747 +        }
   1.748      }
   1.749 -  }
   1.750 -  return -1;
   1.751 +    return -1;
   1.752  }
   1.753  
   1.754  
   1.755 -SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id) {
   1.756 -  int i;
   1.757 -  for(i = 0;i < SDL_numGestureTouches; i++) {
   1.758 -    //printf("%i ?= %i\n",SDL_gestureTouch[i].id,id);
   1.759 -    if(SDL_gestureTouch[i].id == id) return &SDL_gestureTouch[i];
   1.760 -  }
   1.761 -  return NULL;
   1.762 +SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id)
   1.763 +{
   1.764 +    int i;
   1.765 +    for(i = 0;i < SDL_numGestureTouches; i++) {
   1.766 +        //printf("%i ?= %i\n",SDL_gestureTouch[i].id,id);
   1.767 +        if(SDL_gestureTouch[i].id == id) return &SDL_gestureTouch[i];
   1.768 +    }
   1.769 +    return NULL;
   1.770  }
   1.771  
   1.772 -int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist) {
   1.773 -  SDL_Event event;
   1.774 -  event.mgesture.type = SDL_MULTIGESTURE;
   1.775 -  event.mgesture.touchId = touch->id;
   1.776 -  event.mgesture.x = touch->centroid.x;
   1.777 -  event.mgesture.y = touch->centroid.y;
   1.778 -  event.mgesture.dTheta = dTheta;
   1.779 -  event.mgesture.dDist = dDist;  
   1.780 -  event.mgesture.numFingers = touch->numDownFingers;
   1.781 -  return SDL_PushEvent(&event) > 0;
   1.782 +int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist)
   1.783 +{
   1.784 +    SDL_Event event;
   1.785 +    event.mgesture.type = SDL_MULTIGESTURE;
   1.786 +    event.mgesture.touchId = touch->id;
   1.787 +    event.mgesture.x = touch->centroid.x;
   1.788 +    event.mgesture.y = touch->centroid.y;
   1.789 +    event.mgesture.dTheta = dTheta;
   1.790 +    event.mgesture.dDist = dDist;
   1.791 +    event.mgesture.numFingers = touch->numDownFingers;
   1.792 +    return SDL_PushEvent(&event) > 0;
   1.793  }
   1.794  
   1.795  int SDL_SendGestureDollar(SDL_GestureTouch* touch,
   1.796 -                          SDL_GestureID gestureId,float error) {
   1.797 -  SDL_Event event;
   1.798 -  event.dgesture.type = SDL_DOLLARGESTURE;
   1.799 -  event.dgesture.touchId = touch->id;
   1.800 -  /*
   1.801 +                          SDL_GestureID gestureId,float error)
   1.802 +{
   1.803 +    SDL_Event event;
   1.804 +    event.dgesture.type = SDL_DOLLARGESTURE;
   1.805 +    event.dgesture.touchId = touch->id;
   1.806 +    /*
   1.807      //TODO: Add this to give location of gesture?
   1.808 -  event.mgesture.x = touch->centroid.x;
   1.809 -  event.mgesture.y = touch->centroid.y;
   1.810 -  */
   1.811 -  event.dgesture.gestureId = gestureId;
   1.812 -  event.dgesture.error = error;  
   1.813 -  //A finger came up to trigger this event.
   1.814 -  event.dgesture.numFingers = touch->numDownFingers + 1; 
   1.815 -  return SDL_PushEvent(&event) > 0;
   1.816 +    event.mgesture.x = touch->centroid.x;
   1.817 +    event.mgesture.y = touch->centroid.y;
   1.818 +    */
   1.819 +    event.dgesture.gestureId = gestureId;
   1.820 +    event.dgesture.error = error;
   1.821 +    //A finger came up to trigger this event.
   1.822 +    event.dgesture.numFingers = touch->numDownFingers + 1;
   1.823 +    return SDL_PushEvent(&event) > 0;
   1.824  }
   1.825  
   1.826  
   1.827 -int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId) {
   1.828 -  SDL_Event event;
   1.829 -  event.dgesture.type = SDL_DOLLARRECORD;
   1.830 -  event.dgesture.touchId = touch->id;
   1.831 -  event.dgesture.gestureId = gestureId;
   1.832 -  return SDL_PushEvent(&event) > 0;
   1.833 +int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId)
   1.834 +{
   1.835 +    SDL_Event event;
   1.836 +    event.dgesture.type = SDL_DOLLARRECORD;
   1.837 +    event.dgesture.touchId = touch->id;
   1.838 +    event.dgesture.gestureId = gestureId;
   1.839 +    return SDL_PushEvent(&event) > 0;
   1.840  }
   1.841  
   1.842  
   1.843  void SDL_GestureProcessEvent(SDL_Event* event)
   1.844  {
   1.845 -  float x,y; 
   1.846 -  SDL_FloatPoint path[DOLLARNPOINTS];
   1.847 -  int index;
   1.848 -  int i;
   1.849 -  float pathDx, pathDy;
   1.850 -  SDL_FloatPoint lastP;
   1.851 -  SDL_FloatPoint lastCentroid;
   1.852 -  float lDist;
   1.853 -  float Dist;
   1.854 -  float dtheta;
   1.855 -  float dDist;
   1.856 +    float x,y;
   1.857 +    SDL_FloatPoint path[DOLLARNPOINTS];
   1.858 +    int index;
   1.859 +    int i;
   1.860 +    float pathDx, pathDy;
   1.861 +    SDL_FloatPoint lastP;
   1.862 +    SDL_FloatPoint lastCentroid;
   1.863 +    float lDist;
   1.864 +    float Dist;
   1.865 +    float dtheta;
   1.866 +    float dDist;
   1.867  
   1.868 -  if(event->type == SDL_FINGERMOTION || 
   1.869 -     event->type == SDL_FINGERDOWN ||
   1.870 -     event->type == SDL_FINGERUP) {
   1.871 -    SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
   1.872 -    
   1.873 -    //Shouldn't be possible
   1.874 -    if(inTouch == NULL) return;
   1.875 -    
   1.876 -    //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
   1.877 -    //           (int)event->tfinger.y,
   1.878 -    //   (int)inTouch->res.x,(int)inTouch->res.y);
   1.879 +    if(event->type == SDL_FINGERMOTION ||
   1.880 +       event->type == SDL_FINGERDOWN ||
   1.881 +       event->type == SDL_FINGERUP) {
   1.882 +        SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
   1.883  
   1.884 -    
   1.885 -    x = ((float)event->tfinger.x)/(float)inTouch->res.x;
   1.886 -    y = ((float)event->tfinger.y)/(float)inTouch->res.y;   
   1.887 +        //Shouldn't be possible
   1.888 +        if(inTouch == NULL) return;
   1.889  
   1.890 +        //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
   1.891 +        //           (int)event->tfinger.y,
   1.892 +        //   (int)inTouch->res.x,(int)inTouch->res.y);
   1.893  
   1.894 -    //Finger Up
   1.895 -    if(event->type == SDL_FINGERUP) {
   1.896 -      inTouch->numDownFingers--;
   1.897 -      
   1.898 -#ifdef ENABLE_DOLLAR
   1.899 -      if(inTouch->recording) {
   1.900 -        inTouch->recording = SDL_FALSE;        
   1.901 -        dollarNormalize(&inTouch->dollarPath,path);
   1.902 -        //PrintPath(path);
   1.903 -        if(recordAll) {
   1.904 -          index = SDL_AddDollarGesture(NULL,path);
   1.905 -          for(i = 0;i < SDL_numGestureTouches; i++)
   1.906 -            SDL_gestureTouch[i].recording = SDL_FALSE;
   1.907 -        }
   1.908 -        else {
   1.909 -          index = SDL_AddDollarGesture(inTouch,path);
   1.910 -        }
   1.911 -        
   1.912 -        if(index >= 0) {
   1.913 -          SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
   1.914 -        }
   1.915 -        else {
   1.916 -          SDL_SendDollarRecord(inTouch,-1);
   1.917 -        }
   1.918 -      }
   1.919 -      else {        
   1.920 -        int bestTempl;
   1.921 -        float error;
   1.922 -        error = dollarRecognize(&inTouch->dollarPath,
   1.923 -                                &bestTempl,inTouch);
   1.924 -        if(bestTempl >= 0){
   1.925 -          //Send Event
   1.926 -          unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
   1.927 -          SDL_SendGestureDollar(inTouch,gestureId,error);
   1.928 -          //printf ("%s\n",);("Dollar error: %f\n",error);
   1.929 -        }
   1.930 -      }
   1.931 -#endif 
   1.932 -      //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
   1.933 -      if(inTouch->numDownFingers > 0) {
   1.934 -        inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
   1.935 -                               x)/inTouch->numDownFingers;
   1.936 -        inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
   1.937 -                               y)/inTouch->numDownFingers;
   1.938 -      }
   1.939 -    }
   1.940 -    else if(event->type == SDL_FINGERMOTION) {
   1.941 -      float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
   1.942 -      float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
   1.943 -      //printf("dx,dy: (%f,%f)\n",dx,dy); 
   1.944 -#ifdef ENABLE_DOLLAR
   1.945 -      SDL_DollarPath* path = &inTouch->dollarPath;
   1.946 -      if(path->numPoints < MAXPATHSIZE) {
   1.947 -        path->p[path->numPoints].x = inTouch->centroid.x;
   1.948 -        path->p[path->numPoints].y = inTouch->centroid.y;
   1.949 -        pathDx = 
   1.950 -          (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
   1.951 -        pathDy = 
   1.952 -          (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
   1.953 -        path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
   1.954 -        path->numPoints++;
   1.955 -      }
   1.956 -#endif
   1.957 -      lastP.x = x - dx;
   1.958 -      lastP.y = y - dy;
   1.959 -      lastCentroid = inTouch->centroid;
   1.960 -      
   1.961 -      inTouch->centroid.x += dx/inTouch->numDownFingers;
   1.962 -      inTouch->centroid.y += dy/inTouch->numDownFingers;
   1.963 -      //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
   1.964 -      if(inTouch->numDownFingers > 1) {
   1.965 -        SDL_FloatPoint lv; //Vector from centroid to last x,y position
   1.966 -        SDL_FloatPoint v; //Vector from centroid to current x,y position
   1.967 -        //lv = inTouch->gestureLast[j].cv;
   1.968 -        lv.x = lastP.x - lastCentroid.x;
   1.969 -        lv.y = lastP.y - lastCentroid.y;
   1.970 -        lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
   1.971 -        //printf("lDist = %f\n",lDist);
   1.972 -        v.x = x - inTouch->centroid.x;
   1.973 -        v.y = y - inTouch->centroid.y;
   1.974 -        //inTouch->gestureLast[j].cv = v;
   1.975 -        Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
   1.976 -        // SDL_cos(dTheta) = (v . lv)/(|v| * |lv|)
   1.977 -        
   1.978 -        //Normalize Vectors to simplify angle calculation
   1.979 -        lv.x/=lDist;
   1.980 -        lv.y/=lDist;
   1.981 -        v.x/=Dist;
   1.982 -        v.y/=Dist;
   1.983 -        dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
   1.984 -        
   1.985 -        dDist = (Dist - lDist);
   1.986 -        if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
   1.987 -        
   1.988 -        //inTouch->gestureLast[j].dDist = dDist;
   1.989 -        //inTouch->gestureLast[j].dtheta = dtheta;
   1.990 -        
   1.991 -        //printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
   1.992 -        //gdtheta = gdtheta*.9 + dtheta*.1;
   1.993 -        //gdDist  =  gdDist*.9 +  dDist*.1
   1.994 -        //knob.r += dDist/numDownFingers;
   1.995 -        //knob.ang += dtheta;
   1.996 -        //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
   1.997 -        //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
   1.998 -        SDL_SendGestureMulti(inTouch,dtheta,dDist);
   1.999 -      }
  1.1000 -      else {
  1.1001 -        //inTouch->gestureLast[j].dDist = 0;
  1.1002 -        //inTouch->gestureLast[j].dtheta = 0;
  1.1003 -        //inTouch->gestureLast[j].cv.x = 0;
  1.1004 -        //inTouch->gestureLast[j].cv.y = 0;
  1.1005 -      }
  1.1006 -      //inTouch->gestureLast[j].f.p.x = x;
  1.1007 -      //inTouch->gestureLast[j].f.p.y = y;
  1.1008 -      //break;
  1.1009 -      //pressure?
  1.1010 -    }
  1.1011 -    
  1.1012 -    if(event->type == SDL_FINGERDOWN) {
  1.1013  
  1.1014 -      inTouch->numDownFingers++;
  1.1015 -      inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ 
  1.1016 -                             x)/inTouch->numDownFingers;
  1.1017 -      inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
  1.1018 -                             y)/inTouch->numDownFingers;
  1.1019 -      //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
  1.1020 -      //     inTouch->centroid.x,inTouch->centroid.y);
  1.1021 +        x = ((float)event->tfinger.x)/(float)inTouch->res.x;
  1.1022 +        y = ((float)event->tfinger.y)/(float)inTouch->res.y;
  1.1023 +
  1.1024 +
  1.1025 +        //Finger Up
  1.1026 +        if(event->type == SDL_FINGERUP) {
  1.1027 +            inTouch->numDownFingers--;
  1.1028  
  1.1029  #ifdef ENABLE_DOLLAR
  1.1030 -      inTouch->dollarPath.length = 0;
  1.1031 -      inTouch->dollarPath.p[0].x = x;
  1.1032 -      inTouch->dollarPath.p[0].y = y;
  1.1033 -      inTouch->dollarPath.numPoints = 1;
  1.1034 +            if(inTouch->recording) {
  1.1035 +                inTouch->recording = SDL_FALSE;
  1.1036 +                dollarNormalize(&inTouch->dollarPath,path);
  1.1037 +                //PrintPath(path);
  1.1038 +                if(recordAll) {
  1.1039 +                    index = SDL_AddDollarGesture(NULL,path);
  1.1040 +                    for(i = 0;i < SDL_numGestureTouches; i++)
  1.1041 +                        SDL_gestureTouch[i].recording = SDL_FALSE;
  1.1042 +                }
  1.1043 +                else {
  1.1044 +                    index = SDL_AddDollarGesture(inTouch,path);
  1.1045 +                }
  1.1046 +
  1.1047 +                if(index >= 0) {
  1.1048 +                    SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
  1.1049 +                }
  1.1050 +                else {
  1.1051 +                    SDL_SendDollarRecord(inTouch,-1);
  1.1052 +                }
  1.1053 +            }
  1.1054 +            else {
  1.1055 +                int bestTempl;
  1.1056 +                float error;
  1.1057 +                error = dollarRecognize(&inTouch->dollarPath,
  1.1058 +                                        &bestTempl,inTouch);
  1.1059 +                if(bestTempl >= 0){
  1.1060 +                    //Send Event
  1.1061 +                    unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
  1.1062 +                    SDL_SendGestureDollar(inTouch,gestureId,error);
  1.1063 +                    //printf ("%s\n",);("Dollar error: %f\n",error);
  1.1064 +                }
  1.1065 +            }
  1.1066  #endif
  1.1067 +            //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
  1.1068 +            if(inTouch->numDownFingers > 0) {
  1.1069 +                inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
  1.1070 +                                       x)/inTouch->numDownFingers;
  1.1071 +                inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
  1.1072 +                                       y)/inTouch->numDownFingers;
  1.1073 +            }
  1.1074 +        }
  1.1075 +        else if(event->type == SDL_FINGERMOTION) {
  1.1076 +            float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
  1.1077 +            float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
  1.1078 +            //printf("dx,dy: (%f,%f)\n",dx,dy);
  1.1079 +#ifdef ENABLE_DOLLAR
  1.1080 +            SDL_DollarPath* path = &inTouch->dollarPath;
  1.1081 +            if(path->numPoints < MAXPATHSIZE) {
  1.1082 +                path->p[path->numPoints].x = inTouch->centroid.x;
  1.1083 +                path->p[path->numPoints].y = inTouch->centroid.y;
  1.1084 +                pathDx =
  1.1085 +                    (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
  1.1086 +                pathDy =
  1.1087 +                    (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
  1.1088 +                path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
  1.1089 +                path->numPoints++;
  1.1090 +            }
  1.1091 +#endif
  1.1092 +            lastP.x = x - dx;
  1.1093 +            lastP.y = y - dy;
  1.1094 +            lastCentroid = inTouch->centroid;
  1.1095 +
  1.1096 +            inTouch->centroid.x += dx/inTouch->numDownFingers;
  1.1097 +            inTouch->centroid.y += dy/inTouch->numDownFingers;
  1.1098 +            //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
  1.1099 +            if(inTouch->numDownFingers > 1) {
  1.1100 +                SDL_FloatPoint lv; //Vector from centroid to last x,y position
  1.1101 +                SDL_FloatPoint v; //Vector from centroid to current x,y position
  1.1102 +                //lv = inTouch->gestureLast[j].cv;
  1.1103 +                lv.x = lastP.x - lastCentroid.x;
  1.1104 +                lv.y = lastP.y - lastCentroid.y;
  1.1105 +                lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
  1.1106 +                //printf("lDist = %f\n",lDist);
  1.1107 +                v.x = x - inTouch->centroid.x;
  1.1108 +                v.y = y - inTouch->centroid.y;
  1.1109 +                //inTouch->gestureLast[j].cv = v;
  1.1110 +                Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
  1.1111 +                // SDL_cos(dTheta) = (v . lv)/(|v| * |lv|)
  1.1112 +
  1.1113 +                //Normalize Vectors to simplify angle calculation
  1.1114 +                lv.x/=lDist;
  1.1115 +                lv.y/=lDist;
  1.1116 +                v.x/=Dist;
  1.1117 +                v.y/=Dist;
  1.1118 +                dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
  1.1119 +
  1.1120 +                dDist = (Dist - lDist);
  1.1121 +                if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
  1.1122 +
  1.1123 +                //inTouch->gestureLast[j].dDist = dDist;
  1.1124 +                //inTouch->gestureLast[j].dtheta = dtheta;
  1.1125 +
  1.1126 +                //printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
  1.1127 +                //gdtheta = gdtheta*.9 + dtheta*.1;
  1.1128 +                //gdDist  =  gdDist*.9 +  dDist*.1
  1.1129 +                //knob.r += dDist/numDownFingers;
  1.1130 +                //knob.ang += dtheta;
  1.1131 +                //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
  1.1132 +                //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
  1.1133 +                SDL_SendGestureMulti(inTouch,dtheta,dDist);
  1.1134 +            }
  1.1135 +            else {
  1.1136 +                //inTouch->gestureLast[j].dDist = 0;
  1.1137 +                //inTouch->gestureLast[j].dtheta = 0;
  1.1138 +                //inTouch->gestureLast[j].cv.x = 0;
  1.1139 +                //inTouch->gestureLast[j].cv.y = 0;
  1.1140 +            }
  1.1141 +            //inTouch->gestureLast[j].f.p.x = x;
  1.1142 +            //inTouch->gestureLast[j].f.p.y = y;
  1.1143 +            //break;
  1.1144 +            //pressure?
  1.1145 +        }
  1.1146 +
  1.1147 +        if(event->type == SDL_FINGERDOWN) {
  1.1148 +
  1.1149 +            inTouch->numDownFingers++;
  1.1150 +            inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+
  1.1151 +                                   x)/inTouch->numDownFingers;
  1.1152 +            inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
  1.1153 +                                   y)/inTouch->numDownFingers;
  1.1154 +            //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
  1.1155 +            //     inTouch->centroid.x,inTouch->centroid.y);
  1.1156 +
  1.1157 +#ifdef ENABLE_DOLLAR
  1.1158 +            inTouch->dollarPath.length = 0;
  1.1159 +            inTouch->dollarPath.p[0].x = x;
  1.1160 +            inTouch->dollarPath.p[0].y = y;
  1.1161 +            inTouch->dollarPath.numPoints = 1;
  1.1162 +#endif
  1.1163 +        }
  1.1164      }
  1.1165 -  }
  1.1166  }
  1.1167  
  1.1168 -  /* vi: set ts=4 sw=4 expandtab: */
  1.1169 -  
  1.1170 +/* vi: set ts=4 sw=4 expandtab: */