src/events/SDL_gesture.c
changeset 6070 69b6275bb5dc
parent 6044 35448a5ea044
parent 6069 fbb37897c788
child 6071 72f06ae88e7e
     1.1 --- a/src/events/SDL_gesture.c	Tue Nov 08 00:17:41 2011 -0500
     1.2 +++ b/src/events/SDL_gesture.c	Tue Nov 08 16:24:02 2011 -0500
     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_TouchID 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,573 +80,584 @@
    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 -static 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 +static 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_one(SDL_GestureTouch* inTouch, SDL_FloatPoint* path)
   1.230 +{
   1.231 +    SDL_DollarTemplate* dollarTemplate;
   1.232 +    SDL_DollarTemplate *templ;
   1.233 +    int index;
   1.234  
   1.235 -    dollarTemplate = 
   1.236 +    index = inTouch->numDollarTemplates;
   1.237 +    dollarTemplate =
   1.238          (SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
   1.239 -                    (inTouch->numDollarTemplates + 1) * 
   1.240 -                    sizeof(SDL_DollarTemplate));
   1.241 -      if(!dollarTemplate) {
   1.242 +                                          (index + 1) *
   1.243 +                                          sizeof(SDL_DollarTemplate));
   1.244 +    if (!dollarTemplate) {
   1.245          SDL_OutOfMemory();
   1.246          return -1;
   1.247 -      }
   1.248 -        
   1.249 -      inTouch->dollarTemplate = dollarTemplate;
   1.250 -
   1.251 -    templ = 
   1.252 -        &inTouch->dollarTemplate[inTouch->numDollarTemplates];
   1.253 -      SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   1.254 -      templ->hash = SDL_HashDollar(templ->path);
   1.255 -      inTouch->numDollarTemplates++;    
   1.256      }
   1.257 -    return inTouch->numDollarTemplates - 1;
   1.258 -  } else {
   1.259 -    SDL_DollarTemplate* dollarTemplate = 
   1.260 -      ( SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
   1.261 -                  (inTouch->numDollarTemplates + 1) * 
   1.262 -                  sizeof(SDL_DollarTemplate));
   1.263 -    if(!dollarTemplate) {
   1.264 -      SDL_OutOfMemory();
   1.265 -      return -1;
   1.266 -    }
   1.267 -    
   1.268      inTouch->dollarTemplate = dollarTemplate;
   1.269  
   1.270 -    templ = 
   1.271 -      &inTouch->dollarTemplate[inTouch->numDollarTemplates];
   1.272 -    SDL_memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   1.273 +    templ = &inTouch->dollarTemplate[index];
   1.274 +    SDL_memcpy(templ->path, path, DOLLARNPOINTS*sizeof(SDL_FloatPoint));
   1.275      templ->hash = SDL_HashDollar(templ->path);
   1.276      inTouch->numDollarTemplates++;
   1.277 -    return inTouch->numDollarTemplates - 1;
   1.278 -  }
   1.279 -  return -1;
   1.280 +
   1.281 +    return index;
   1.282  }
   1.283  
   1.284 -int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) {
   1.285 -  int i,loaded = 0;
   1.286 -  SDL_GestureTouch *touch = NULL;
   1.287 -  if(src == NULL) return 0;
   1.288 -  if(touchId >= 0) {
   1.289 -    for(i = 0;i < SDL_numGestureTouches; i++)
   1.290 -      if(SDL_gestureTouch[i].id == touchId)
   1.291 -        touch = &SDL_gestureTouch[i];
   1.292 -    if(touch == NULL) return -1;
   1.293 -  }
   1.294 -
   1.295 -  while(1) {
   1.296 -    SDL_DollarTemplate templ;
   1.297 -
   1.298 -    if(SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) < 
   1.299 -       DOLLARNPOINTS) break;
   1.300 -
   1.301 -    if(touchId >= 0) {
   1.302 -      //printf("Adding loaded gesture to 1 touch\n");
   1.303 -      if(SDL_AddDollarGesture(touch,templ.path)) loaded++;
   1.304 +static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch, SDL_FloatPoint* path)
   1.305 +{
   1.306 +    int index;
   1.307 +    int i = 0;
   1.308 +    if (inTouch == NULL) {
   1.309 +        if (SDL_numGestureTouches == 0) return -1;
   1.310 +        for (i = 0; i < SDL_numGestureTouches; i++) {
   1.311 +            inTouch = &SDL_gestureTouch[i];
   1.312 +            index = SDL_AddDollarGesture_one(inTouch, path);
   1.313 +            if (index < 0)
   1.314 +                return -1;
   1.315 +        }
   1.316 +        // Use the index of the last one added.
   1.317 +        return index;
   1.318 +    } else {
   1.319 +        return SDL_AddDollarGesture_one(inTouch, path);
   1.320      }
   1.321 -    else {
   1.322 -      //printf("Adding to: %i touches\n",SDL_numGestureTouches);
   1.323 -      for(i = 0;i < SDL_numGestureTouches; i++) {
   1.324 -        touch = &SDL_gestureTouch[i];
   1.325 -        //printf("Adding loaded gesture to + touches\n");
   1.326 -        //TODO: What if this fails?
   1.327 -        SDL_AddDollarGesture(touch,templ.path);        
   1.328 -      }
   1.329 -      loaded++;
   1.330 -    }
   1.331 -  }
   1.332 -
   1.333 -  return loaded; 
   1.334 +    return -1;
   1.335  }
   1.336  
   1.337 +int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src)
   1.338 +{
   1.339 +    int i,loaded = 0;
   1.340 +    SDL_GestureTouch *touch = NULL;
   1.341 +    if (src == NULL) return 0;
   1.342 +    if (touchId >= 0) {
   1.343 +        for (i = 0; i < SDL_numGestureTouches; i++)
   1.344 +            if (SDL_gestureTouch[i].id == touchId)
   1.345 +                touch = &SDL_gestureTouch[i];
   1.346 +        if (touch == NULL) return -1;
   1.347 +    }
   1.348  
   1.349 -static float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang) {
   1.350 -  //  SDL_FloatPoint p[DOLLARNPOINTS];
   1.351 -  float dist = 0;
   1.352 -  SDL_FloatPoint p;
   1.353 -  int i;
   1.354 -  for(i = 0; i < DOLLARNPOINTS; i++) {
   1.355 -    p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang));
   1.356 -    p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang));
   1.357 -    dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
   1.358 -                 (p.y-templ[i].y)*(p.y-templ[i].y)));
   1.359 -  }
   1.360 -  return dist/DOLLARNPOINTS;
   1.361 -  
   1.362 +    while (1) {
   1.363 +        SDL_DollarTemplate templ;
   1.364 +
   1.365 +        if (SDL_RWread(src,templ.path,sizeof(templ.path[0]),DOLLARNPOINTS) <
   1.366 +           DOLLARNPOINTS) break;
   1.367 +
   1.368 +        if (touchId >= 0) {
   1.369 +            //printf("Adding loaded gesture to 1 touch\n");
   1.370 +            if (SDL_AddDollarGesture(touch, templ.path) >= 0)
   1.371 +                loaded++;
   1.372 +        }
   1.373 +        else {
   1.374 +            //printf("Adding to: %i touches\n",SDL_numGestureTouches);
   1.375 +            for (i = 0; i < SDL_numGestureTouches; i++) {
   1.376 +                touch = &SDL_gestureTouch[i];
   1.377 +                //printf("Adding loaded gesture to + touches\n");
   1.378 +                //TODO: What if this fails?
   1.379 +                SDL_AddDollarGesture(touch,templ.path);
   1.380 +            }
   1.381 +            loaded++;
   1.382 +        }
   1.383 +    }
   1.384 +
   1.385 +    return loaded;
   1.386  }
   1.387  
   1.388 -static float bestDollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ) {
   1.389 -  //------------BEGIN DOLLAR BLACKBOX----------------//
   1.390 -  //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
   1.391 -  //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
   1.392 -  double ta = -M_PI/4;
   1.393 -  double tb = M_PI/4;
   1.394 -  double dt = M_PI/90;
   1.395 -  float x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.396 -  float f1 = dollarDifference(points,templ,x1);
   1.397 -  float x2 = (float)((1-PHI)*ta + PHI*tb);
   1.398 -  float f2 = dollarDifference(points,templ,x2);
   1.399 -  while(SDL_fabs(ta-tb) > dt) {
   1.400 -    if(f1 < f2) {
   1.401 -      tb = x2;
   1.402 -      x2 = x1;
   1.403 -      f2 = f1;
   1.404 -      x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.405 -      f1 = dollarDifference(points,templ,x1);
   1.406 +
   1.407 +static float dollarDifference(SDL_FloatPoint* points,SDL_FloatPoint* templ,float ang)
   1.408 +{
   1.409 +    //  SDL_FloatPoint p[DOLLARNPOINTS];
   1.410 +    float dist = 0;
   1.411 +    SDL_FloatPoint p;
   1.412 +    int i;
   1.413 +    for (i = 0; i < DOLLARNPOINTS; i++) {
   1.414 +        p.x = (float)(points[i].x * SDL_cos(ang) - points[i].y * SDL_sin(ang));
   1.415 +        p.y = (float)(points[i].x * SDL_sin(ang) + points[i].y * SDL_cos(ang));
   1.416 +        dist += (float)(SDL_sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
   1.417 +                                 (p.y-templ[i].y)*(p.y-templ[i].y)));
   1.418      }
   1.419 -    else {
   1.420 -      ta = x1;
   1.421 -      x1 = x2;
   1.422 -      f1 = f2;
   1.423 -      x2 = (float)((1-PHI)*ta + PHI*tb);
   1.424 -      f2 = dollarDifference(points,templ,x2);
   1.425 +    return dist/DOLLARNPOINTS;
   1.426 +
   1.427 +}
   1.428 +
   1.429 +static 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 -  }
   1.458 -  /*
   1.459 -  if(f1 <= f2)
   1.460 -    printf("Min angle (x1): %f\n",x1);
   1.461 -  else if(f1 >  f2)
   1.462 -    printf("Min angle (x2): %f\n",x2);
   1.463 -  */
   1.464 -  return SDL_min(f1,f2);  
   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  
   1.474  //DollarPath contains raw points, plus (possibly) the calculated length
   1.475 -static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points) {
   1.476 -  int i;
   1.477 -  float interval;
   1.478 -  float dist;
   1.479 -  int numPoints = 0;
   1.480 -  SDL_FloatPoint centroid; 
   1.481 -  float xmin,xmax,ymin,ymax;
   1.482 -  float ang;
   1.483 -  float w,h;
   1.484 -  float length = path->length;
   1.485 +static int dollarNormalize(const SDL_DollarPath *path,SDL_FloatPoint *points)
   1.486 +{
   1.487 +    int i;
   1.488 +    float interval;
   1.489 +    float dist;
   1.490 +    int numPoints = 0;
   1.491 +    SDL_FloatPoint centroid;
   1.492 +    float xmin,xmax,ymin,ymax;
   1.493 +    float ang;
   1.494 +    float w,h;
   1.495 +    float length = path->length;
   1.496  
   1.497 -  //Calculate length if it hasn't already been done
   1.498 -  if(length <= 0) {
   1.499 -    for(i=1;i<path->numPoints;i++) {
   1.500 -      float dx = path->p[i  ].x - 
   1.501 -                 path->p[i-1].x;
   1.502 -      float dy = path->p[i  ].y - 
   1.503 -                 path->p[i-1].y;
   1.504 -      length += (float)(SDL_sqrt(dx*dx+dy*dy));
   1.505 +    //Calculate length if it hasn't already been done
   1.506 +    if (length <= 0) {
   1.507 +        for (i=1;i < path->numPoints; i++) {
   1.508 +            float dx = path->p[i  ].x - path->p[i-1].x;
   1.509 +            float dy = path->p[i  ].y - path->p[i-1].y;
   1.510 +            length += (float)(SDL_sqrt(dx*dx+dy*dy));
   1.511 +        }
   1.512      }
   1.513 -  }
   1.514  
   1.515 -  //Resample
   1.516 -  interval = length/(DOLLARNPOINTS - 1);
   1.517 -  dist = interval;
   1.518 +    //Resample
   1.519 +    interval = length/(DOLLARNPOINTS - 1);
   1.520 +    dist = interval;
   1.521  
   1.522 -  centroid.x = 0;centroid.y = 0;
   1.523 -  
   1.524 -  //printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y);
   1.525 -  for(i = 1;i < path->numPoints;i++) {
   1.526 -    float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+
   1.527 -                             (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y)));
   1.528 -    //printf("d = %f dist = %f/%f\n",d,dist,interval);
   1.529 -    while(dist + d > interval) {
   1.530 -      points[numPoints].x = path->p[i-1].x + 
   1.531 -        ((interval-dist)/d)*(path->p[i].x-path->p[i-1].x);
   1.532 -      points[numPoints].y = path->p[i-1].y + 
   1.533 -        ((interval-dist)/d)*(path->p[i].y-path->p[i-1].y);
   1.534 -      centroid.x += points[numPoints].x;
   1.535 -      centroid.y += points[numPoints].y;
   1.536 -      numPoints++;
   1.537 +    centroid.x = 0;centroid.y = 0;
   1.538  
   1.539 -      dist -= interval;
   1.540 +    //printf("(%f,%f)\n",path->p[path->numPoints-1].x,path->p[path->numPoints-1].y);
   1.541 +    for (i = 1; i < path->numPoints; i++) {
   1.542 +        float d = (float)(SDL_sqrt((path->p[i-1].x-path->p[i].x)*(path->p[i-1].x-path->p[i].x)+
   1.543 +                                   (path->p[i-1].y-path->p[i].y)*(path->p[i-1].y-path->p[i].y)));
   1.544 +        //printf("d = %f dist = %f/%f\n",d,dist,interval);
   1.545 +        while (dist + d > interval) {
   1.546 +            points[numPoints].x = path->p[i-1].x +
   1.547 +                ((interval-dist)/d)*(path->p[i].x-path->p[i-1].x);
   1.548 +            points[numPoints].y = path->p[i-1].y +
   1.549 +                ((interval-dist)/d)*(path->p[i].y-path->p[i-1].y);
   1.550 +            centroid.x += points[numPoints].x;
   1.551 +            centroid.y += points[numPoints].y;
   1.552 +            numPoints++;
   1.553 +
   1.554 +            dist -= interval;
   1.555 +        }
   1.556 +        dist += d;
   1.557      }
   1.558 -    dist += d;
   1.559 -  }
   1.560 -  if(numPoints < DOLLARNPOINTS-1) {
   1.561 -    SDL_SetError("ERROR: NumPoints = %i\n",numPoints); 
   1.562 -    return 0;
   1.563 -  }
   1.564 -  //copy the last point
   1.565 -  points[DOLLARNPOINTS-1] = path->p[path->numPoints-1];
   1.566 -  numPoints = DOLLARNPOINTS;
   1.567 +    if (numPoints < DOLLARNPOINTS-1) {
   1.568 +        SDL_SetError("ERROR: NumPoints = %i\n",numPoints);
   1.569 +        return 0;
   1.570 +    }
   1.571 +    //copy the last point
   1.572 +    points[DOLLARNPOINTS-1] = path->p[path->numPoints-1];
   1.573 +    numPoints = DOLLARNPOINTS;
   1.574  
   1.575 -  centroid.x /= numPoints;
   1.576 -  centroid.y /= numPoints;
   1.577 - 
   1.578 -  //printf("Centroid (%f,%f)",centroid.x,centroid.y);
   1.579 -  //Rotate Points so point 0 is left of centroid and solve for the bounding box
   1.580 -  xmin = centroid.x;
   1.581 -  xmax = centroid.x;
   1.582 -  ymin = centroid.y;
   1.583 -  ymax = centroid.y;
   1.584 -  
   1.585 -  ang = (float)(SDL_atan2(centroid.y - points[0].y,
   1.586 -                    centroid.x - points[0].x));
   1.587 +    centroid.x /= numPoints;
   1.588 +    centroid.y /= numPoints;
   1.589  
   1.590 -  for(i = 0;i<numPoints;i++) {                                               
   1.591 -    float px = points[i].x;
   1.592 -    float py = points[i].y;
   1.593 -    points[i].x = (float)((px - centroid.x)*SDL_cos(ang) - 
   1.594 -                  (py - centroid.y)*SDL_sin(ang) + centroid.x);
   1.595 -    points[i].y = (float)((px - centroid.x)*SDL_sin(ang) + 
   1.596 -                  (py - centroid.y)*SDL_cos(ang) + centroid.y);
   1.597 +    //printf("Centroid (%f,%f)",centroid.x,centroid.y);
   1.598 +    //Rotate Points so point 0 is left of centroid and solve for the bounding box
   1.599 +    xmin = centroid.x;
   1.600 +    xmax = centroid.x;
   1.601 +    ymin = centroid.y;
   1.602 +    ymax = centroid.y;
   1.603  
   1.604 +    ang = (float)(SDL_atan2(centroid.y - points[0].y,
   1.605 +                            centroid.x - points[0].x));
   1.606  
   1.607 -    if(points[i].x < xmin) xmin = points[i].x;
   1.608 -    if(points[i].x > xmax) xmax = points[i].x; 
   1.609 -    if(points[i].y < ymin) ymin = points[i].y;
   1.610 -    if(points[i].y > ymax) ymax = points[i].y;
   1.611 -  }
   1.612 +    for (i = 0; i<numPoints; i++) {
   1.613 +        float px = points[i].x;
   1.614 +        float py = points[i].y;
   1.615 +        points[i].x = (float)((px - centroid.x)*SDL_cos(ang) -
   1.616 +                              (py - centroid.y)*SDL_sin(ang) + centroid.x);
   1.617 +        points[i].y = (float)((px - centroid.x)*SDL_sin(ang) +
   1.618 +                              (py - centroid.y)*SDL_cos(ang) + centroid.y);
   1.619  
   1.620 -  //Scale points to DOLLARSIZE, and translate to the origin
   1.621 -  w = xmax-xmin;
   1.622 -  h = ymax-ymin;
   1.623  
   1.624 -  for(i=0;i<numPoints;i++) {
   1.625 -    points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
   1.626 -    points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
   1.627 -  }  
   1.628 -  return numPoints;
   1.629 +        if (points[i].x < xmin) xmin = points[i].x;
   1.630 +        if (points[i].x > xmax) xmax = points[i].x;
   1.631 +        if (points[i].y < ymin) ymin = points[i].y;
   1.632 +        if (points[i].y > ymax) ymax = points[i].y;
   1.633 +    }
   1.634 +
   1.635 +    //Scale points to DOLLARSIZE, and translate to the origin
   1.636 +    w = xmax-xmin;
   1.637 +    h = ymax-ymin;
   1.638 +
   1.639 +    for (i=0; i<numPoints; i++) {
   1.640 +        points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
   1.641 +        points[i].y = (points[i].y - centroid.y)*DOLLARSIZE/h;
   1.642 +    }
   1.643 +    return numPoints;
   1.644  }
   1.645  
   1.646 -static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch) {
   1.647 -        
   1.648 -        SDL_FloatPoint points[DOLLARNPOINTS];
   1.649 -        int i;
   1.650 -        float bestDiff = 10000;
   1.651 +static float dollarRecognize(const SDL_DollarPath *path,int *bestTempl,SDL_GestureTouch* touch)
   1.652 +{
   1.653  
   1.654 -        dollarNormalize(path,points);
   1.655 +    SDL_FloatPoint points[DOLLARNPOINTS];
   1.656 +    int i;
   1.657 +    float bestDiff = 10000;
   1.658  
   1.659 -        //PrintPath(points);
   1.660 -        *bestTempl = -1;
   1.661 -        for(i = 0;i < touch->numDollarTemplates;i++) {
   1.662 -                float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
   1.663 -                if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
   1.664 -        }
   1.665 -        return bestDiff;
   1.666 +    dollarNormalize(path,points);
   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  }
   1.676  
   1.677 -int SDL_GestureAddTouch(SDL_Touch* touch) {  
   1.678 -  SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
   1.679 -                                               (SDL_numGestureTouches + 1) *
   1.680 -                                               sizeof(SDL_GestureTouch));
   1.681 +int SDL_GestureAddTouch(SDL_Touch* touch)
   1.682 +{
   1.683 +    SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
   1.684 +                                                                     (SDL_numGestureTouches + 1) *
   1.685 +                                                                     sizeof(SDL_GestureTouch));
   1.686  
   1.687 -  if(!gestureTouch) {
   1.688 -    SDL_OutOfMemory();
   1.689 -    return -1;
   1.690 -  }
   1.691 +    if (!gestureTouch) {
   1.692 +        SDL_OutOfMemory();
   1.693 +        return -1;
   1.694 +    }
   1.695  
   1.696 -  SDL_gestureTouch = gestureTouch;
   1.697 +    SDL_gestureTouch = gestureTouch;
   1.698  
   1.699 -  SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.700 -  SDL_gestureTouch[SDL_numGestureTouches].res.y = touch->yres;
   1.701 -  SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0;
   1.702 +    SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.703 +    SDL_gestureTouch[SDL_numGestureTouches].res.y = touch->yres;
   1.704 +    SDL_gestureTouch[SDL_numGestureTouches].numDownFingers = 0;
   1.705  
   1.706 -  SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.707 -  SDL_gestureTouch[SDL_numGestureTouches].id = touch->id;
   1.708 +    SDL_gestureTouch[SDL_numGestureTouches].res.x = touch->xres;
   1.709 +    SDL_gestureTouch[SDL_numGestureTouches].id = touch->id;
   1.710  
   1.711 -  SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0;
   1.712 +    SDL_gestureTouch[SDL_numGestureTouches].numDollarTemplates = 0;
   1.713  
   1.714 -  SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE;
   1.715 +    SDL_gestureTouch[SDL_numGestureTouches].recording = SDL_FALSE;
   1.716  
   1.717 -  SDL_numGestureTouches++;
   1.718 -  return 0;
   1.719 +    SDL_numGestureTouches++;
   1.720 +    return 0;
   1.721  }
   1.722  
   1.723 -static SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id) {
   1.724 -  int i;
   1.725 -  for(i = 0;i < SDL_numGestureTouches; i++) {
   1.726 -    //printf("%i ?= %i\n",SDL_gestureTouch[i].id,id);
   1.727 -    if(SDL_gestureTouch[i].id == id) return &SDL_gestureTouch[i];
   1.728 -  }
   1.729 -  return NULL;
   1.730 +static SDL_GestureTouch * SDL_GetGestureTouch(SDL_TouchID id)
   1.731 +{
   1.732 +    int i;
   1.733 +    for (i = 0; i < SDL_numGestureTouches; i++) {
   1.734 +        //printf("%i ?= %i\n",SDL_gestureTouch[i].id,id);
   1.735 +        if (SDL_gestureTouch[i].id == id)
   1.736 +            return &SDL_gestureTouch[i];
   1.737 +    }
   1.738 +    return NULL;
   1.739  }
   1.740  
   1.741 -static int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist) {
   1.742 -  SDL_Event event;
   1.743 -  event.mgesture.type = SDL_MULTIGESTURE;
   1.744 -  event.mgesture.touchId = touch->id;
   1.745 -  event.mgesture.x = touch->centroid.x;
   1.746 -  event.mgesture.y = touch->centroid.y;
   1.747 -  event.mgesture.dTheta = dTheta;
   1.748 -  event.mgesture.dDist = dDist;  
   1.749 -  event.mgesture.numFingers = touch->numDownFingers;
   1.750 -  return SDL_PushEvent(&event) > 0;
   1.751 +int SDL_SendGestureMulti(SDL_GestureTouch* touch,float dTheta,float dDist)
   1.752 +{
   1.753 +    SDL_Event event;
   1.754 +    event.mgesture.type = SDL_MULTIGESTURE;
   1.755 +    event.mgesture.touchId = touch->id;
   1.756 +    event.mgesture.x = touch->centroid.x;
   1.757 +    event.mgesture.y = touch->centroid.y;
   1.758 +    event.mgesture.dTheta = dTheta;
   1.759 +    event.mgesture.dDist = dDist;
   1.760 +    event.mgesture.numFingers = touch->numDownFingers;
   1.761 +    return SDL_PushEvent(&event) > 0;
   1.762  }
   1.763  
   1.764  static int SDL_SendGestureDollar(SDL_GestureTouch* touch,
   1.765 -                          SDL_GestureID gestureId,float error) {
   1.766 -  SDL_Event event;
   1.767 -  event.dgesture.type = SDL_DOLLARGESTURE;
   1.768 -  event.dgesture.touchId = touch->id;
   1.769 -  /*
   1.770 +                          SDL_GestureID gestureId,float error)
   1.771 +{
   1.772 +    SDL_Event event;
   1.773 +    event.dgesture.type = SDL_DOLLARGESTURE;
   1.774 +    event.dgesture.touchId = touch->id;
   1.775 +    /*
   1.776      //TODO: Add this to give location of gesture?
   1.777 -  event.mgesture.x = touch->centroid.x;
   1.778 -  event.mgesture.y = touch->centroid.y;
   1.779 -  */
   1.780 -  event.dgesture.gestureId = gestureId;
   1.781 -  event.dgesture.error = error;  
   1.782 -  //A finger came up to trigger this event.
   1.783 -  event.dgesture.numFingers = touch->numDownFingers + 1; 
   1.784 -  return SDL_PushEvent(&event) > 0;
   1.785 +    event.mgesture.x = touch->centroid.x;
   1.786 +    event.mgesture.y = touch->centroid.y;
   1.787 +    */
   1.788 +    event.dgesture.gestureId = gestureId;
   1.789 +    event.dgesture.error = error;
   1.790 +    //A finger came up to trigger this event.
   1.791 +    event.dgesture.numFingers = touch->numDownFingers + 1;
   1.792 +    return SDL_PushEvent(&event) > 0;
   1.793  }
   1.794  
   1.795  
   1.796 -static int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId) {
   1.797 -  SDL_Event event;
   1.798 -  event.dgesture.type = SDL_DOLLARRECORD;
   1.799 -  event.dgesture.touchId = touch->id;
   1.800 -  event.dgesture.gestureId = gestureId;
   1.801 -  return SDL_PushEvent(&event) > 0;
   1.802 +static int SDL_SendDollarRecord(SDL_GestureTouch* touch,SDL_GestureID gestureId)
   1.803 +{
   1.804 +    SDL_Event event;
   1.805 +    event.dgesture.type = SDL_DOLLARRECORD;
   1.806 +    event.dgesture.touchId = touch->id;
   1.807 +    event.dgesture.gestureId = gestureId;
   1.808 +    return SDL_PushEvent(&event) > 0;
   1.809  }
   1.810  
   1.811  
   1.812  void SDL_GestureProcessEvent(SDL_Event* event)
   1.813  {
   1.814 -  float x,y; 
   1.815 -  SDL_FloatPoint path[DOLLARNPOINTS];
   1.816 -  int index;
   1.817 -  int i;
   1.818 -  float pathDx, pathDy;
   1.819 -  SDL_FloatPoint lastP;
   1.820 -  SDL_FloatPoint lastCentroid;
   1.821 -  float lDist;
   1.822 -  float Dist;
   1.823 -  float dtheta;
   1.824 -  float dDist;
   1.825 +    float x,y;
   1.826 +    SDL_FloatPoint path[DOLLARNPOINTS];
   1.827 +    int index;
   1.828 +    int i;
   1.829 +    float pathDx, pathDy;
   1.830 +    SDL_FloatPoint lastP;
   1.831 +    SDL_FloatPoint lastCentroid;
   1.832 +    float lDist;
   1.833 +    float Dist;
   1.834 +    float dtheta;
   1.835 +    float dDist;
   1.836  
   1.837 -  if(event->type == SDL_FINGERMOTION || 
   1.838 -     event->type == SDL_FINGERDOWN ||
   1.839 -     event->type == SDL_FINGERUP) {
   1.840 -    SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
   1.841 -    
   1.842 -    //Shouldn't be possible
   1.843 -    if(inTouch == NULL) return;
   1.844 -    
   1.845 -    //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
   1.846 -    //           (int)event->tfinger.y,
   1.847 -    //   (int)inTouch->res.x,(int)inTouch->res.y);
   1.848 +    if (event->type == SDL_FINGERMOTION ||
   1.849 +        event->type == SDL_FINGERDOWN ||
   1.850 +        event->type == SDL_FINGERUP) {
   1.851 +        SDL_GestureTouch* inTouch = SDL_GetGestureTouch(event->tfinger.touchId);
   1.852  
   1.853 -    
   1.854 -    x = ((float)event->tfinger.x)/(float)inTouch->res.x;
   1.855 -    y = ((float)event->tfinger.y)/(float)inTouch->res.y;   
   1.856 +        //Shouldn't be possible
   1.857 +        if (inTouch == NULL) return;
   1.858  
   1.859 +        //printf("@ (%i,%i) with res: (%i,%i)\n",(int)event->tfinger.x,
   1.860 +        //           (int)event->tfinger.y,
   1.861 +        //   (int)inTouch->res.x,(int)inTouch->res.y);
   1.862  
   1.863 -    //Finger Up
   1.864 -    if(event->type == SDL_FINGERUP) {
   1.865 -      inTouch->numDownFingers--;
   1.866 -      
   1.867 -#ifdef ENABLE_DOLLAR
   1.868 -      if(inTouch->recording) {
   1.869 -        inTouch->recording = SDL_FALSE;        
   1.870 -        dollarNormalize(&inTouch->dollarPath,path);
   1.871 -        //PrintPath(path);
   1.872 -        if(recordAll) {
   1.873 -          index = SDL_AddDollarGesture(NULL,path);
   1.874 -          for(i = 0;i < SDL_numGestureTouches; i++)
   1.875 -            SDL_gestureTouch[i].recording = SDL_FALSE;
   1.876 -        }
   1.877 -        else {
   1.878 -          index = SDL_AddDollarGesture(inTouch,path);
   1.879 -        }
   1.880 -        
   1.881 -        if(index >= 0) {
   1.882 -          SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
   1.883 -        }
   1.884 -        else {
   1.885 -          SDL_SendDollarRecord(inTouch,-1);
   1.886 -        }
   1.887 -      }
   1.888 -      else {        
   1.889 -        int bestTempl;
   1.890 -        float error;
   1.891 -        error = dollarRecognize(&inTouch->dollarPath,
   1.892 -                                &bestTempl,inTouch);
   1.893 -        if(bestTempl >= 0){
   1.894 -          //Send Event
   1.895 -          unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
   1.896 -          SDL_SendGestureDollar(inTouch,gestureId,error);
   1.897 -          //printf ("%s\n",);("Dollar error: %f\n",error);
   1.898 -        }
   1.899 -      }
   1.900 -#endif 
   1.901 -      //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
   1.902 -      if(inTouch->numDownFingers > 0) {
   1.903 -        inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
   1.904 -                               x)/inTouch->numDownFingers;
   1.905 -        inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
   1.906 -                               y)/inTouch->numDownFingers;
   1.907 -      }
   1.908 -    }
   1.909 -    else if(event->type == SDL_FINGERMOTION) {
   1.910 -      float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
   1.911 -      float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
   1.912 -      //printf("dx,dy: (%f,%f)\n",dx,dy); 
   1.913 -#ifdef ENABLE_DOLLAR
   1.914 -      SDL_DollarPath* path = &inTouch->dollarPath;
   1.915 -      if(path->numPoints < MAXPATHSIZE) {
   1.916 -        path->p[path->numPoints].x = inTouch->centroid.x;
   1.917 -        path->p[path->numPoints].y = inTouch->centroid.y;
   1.918 -        pathDx = 
   1.919 -          (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
   1.920 -        pathDy = 
   1.921 -          (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
   1.922 -        path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
   1.923 -        path->numPoints++;
   1.924 -      }
   1.925 -#endif
   1.926 -      lastP.x = x - dx;
   1.927 -      lastP.y = y - dy;
   1.928 -      lastCentroid = inTouch->centroid;
   1.929 -      
   1.930 -      inTouch->centroid.x += dx/inTouch->numDownFingers;
   1.931 -      inTouch->centroid.y += dy/inTouch->numDownFingers;
   1.932 -      //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
   1.933 -      if(inTouch->numDownFingers > 1) {
   1.934 -        SDL_FloatPoint lv; //Vector from centroid to last x,y position
   1.935 -        SDL_FloatPoint v; //Vector from centroid to current x,y position
   1.936 -        //lv = inTouch->gestureLast[j].cv;
   1.937 -        lv.x = lastP.x - lastCentroid.x;
   1.938 -        lv.y = lastP.y - lastCentroid.y;
   1.939 -        lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
   1.940 -        //printf("lDist = %f\n",lDist);
   1.941 -        v.x = x - inTouch->centroid.x;
   1.942 -        v.y = y - inTouch->centroid.y;
   1.943 -        //inTouch->gestureLast[j].cv = v;
   1.944 -        Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
   1.945 -        // SDL_cos(dTheta) = (v . lv)/(|v| * |lv|)
   1.946 -        
   1.947 -        //Normalize Vectors to simplify angle calculation
   1.948 -        lv.x/=lDist;
   1.949 -        lv.y/=lDist;
   1.950 -        v.x/=Dist;
   1.951 -        v.y/=Dist;
   1.952 -        dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
   1.953 -        
   1.954 -        dDist = (Dist - lDist);
   1.955 -        if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
   1.956 -        
   1.957 -        //inTouch->gestureLast[j].dDist = dDist;
   1.958 -        //inTouch->gestureLast[j].dtheta = dtheta;
   1.959 -        
   1.960 -        //printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
   1.961 -        //gdtheta = gdtheta*.9 + dtheta*.1;
   1.962 -        //gdDist  =  gdDist*.9 +  dDist*.1
   1.963 -        //knob.r += dDist/numDownFingers;
   1.964 -        //knob.ang += dtheta;
   1.965 -        //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
   1.966 -        //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
   1.967 -        SDL_SendGestureMulti(inTouch,dtheta,dDist);
   1.968 -      }
   1.969 -      else {
   1.970 -        //inTouch->gestureLast[j].dDist = 0;
   1.971 -        //inTouch->gestureLast[j].dtheta = 0;
   1.972 -        //inTouch->gestureLast[j].cv.x = 0;
   1.973 -        //inTouch->gestureLast[j].cv.y = 0;
   1.974 -      }
   1.975 -      //inTouch->gestureLast[j].f.p.x = x;
   1.976 -      //inTouch->gestureLast[j].f.p.y = y;
   1.977 -      //break;
   1.978 -      //pressure?
   1.979 -    }
   1.980 -    
   1.981 -    if(event->type == SDL_FINGERDOWN) {
   1.982  
   1.983 -      inTouch->numDownFingers++;
   1.984 -      inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+ 
   1.985 -                             x)/inTouch->numDownFingers;
   1.986 -      inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
   1.987 -                             y)/inTouch->numDownFingers;
   1.988 -      //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
   1.989 -      //     inTouch->centroid.x,inTouch->centroid.y);
   1.990 +        x = ((float)event->tfinger.x)/(float)inTouch->res.x;
   1.991 +        y = ((float)event->tfinger.y)/(float)inTouch->res.y;
   1.992 +
   1.993 +
   1.994 +        //Finger Up
   1.995 +        if (event->type == SDL_FINGERUP) {
   1.996 +            inTouch->numDownFingers--;
   1.997  
   1.998  #ifdef ENABLE_DOLLAR
   1.999 -      inTouch->dollarPath.length = 0;
  1.1000 -      inTouch->dollarPath.p[0].x = x;
  1.1001 -      inTouch->dollarPath.p[0].y = y;
  1.1002 -      inTouch->dollarPath.numPoints = 1;
  1.1003 +            if (inTouch->recording) {
  1.1004 +                inTouch->recording = SDL_FALSE;
  1.1005 +                dollarNormalize(&inTouch->dollarPath,path);
  1.1006 +                //PrintPath(path);
  1.1007 +                if (recordAll) {
  1.1008 +                    index = SDL_AddDollarGesture(NULL,path);
  1.1009 +                    for (i = 0; i < SDL_numGestureTouches; i++)
  1.1010 +                        SDL_gestureTouch[i].recording = SDL_FALSE;
  1.1011 +                }
  1.1012 +                else {
  1.1013 +                    index = SDL_AddDollarGesture(inTouch,path);
  1.1014 +                }
  1.1015 +
  1.1016 +                if (index >= 0) {
  1.1017 +                    SDL_SendDollarRecord(inTouch,inTouch->dollarTemplate[index].hash);
  1.1018 +                }
  1.1019 +                else {
  1.1020 +                    SDL_SendDollarRecord(inTouch,-1);
  1.1021 +                }
  1.1022 +            }
  1.1023 +            else {
  1.1024 +                int bestTempl;
  1.1025 +                float error;
  1.1026 +                error = dollarRecognize(&inTouch->dollarPath,
  1.1027 +                                        &bestTempl,inTouch);
  1.1028 +                if (bestTempl >= 0){
  1.1029 +                    //Send Event
  1.1030 +                    unsigned long gestureId = inTouch->dollarTemplate[bestTempl].hash;
  1.1031 +                    SDL_SendGestureDollar(inTouch,gestureId,error);
  1.1032 +                    //printf ("%s\n",);("Dollar error: %f\n",error);
  1.1033 +                }
  1.1034 +            }
  1.1035  #endif
  1.1036 +            //inTouch->gestureLast[j] = inTouch->gestureLast[inTouch->numDownFingers];
  1.1037 +            if (inTouch->numDownFingers > 0) {
  1.1038 +                inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers+1)-
  1.1039 +                                       x)/inTouch->numDownFingers;
  1.1040 +                inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers+1)-
  1.1041 +                                       y)/inTouch->numDownFingers;
  1.1042 +            }
  1.1043 +        }
  1.1044 +        else if (event->type == SDL_FINGERMOTION) {
  1.1045 +            float dx = ((float)event->tfinger.dx)/(float)inTouch->res.x;
  1.1046 +            float dy = ((float)event->tfinger.dy)/(float)inTouch->res.y;
  1.1047 +            //printf("dx,dy: (%f,%f)\n",dx,dy);
  1.1048 +#ifdef ENABLE_DOLLAR
  1.1049 +            SDL_DollarPath* path = &inTouch->dollarPath;
  1.1050 +            if (path->numPoints < MAXPATHSIZE) {
  1.1051 +                path->p[path->numPoints].x = inTouch->centroid.x;
  1.1052 +                path->p[path->numPoints].y = inTouch->centroid.y;
  1.1053 +                pathDx =
  1.1054 +                    (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
  1.1055 +                pathDy =
  1.1056 +                    (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
  1.1057 +                path->length += (float)SDL_sqrt(pathDx*pathDx + pathDy*pathDy);
  1.1058 +                path->numPoints++;
  1.1059 +            }
  1.1060 +#endif
  1.1061 +            lastP.x = x - dx;
  1.1062 +            lastP.y = y - dy;
  1.1063 +            lastCentroid = inTouch->centroid;
  1.1064 +
  1.1065 +            inTouch->centroid.x += dx/inTouch->numDownFingers;
  1.1066 +            inTouch->centroid.y += dy/inTouch->numDownFingers;
  1.1067 +            //printf("Centrid : (%f,%f)\n",inTouch->centroid.x,inTouch->centroid.y);
  1.1068 +            if (inTouch->numDownFingers > 1) {
  1.1069 +                SDL_FloatPoint lv; //Vector from centroid to last x,y position
  1.1070 +                SDL_FloatPoint v; //Vector from centroid to current x,y position
  1.1071 +                //lv = inTouch->gestureLast[j].cv;
  1.1072 +                lv.x = lastP.x - lastCentroid.x;
  1.1073 +                lv.y = lastP.y - lastCentroid.y;
  1.1074 +                lDist = (float)SDL_sqrt(lv.x*lv.x + lv.y*lv.y);
  1.1075 +                //printf("lDist = %f\n",lDist);
  1.1076 +                v.x = x - inTouch->centroid.x;
  1.1077 +                v.y = y - inTouch->centroid.y;
  1.1078 +                //inTouch->gestureLast[j].cv = v;
  1.1079 +                Dist = (float)SDL_sqrt(v.x*v.x+v.y*v.y);
  1.1080 +                // SDL_cos(dTheta) = (v . lv)/(|v| * |lv|)
  1.1081 +
  1.1082 +                //Normalize Vectors to simplify angle calculation
  1.1083 +                lv.x/=lDist;
  1.1084 +                lv.y/=lDist;
  1.1085 +                v.x/=Dist;
  1.1086 +                v.y/=Dist;
  1.1087 +                dtheta = (float)SDL_atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
  1.1088 +
  1.1089 +                dDist = (Dist - lDist);
  1.1090 +                if (lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
  1.1091 +
  1.1092 +                //inTouch->gestureLast[j].dDist = dDist;
  1.1093 +                //inTouch->gestureLast[j].dtheta = dtheta;
  1.1094 +
  1.1095 +                //printf("dDist = %f, dTheta = %f\n",dDist,dtheta);
  1.1096 +                //gdtheta = gdtheta*.9 + dtheta*.1;
  1.1097 +                //gdDist  =  gdDist*.9 +  dDist*.1
  1.1098 +                //knob.r += dDist/numDownFingers;
  1.1099 +                //knob.ang += dtheta;
  1.1100 +                //printf("thetaSum = %f, distSum = %f\n",gdtheta,gdDist);
  1.1101 +                //printf("id: %i dTheta = %f, dDist = %f\n",j,dtheta,dDist);
  1.1102 +                SDL_SendGestureMulti(inTouch,dtheta,dDist);
  1.1103 +            }
  1.1104 +            else {
  1.1105 +                //inTouch->gestureLast[j].dDist = 0;
  1.1106 +                //inTouch->gestureLast[j].dtheta = 0;
  1.1107 +                //inTouch->gestureLast[j].cv.x = 0;
  1.1108 +                //inTouch->gestureLast[j].cv.y = 0;
  1.1109 +            }
  1.1110 +            //inTouch->gestureLast[j].f.p.x = x;
  1.1111 +            //inTouch->gestureLast[j].f.p.y = y;
  1.1112 +            //break;
  1.1113 +            //pressure?
  1.1114 +        }
  1.1115 +
  1.1116 +        if (event->type == SDL_FINGERDOWN) {
  1.1117 +
  1.1118 +            inTouch->numDownFingers++;
  1.1119 +            inTouch->centroid.x = (inTouch->centroid.x*(inTouch->numDownFingers - 1)+
  1.1120 +                                   x)/inTouch->numDownFingers;
  1.1121 +            inTouch->centroid.y = (inTouch->centroid.y*(inTouch->numDownFingers - 1)+
  1.1122 +                                   y)/inTouch->numDownFingers;
  1.1123 +            //printf("Finger Down: (%f,%f). Centroid: (%f,%f\n",x,y,
  1.1124 +            //     inTouch->centroid.x,inTouch->centroid.y);
  1.1125 +
  1.1126 +#ifdef ENABLE_DOLLAR
  1.1127 +            inTouch->dollarPath.length = 0;
  1.1128 +            inTouch->dollarPath.p[0].x = x;
  1.1129 +            inTouch->dollarPath.p[0].y = y;
  1.1130 +            inTouch->dollarPath.numPoints = 1;
  1.1131 +#endif
  1.1132 +        }
  1.1133      }
  1.1134 -  }
  1.1135  }
  1.1136  
  1.1137 -  /* vi: set ts=4 sw=4 expandtab: */
  1.1138 -  
  1.1139 +/* vi: set ts=4 sw=4 expandtab: */