src/events/SDL_gesture.c
changeset 4880 27c458e4ae31
parent 4689 f9ab8df6d45a
     1.1 --- a/src/events/SDL_gesture.c	Sun Aug 22 17:19:10 2010 -0700
     1.2 +++ b/src/events/SDL_gesture.c	Mon Aug 23 23:44:28 2010 -0700
     1.3 @@ -18,6 +18,7 @@
     1.4      Sam Lantinga
     1.5      slouken@libsdl.org
     1.6  */
     1.7 +
     1.8  #include "SDL_config.h"
     1.9  
    1.10  /* General mouse handling code for SDL */
    1.11 @@ -26,6 +27,11 @@
    1.12  #include "SDL_events_c.h"
    1.13  #include "SDL_gesture_c.h"
    1.14  
    1.15 +#include <memory.h>
    1.16 +#include <string.h>
    1.17 +#include <stdio.h>
    1.18 +#include <math.h>
    1.19 +
    1.20  //TODO: Replace with malloc
    1.21  
    1.22  #define MAXPATHSIZE 1024
    1.23 @@ -100,8 +106,8 @@
    1.24    unsigned long hash = 5381;
    1.25    int i;
    1.26    for(i = 0;i < DOLLARNPOINTS; i++) { 
    1.27 -    hash = ((hash<<5) + hash) + points[i].x;
    1.28 -    hash = ((hash<<5) + hash) + points[i].y;
    1.29 +    hash = ((hash<<5) + hash) + (unsigned long)points[i].x;
    1.30 +    hash = ((hash<<5) + hash) + (unsigned long)points[i].y;
    1.31    }
    1.32    return hash;
    1.33  }
    1.34 @@ -110,7 +116,6 @@
    1.35  static int SaveTemplate(SDL_DollarTemplate *templ, SDL_RWops * src) {
    1.36    if(src == NULL) return 0;
    1.37  
    1.38 -  int i;
    1.39    
    1.40    //No Longer storing the Hash, rehash on load
    1.41    //if(SDL_RWops.write(src,&(templ->hash),sizeof(templ->hash),1) != 1) return 0;
    1.42 @@ -151,14 +156,16 @@
    1.43  //path is an already sampled set of points
    1.44  //Returns the index of the gesture on success, or -1
    1.45  static int SDL_AddDollarGesture(SDL_GestureTouch* inTouch,SDL_FloatPoint* path) {
    1.46 +  SDL_DollarTemplate* dollarTemplate;
    1.47 +  SDL_DollarTemplate *templ;
    1.48 +  int i = 0;
    1.49    if(inTouch == NULL) {
    1.50      if(SDL_numGestureTouches == 0) return -1;
    1.51 -    int i = 0;
    1.52      for(i = 0;i < SDL_numGestureTouches; i++) {
    1.53        inTouch = &SDL_gestureTouch[i];
    1.54  
    1.55 -      SDL_DollarTemplate* dollarTemplate = 
    1.56 -	SDL_realloc(inTouch->dollarTemplate,
    1.57 +    dollarTemplate = 
    1.58 +	(SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
    1.59  		    (inTouch->numDollarTemplates + 1) * 
    1.60  		    sizeof(SDL_DollarTemplate));
    1.61        if(!dollarTemplate) {
    1.62 @@ -168,7 +175,7 @@
    1.63  	
    1.64        inTouch->dollarTemplate = dollarTemplate;
    1.65  
    1.66 -      SDL_DollarTemplate *templ = 
    1.67 +    templ = 
    1.68  	&inTouch->dollarTemplate[inTouch->numDollarTemplates];
    1.69        memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
    1.70        templ->hash = SDL_HashDollar(templ->path);
    1.71 @@ -177,7 +184,7 @@
    1.72      return inTouch->numDollarTemplates - 1;
    1.73    } else {
    1.74      SDL_DollarTemplate* dollarTemplate = 
    1.75 -      SDL_realloc(inTouch->dollarTemplate,
    1.76 +      ( SDL_DollarTemplate *)SDL_realloc(inTouch->dollarTemplate,
    1.77  		  (inTouch->numDollarTemplates + 1) * 
    1.78  		  sizeof(SDL_DollarTemplate));
    1.79      if(!dollarTemplate) {
    1.80 @@ -187,7 +194,7 @@
    1.81      
    1.82      inTouch->dollarTemplate = dollarTemplate;
    1.83  
    1.84 -    SDL_DollarTemplate *templ = 
    1.85 +    templ = 
    1.86        &inTouch->dollarTemplate[inTouch->numDollarTemplates];
    1.87      memcpy(templ->path,path,DOLLARNPOINTS*sizeof(SDL_FloatPoint));
    1.88      templ->hash = SDL_HashDollar(templ->path);
    1.89 @@ -198,9 +205,9 @@
    1.90  }
    1.91  
    1.92  int SDL_LoadDollarTemplates(SDL_TouchID touchId, SDL_RWops *src) {
    1.93 -  if(src == NULL) return 0;
    1.94    int i,loaded = 0;
    1.95    SDL_GestureTouch *touch = NULL;
    1.96 +  if(src == NULL) return 0;
    1.97    if(touchId >= 0) {
    1.98      for(i = 0;i < SDL_numGestureTouches; i++)
    1.99        if(SDL_gestureTouch[i].id == touchId)
   1.100 @@ -240,10 +247,10 @@
   1.101    SDL_FloatPoint p;
   1.102    int i;
   1.103    for(i = 0; i < DOLLARNPOINTS; i++) {
   1.104 -    p.x = points[i].x * cos(ang) - points[i].y * sin(ang);
   1.105 -    p.y = points[i].x * sin(ang) + points[i].y * cos(ang);
   1.106 -    dist += sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
   1.107 -		 (p.y-templ[i].y)*(p.y-templ[i].y));
   1.108 +    p.x = (float)(points[i].x * cos(ang) - points[i].y * sin(ang));
   1.109 +    p.y = (float)(points[i].x * sin(ang) + points[i].y * cos(ang));
   1.110 +    dist += (float)(sqrt((p.x-templ[i].x)*(p.x-templ[i].x)+
   1.111 +		 (p.y-templ[i].y)*(p.y-templ[i].y)));
   1.112    }
   1.113    return dist/DOLLARNPOINTS;
   1.114    
   1.115 @@ -253,26 +260,26 @@
   1.116    //------------BEGIN DOLLAR BLACKBOX----------------//
   1.117    //-TRANSLATED DIRECTLY FROM PSUDEO-CODE AVAILABLE AT-//
   1.118    //-"http://depts.washington.edu/aimgroup/proj/dollar/"-//
   1.119 -  float ta = -M_PI/4;
   1.120 -  float tb = M_PI/4;
   1.121 -  float dt = M_PI/90;
   1.122 -  float x1 = PHI*ta + (1-PHI)*tb;
   1.123 +  double ta = -M_PI/4;
   1.124 +  double tb = M_PI/4;
   1.125 +  double dt = M_PI/90;
   1.126 +  float x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.127    float f1 = dollarDifference(points,templ,x1);
   1.128 -  float x2 = (1-PHI)*ta + PHI*tb;
   1.129 +  float x2 = (float)((1-PHI)*ta + PHI*tb);
   1.130    float f2 = dollarDifference(points,templ,x2);
   1.131 -  while(abs(ta-tb) > dt) {
   1.132 +  while(fabs(ta-tb) > dt) {
   1.133      if(f1 < f2) {
   1.134        tb = x2;
   1.135        x2 = x1;
   1.136        f2 = f1;
   1.137 -      x1 = PHI*ta + (1-PHI)*tb;
   1.138 +      x1 = (float)(PHI*ta + (1-PHI)*tb);
   1.139        f1 = dollarDifference(points,templ,x1);
   1.140      }
   1.141      else {
   1.142        ta = x1;
   1.143        x1 = x2;
   1.144        f1 = f2;
   1.145 -      x2 = (1-PHI)*ta + PHI*tb;
   1.146 +      x2 = (float)((1-PHI)*ta + PHI*tb);
   1.147        f2 = dollarDifference(points,templ,x2);
   1.148      }
   1.149    }
   1.150 @@ -288,6 +295,14 @@
   1.151  //DollarPath contains raw points, plus (possibly) the calculated length
   1.152  int dollarNormalize(SDL_DollarPath path,SDL_FloatPoint *points) {
   1.153    int i;
   1.154 +  float interval;
   1.155 +  float dist;
   1.156 +  int numPoints = 0;
   1.157 +  SDL_FloatPoint centroid; 
   1.158 +  float xmin,xmax,ymin,ymax;
   1.159 +  float ang;
   1.160 +  float w,h;
   1.161 +
   1.162    //Calculate length if it hasn't already been done
   1.163    if(path.length <= 0) {
   1.164      for(i=1;i<path.numPoints;i++) {
   1.165 @@ -295,22 +310,20 @@
   1.166  	         path.p[i-1].x;
   1.167        float dy = path.p[i  ].y - 
   1.168  	         path.p[i-1].y;
   1.169 -      path.length += sqrt(dx*dx+dy*dy);
   1.170 +      path.length += (float)(sqrt(dx*dx+dy*dy));
   1.171      }
   1.172    }
   1.173  
   1.174    //Resample
   1.175 -  float interval = path.length/(DOLLARNPOINTS - 1);
   1.176 -  float dist = interval;
   1.177 +  interval = path.length/(DOLLARNPOINTS - 1);
   1.178 +  dist = interval;
   1.179  
   1.180 -  int numPoints = 0;
   1.181 -  SDL_FloatPoint centroid; 
   1.182    centroid.x = 0;centroid.y = 0;
   1.183    
   1.184    //printf("(%f,%f)\n",path.p[path.numPoints-1].x,path.p[path.numPoints-1].y);
   1.185    for(i = 1;i < path.numPoints;i++) {
   1.186 -    float d = sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+
   1.187 -		   (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y));
   1.188 +    float d = (float)(sqrt((path.p[i-1].x-path.p[i].x)*(path.p[i-1].x-path.p[i].x)+
   1.189 +		             (path.p[i-1].y-path.p[i].y)*(path.p[i-1].y-path.p[i].y)));
   1.190      //printf("d = %f dist = %f/%f\n",d,dist,interval);
   1.191      while(dist + d > interval) {
   1.192        points[numPoints].x = path.p[i-1].x + 
   1.193 @@ -338,22 +351,21 @@
   1.194   
   1.195    //printf("Centroid (%f,%f)",centroid.x,centroid.y);
   1.196    //Rotate Points so point 0 is left of centroid and solve for the bounding box
   1.197 -  float xmin,xmax,ymin,ymax;
   1.198    xmin = centroid.x;
   1.199    xmax = centroid.x;
   1.200    ymin = centroid.y;
   1.201    ymax = centroid.y;
   1.202    
   1.203 -  float ang = atan2(centroid.y - points[0].y,
   1.204 -		    centroid.x - points[0].x);
   1.205 +  ang = (float)(atan2(centroid.y - points[0].y,
   1.206 +		    centroid.x - points[0].x));
   1.207  
   1.208    for(i = 0;i<numPoints;i++) {					       
   1.209      float px = points[i].x;
   1.210      float py = points[i].y;
   1.211 -    points[i].x = (px - centroid.x)*cos(ang) - 
   1.212 -                  (py - centroid.y)*sin(ang) + centroid.x;
   1.213 -    points[i].y = (px - centroid.x)*sin(ang) + 
   1.214 -                  (py - centroid.y)*cos(ang) + centroid.y;
   1.215 +    points[i].x = (float)((px - centroid.x)*cos(ang) - 
   1.216 +                  (py - centroid.y)*sin(ang) + centroid.x);
   1.217 +    points[i].y = (float)((px - centroid.x)*sin(ang) + 
   1.218 +                  (py - centroid.y)*cos(ang) + centroid.y);
   1.219  
   1.220  
   1.221      if(points[i].x < xmin) xmin = points[i].x;
   1.222 @@ -363,8 +375,8 @@
   1.223    }
   1.224  
   1.225    //Scale points to DOLLARSIZE, and translate to the origin
   1.226 -  float w = xmax-xmin;
   1.227 -  float h = ymax-ymin;
   1.228 +  w = xmax-xmin;
   1.229 +  h = ymax-ymin;
   1.230  
   1.231    for(i=0;i<numPoints;i++) {
   1.232      points[i].x = (points[i].x - centroid.x)*DOLLARSIZE/w;
   1.233 @@ -380,17 +392,17 @@
   1.234  	//SDL_PrintPath(points);
   1.235  	int i;
   1.236  	
   1.237 -	int bestDiff = 10000;
   1.238 +	float bestDiff = 10000;
   1.239  	*bestTempl = -1;
   1.240  	for(i = 0;i < touch->numDollarTemplates;i++) {
   1.241 -		int diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
   1.242 +		float diff = bestDollarDifference(points,touch->dollarTemplate[i].path);
   1.243  		if(diff < bestDiff) {bestDiff = diff; *bestTempl = i;}
   1.244  	}
   1.245  	return bestDiff;
   1.246  }
   1.247  
   1.248  int SDL_GestureAddTouch(SDL_Touch* touch) {  
   1.249 -  SDL_GestureTouch *gestureTouch = SDL_realloc(SDL_gestureTouch,
   1.250 +  SDL_GestureTouch *gestureTouch = (SDL_GestureTouch *)SDL_realloc(SDL_gestureTouch,
   1.251  					       (SDL_numGestureTouches + 1) *
   1.252  					       sizeof(SDL_GestureTouch));
   1.253  
   1.254 @@ -479,6 +491,18 @@
   1.255  
   1.256  void SDL_GestureProcessEvent(SDL_Event* event)
   1.257  {
   1.258 +  float x,y; 
   1.259 +  SDL_FloatPoint path[DOLLARNPOINTS];
   1.260 +  int index;
   1.261 +  int i;
   1.262 +  float pathDx, pathDy;
   1.263 +  SDL_FloatPoint lastP;
   1.264 +  SDL_FloatPoint lastCentroid;
   1.265 +  float lDist;
   1.266 +  float Dist;
   1.267 +  float dtheta;
   1.268 +  float dDist;
   1.269 +
   1.270    if(event->type == SDL_FINGERMOTION || 
   1.271       event->type == SDL_FINGERDOWN ||
   1.272       event->type == SDL_FINGERUP) {
   1.273 @@ -492,8 +516,8 @@
   1.274      //   (int)inTouch->res.x,(int)inTouch->res.y);
   1.275  
   1.276      
   1.277 -    float x = ((float)event->tfinger.x)/(float)inTouch->res.x;
   1.278 -    float y = ((float)event->tfinger.y)/(float)inTouch->res.y;   
   1.279 +    x = ((float)event->tfinger.x)/(float)inTouch->res.x;
   1.280 +    y = ((float)event->tfinger.y)/(float)inTouch->res.y;   
   1.281  
   1.282  
   1.283      //Finger Up
   1.284 @@ -502,14 +526,11 @@
   1.285        
   1.286  #ifdef ENABLE_DOLLAR
   1.287        if(inTouch->recording) {
   1.288 -	inTouch->recording = SDL_FALSE;
   1.289 -	SDL_FloatPoint path[DOLLARNPOINTS];
   1.290 +	inTouch->recording = SDL_FALSE;	
   1.291  	dollarNormalize(inTouch->dollarPath,path);
   1.292  	//SDL_PrintPath(path);
   1.293 -	int index;
   1.294  	if(recordAll) {
   1.295  	  index = SDL_AddDollarGesture(NULL,path);
   1.296 -	  int i;
   1.297  	  for(i = 0;i < SDL_numGestureTouches; i++)
   1.298  	    SDL_gestureTouch[i].recording = SDL_FALSE;
   1.299  	}
   1.300 @@ -554,18 +575,16 @@
   1.301        if(path->numPoints < MAXPATHSIZE) {
   1.302  	path->p[path->numPoints].x = inTouch->centroid.x;
   1.303  	path->p[path->numPoints].y = inTouch->centroid.y;
   1.304 -	float pathDx = 
   1.305 +	pathDx = 
   1.306  	  (path->p[path->numPoints].x-path->p[path->numPoints-1].x);
   1.307 -	float pathDy = 
   1.308 +	pathDy = 
   1.309  	  (path->p[path->numPoints].y-path->p[path->numPoints-1].y);
   1.310 -	path->length += sqrt(pathDx*pathDx + pathDy*pathDy);
   1.311 +	path->length += (float)sqrt(pathDx*pathDx + pathDy*pathDy);
   1.312  	path->numPoints++;
   1.313        }
   1.314  #endif
   1.315 -      SDL_FloatPoint lastP;
   1.316        lastP.x = x - dx;
   1.317        lastP.y = y - dy;
   1.318 -      SDL_FloatPoint lastCentroid;
   1.319        lastCentroid = inTouch->centroid;
   1.320        
   1.321        inTouch->centroid.x += dx/inTouch->numDownFingers;
   1.322 @@ -577,12 +596,12 @@
   1.323  	//lv = inTouch->gestureLast[j].cv;
   1.324  	lv.x = lastP.x - lastCentroid.x;
   1.325  	lv.y = lastP.y - lastCentroid.y;
   1.326 -	float lDist = sqrt(lv.x*lv.x + lv.y*lv.y);
   1.327 +	lDist = (float)sqrt(lv.x*lv.x + lv.y*lv.y);
   1.328  	//printf("lDist = %f\n",lDist);
   1.329  	v.x = x - inTouch->centroid.x;
   1.330  	v.y = y - inTouch->centroid.y;
   1.331  	//inTouch->gestureLast[j].cv = v;
   1.332 -	float Dist = sqrt(v.x*v.x+v.y*v.y);
   1.333 +	Dist = (float)sqrt(v.x*v.x+v.y*v.y);
   1.334  	// cos(dTheta) = (v . lv)/(|v| * |lv|)
   1.335  	
   1.336  	//Normalize Vectors to simplify angle calculation
   1.337 @@ -590,9 +609,9 @@
   1.338  	lv.y/=lDist;
   1.339  	v.x/=Dist;
   1.340  	v.y/=Dist;
   1.341 -	float dtheta = atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
   1.342 +	dtheta = (float)atan2(lv.x*v.y - lv.y*v.x,lv.x*v.x + lv.y*v.y);
   1.343  	
   1.344 -	float dDist = (Dist - lDist);
   1.345 +	dDist = (Dist - lDist);
   1.346  	if(lDist == 0) {dDist = 0;dtheta = 0;} //To avoid impossible values
   1.347  	
   1.348  	//inTouch->gestureLast[j].dDist = dDist;