The Game Engine  1
Input.cpp
Go to the documentation of this file.
1 #include "Input.h"
2 #include "SDL/SDL_keyboard.h"
3 
4 Input::Input(bool isJoy):isJoystick(isJoy)
5 {
7  mIndex = inputs.size();
8  //open joystick
9  if(isJoy){
10  mJoystick=SDL_JoystickOpen(mIndex-1);
11  cout<<"Joystick:"<<mIndex-1<<endl;
12  cout<<"Name:"<<SDL_JoystickName(mIndex-1)<<endl;
13  cout<<SDL_JoystickNumAxes(mJoystick)<<" axes"<<endl;
14  cout<<SDL_JoystickNumButtons(mJoystick)<<" buttons"<<endl;
15  cout<<SDL_JoystickNumBalls(mJoystick)<<" balls"<<endl;
16  cout<<SDL_JoystickNumHats(mJoystick)<<" hats"<<endl;
17  //initialize button key storage
18  mJoyStates = vector<bool>(SDL_JoystickNumButtons(mJoystick));
19  mLastJoyStates = vector<Uint32>(SDL_JoystickNumButtons(mJoystick));
20  mLastJoyDoubleStates = vector<Uint32>(SDL_JoystickNumButtons(mJoystick));
21  }
22 
23  //store this input
24  addInput(this);
25 }
26 
28  return inputs.size();
29 }
30 
31 Input* Input::getInput(unsigned int index){
32  return index < inputs.size() ? inputs[index] : NULL;
33 }
34 
36 {
37  if(SDL_WasInit(SDL_INIT_JOYSTICK))
38  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
39  if(SDL_InitSubSystem(SDL_INIT_JOYSTICK)<0){
40  cout<<"Joystick could not be initialized"<<endl;
41  }
42  //open all joysticks
43  for(int i=0,end=Input::getNumJoysticks(); i < end; ++i )
44  {
45  cout<< SDL_JoystickName(i)<<endl;
46 
47  }
48  return getNumJoysticks();
49 }
50 
51 void Input::updateInputs(SDL_Event event)
52 {
53  Input* i = NULL;
54  string name="";
55  switch (event.type) {
56  case SDL_KEYDOWN:
57  i = inputs[0];
58  i->mKeyStates[event.key.keysym.sym] = make_pair(true,event.key.keysym.mod);
59  if(i->triggered(event.key.keysym.sym, DOUBLECLICKTRIGGERTIME))
60  i->mLastKeyDoubleStates[event.key.keysym.sym]=SDL_GetTicks();
61  cout<<"key:"<<event.key.keysym.sym<<" down."<<endl;
63  auto fnc = *fn++;
64  fnc(event.key.keysym.sym, event.key.keysym.mod);
65  }
66  break;
67  case SDL_KEYUP:
68  i = inputs[0];
69  i->mKeyStates[event.key.keysym.sym] = make_pair(false,event.key.keysym.mod);;
70  i->mLastKeyStates[event.key.keysym.sym] = SDL_GetTicks();
71  cout<<"key:"<<event.key.keysym.sym<<" up."<<endl;
73  auto fnc = *fn++;
74  fnc(event.key.keysym.sym, event.key.keysym.mod);
75  }
76  break;
78  case SDL_MOUSEBUTTONDOWN:
79  {
80  i = inputs[0];
81  cout<<"Mouse Button:"<<(int)event.button.button<<" pressed."<<endl;
82  //hack to ensure mouse states exist
83  while(i->mMouseButtonStates.size()<event.button.button){
84  i->mMouseButtonStates.push_back(MouseState());
85  i->mLastMouseStates.push_back(MouseState());
86  i->mLastMouseDoubleStates.push_back(MouseState());
87  }
88  MouseState ms(
89  true,
90  Point2D(event.button.x,event.button.y),
91  SDL_GetTicks()
92  );
93  i->mMouseButtonStates[event.button.button-1] = ms;
94  if(i->triggered((MouseButton)(event.button.button-1), DOUBLECLICKTRIGGERTIME))
95  i->mLastMouseDoubleStates[event.button.button-1].time = SDL_GetTicks();
97  auto fnc = *fn++;
98  fnc(event.button.button-1, ms);
99  }
100  break;
101  }
102  case SDL_MOUSEBUTTONUP:
103  {
104  i = inputs[0];
105  cout<<"Mouse Button:"<<(int)event.button.button<<" released."<<endl;
106  //hack to ensure mouse states exist
107  while(i->mMouseButtonStates.size()<event.button.button){
108  i->mMouseButtonStates.push_back(MouseState());
109  i->mLastMouseStates.push_back(MouseState());
110  i->mLastMouseDoubleStates.push_back(MouseState());
111  }
112  i->mLastMouseStates[event.button.button-1]=i->mMouseButtonStates[event.button.button-1];
113  MouseState ms(
114  false,
115  Point2D(event.button.x,event.button.y),
116  SDL_GetTicks()
117  );
118  i->mMouseButtonStates[event.button.button-1] = ms;
120  auto fnc = *fn++;
121  fnc(event.button.button-1, ms);
122  }
123  break;
124  }
125  case SDL_MOUSEMOTION:
126  {
127  i = inputs[0];
128  i->mMouseState.pos.x = event.motion.x;
129  i->mMouseState.pos.y = event.motion.y;
130  i->mMouseState.relPos.x = event.motion.yrel;
131  i->mMouseState.relPos.y = event.motion.yrel;
132  i->mMouseState.time = SDL_GetTicks();
134  auto fnc = *fn++;
135  fnc(i->mMouseState);
136  }
137  break;
138  }
139  case SDL_JOYBUTTONDOWN:
140  cout<<"Joybutton "<<(int)event.jbutton.button<<" down"<<endl;
141  i = inputs[1+event.jbutton.which];
142  name = SDL_JoystickName(event.jbutton.which);
143  if(name.find("360")!=string::npos){
144  i->mJoyStates[event.jbutton.button] = true;
145  if(i->triggered((JoyButton)event.jbutton.button, 500))
146  i->mLastJoyDoubleStates[(JoyButton)event.jbutton.button] = SDL_GetTicks();
148  auto fnc = *fn++;
149  fnc(event.jbutton.which, (JoyButton)event.jbutton.button);
150  }
151  }
152  else if(name == "MotioninJoy Virtual Game Controller"){
154  switch(event.jbutton.button){
155  case 0:
156  i->mJoyStates[3] = true;
157  break;
158  case 1:
159  i->mJoyStates[1] = true;
160  break;
161  case 2:
162  i->mJoyStates[0] = true;
163  break;
164  case 3:
165  i->mJoyStates[2] = true;
166  break;
167  case 6:
168  i->mJoyStates[4] = true;
169  break;
170  case 7:
171  i->mJoyStates[5] = true;
172  break;
173  case 8:
174  i->mJoyStates[6] = true;
175  break;
176  case 9:
177  i->mJoyStates[7] = true;
178  break;
179  case 10:
180  i->mJoyStates[8] = true;
181  break;
182  case 11:
183  i->mJoyStates[9] = true;
184  break;
185  case 12:
186  i->mJoyStates[12] = true;
187  break;
188  default:
189  cout<<"Unexpected value:"<<event.jaxis.which<<endl;
190  }
191  }
192  break;
193  case SDL_JOYBUTTONUP:
194  cout<<"Joybutton "<<(int)event.jbutton.button<<" up"<<endl;
195  i = inputs[1+event.jbutton.which];
196  name = SDL_JoystickName(event.jbutton.which);
197  if(name.find("360")!=string::npos){
198  i->mJoyStates[event.jbutton.button] = false;
199  i->mLastJoyStates[event.jbutton.button] = SDL_GetTicks();
201  auto fnc = *fn++;
202  fnc(event.jbutton.which, (JoyButton)event.jbutton.button);
203  }
204  }
205  else if(name == "MotioninJoy Virtual Game Controller"){
206  switch(event.jbutton.button){
207  case 0:
208  i->mJoyStates[3] = false;
209  i->mLastJoyStates[3] = SDL_GetTicks();
210  break;
211  case 1:
212  i->mJoyStates[1] = false;
213  i->mLastJoyStates[1] = SDL_GetTicks();
214  break;
215  case 2:
216  i->mJoyStates[0] = false;
217  i->mLastJoyStates[0] = SDL_GetTicks();
218  break;
219  case 3:
220  i->mJoyStates[2] = false;
221  i->mLastJoyStates[2] = SDL_GetTicks();
222  break;
223  case 6:
224  i->mJoyStates[4] = false;
225  i->mLastJoyStates[4] = SDL_GetTicks();
226  break;
227  case 7:
228  i->mJoyStates[5] = false;
229  i->mLastJoyStates[5] = SDL_GetTicks();
230  break;
231  case 8:
232  i->mJoyStates[6] = false;
233  i->mLastJoyStates[6] = SDL_GetTicks();
234  break;
235  case 9:
236  i->mJoyStates[7] = false;
237  i->mLastJoyStates[7] = SDL_GetTicks();
238  break;
239  case 10:
240  i->mJoyStates[8] = false;
241  i->mLastJoyStates[8] = SDL_GetTicks();
242  break;
243  case 11:
244  i->mJoyStates[9] = false;
245  i->mLastJoyStates[9] = SDL_GetTicks();
246  break;
247  case 12:
248  i->mJoyStates[12] = false;
249  i->mLastJoyStates[12] = SDL_GetTicks();
250  break;
251  default:
252  cout<<"Unexpected value:"<<event.jaxis.which<<endl;
253  }
254  }
255  break;
256  case SDL_JOYAXISMOTION:
257  i = inputs[1+event.jaxis.which];
258  name = SDL_JoystickName(event.jbutton.which);
259  if ( ( event.jaxis.value < -THRESHHOLD )|| (event.jaxis.value > THRESHHOLD ))
260  {
261  cout<<"axis "<<(int)event.jaxis.axis<<" triggered"<<endl;
262  cout<<"value:"<<(int)event.jaxis.value<<endl;
263 
264  if(name.find("360")!=string::npos){
265  // JoyLeft-right movement/right stick code goes here
266  if( event.jaxis.axis == 0)
267  {
268  i->mJoyLeftPos.x = event.jaxis.value/JOYSTICKRANGE;
270  auto fnc = *fn++;
271  fnc(event.jbutton.which, (JoyStick)event.jaxis.axis, i->mJoyLeftPos);
272  }
273  }
274  // Up-Down movement code goes here
275  else if( event.jaxis.axis == 1)
276  {
277  i->mJoyLeftPos.y = event.jaxis.value/JOYSTICKRANGE;
279  auto fnc = *fn++;
280  fnc(event.jbutton.which, (JoyStick)event.jaxis.axis, i->mJoyLeftPos);
281  }
282  }
283  // Trigger pulls go here
284  else if( event.jaxis.axis == 2)
285  {
286  if(event.jaxis.value < 0){
287  cout<<"less"<<endl;
288  }
289  if(event.jaxis.value >0){
290  cout<<"more"<<endl;
291  }
293  auto fnc = *fn++;
294  fnc(event.jbutton.which, (JoyStick)event.jaxis.axis, Point2D(event.jaxis.value, event.jaxis.value));
295  }
296 
297  }
298  // Up-Down cursor/left stick code goes here
299  else if( event.jaxis.axis == 3)
300  {
301  i->mJoyRightPos.y = event.jaxis.value/JOYSTICKRANGE;
303  auto fnc = *fn++;
304  fnc(event.jbutton.which, (JoyStick)event.jaxis.axis, i->mJoyRightPos);
305  }
306  }
307  // JoyLeft-right cursor/left stick code goes here
308  else if( event.jaxis.axis == 4)
309  {
310  i->mJoyRightPos.x = event.jaxis.value/JOYSTICKRANGE;
312  auto fnc = *fn++;
313  fnc(event.jbutton.which, (JoyStick)event.jaxis.axis, i->mJoyRightPos);
314  }
315  }
316  }
317  else if(name == "MotioninJoy Virtual Game Controller"){
318  // JoyLeft-right movement/right stick code goes here
319  if( event.jaxis.axis == 0)
320  {
321  i->mJoyLeftPos.x = event.jaxis.value/JOYSTICKRANGE;
322  }
323  // Up-Down movement code goes here
324  if( event.jaxis.axis == 1)
325  {
326  i->mJoyLeftPos.y = event.jaxis.value/JOYSTICKRANGE;
327  }
328  // Trigger pulls go here
329  if( event.jaxis.axis == 2)
330  {
331  if(event.jaxis.value < 0)
332  cout<<"less"<<endl;
333  if(event.jaxis.value >0)
334  cout<<"more"<<endl;
335  }
336  // JoyLeft-right cursor/left stick code goes here
337  if( event.jaxis.axis == 5)
338  {
339  i->mJoyRightPos.x = event.jaxis.value/JOYSTICKRANGE;
340  }
341  // Up-Down cursor/left stick code goes here
342  if( event.jaxis.axis == 3)
343  {
344  i->mJoyRightPos.y = event.jaxis.value/JOYSTICKRANGE;
345  }
346  }
347  else{
348  cout<<name<<endl;
349  }
350  }
351  else{
352  cout<<"axis "<<(int)event.jaxis.axis<<endl;
353  cout<<"value:"<<(int)event.jaxis.value<<endl;
354  if(name.find("360")!=string::npos){
355  // JoyLeft-right movement/right stick code goes here
356  if( event.jaxis.axis == 0)
357  {
358  i->mJoyLeftPos.x = 0.0;
359  }
360  // Up-Down movement code goes here
361  if( event.jaxis.axis == 1)
362  {
363  i->mJoyLeftPos.y = 0.0;
364  }
365  // Trigger pulls go here
366  if( event.jaxis.axis == 2)
367  {
368  if(event.jaxis.value < 0)
369  cout<<"less"<<endl;
370  if(event.jaxis.value >0)
371  cout<<"more"<<endl;
372  }
373  // Up-Down cursor/left stick code goes here
374  if( event.jaxis.axis == 3)
375  {
376  i->mJoyRightPos.y = 0.0;
377  }
378  // JoyLeft-right cursor/left stick code goes here
379  if( event.jaxis.axis == 4)
380  {
381  i->mJoyRightPos.x = 0.0;
382  }
383  }
384  else if(name == "MotioninJoy Virtual Game Controller"){
385  // JoyLeft-right movement/right stick code goes here
386  if( event.jaxis.axis == 0)
387  {
388  i->mJoyLeftPos.x = 0.0;
389  }
390  // Up-Down movement code goes here
391  if( event.jaxis.axis == 1)
392  {
393  i->mJoyLeftPos.y = 0.0;
394  }
395  // Trigger pulls go here
396  if( event.jaxis.axis == 2)
397  {
398  if(event.jaxis.value < 0)
399  cout<<"less"<<endl;
400  if(event.jaxis.value >0)
401  cout<<"more"<<endl;
402  }
403  // JoyLeft-right cursor/left stick code goes here
404  if( event.jaxis.axis == 5)
405  {
406  i->mJoyRightPos.x = 0.0;
407  }
408  // Up-Down cursor/left stick code goes here
409  if( event.jaxis.axis == 3)
410  {
411  i->mJoyRightPos.y = 0.0;
412  }
413  }
414  }
415  break;
416  case SDL_JOYHATMOTION:
417  cout<<"hat "<<(int)event.jhat.hat<<" triggered"<<endl;
418  cout<<"value:"<<(int)event.jhat.value<<endl;
419  i = inputs[1+event.jhat.which];
420  name = SDL_JoystickName(event.jhat.which);
421  if(name.find("360")!=string::npos){
422  if(event.jhat.value == SDL_HAT_CENTERED){
423  i = inputs[1+event.jhat.which];
424  i->mJoyDPos.zero();
425  cout<<"Centered"<<endl;
426  }
427  if(event.jhat.value == SDL_HAT_LEFT){
428  i = inputs[1+event.jhat.which];
429  i->mJoyDPos.x = -1;
430  cout<<"JoyLeft"<<endl;
431  }
432  if(event.jhat.value == SDL_HAT_RIGHT){
433  i = inputs[1+event.jhat.which];
434  cout<<"JoyRight"<<endl;
435  i->mJoyDPos.x = 1;
436  }
437  if(event.jhat.value == SDL_HAT_UP){
438  i = inputs[1+event.jhat.which];
439  cout<<"Up"<<endl;
440  i->mJoyDPos.y = -1;
441  }
442  if(event.jhat.value == SDL_HAT_DOWN){
443  i = inputs[1+event.jhat.which];
444  cout<<"Down"<<endl;
445  i->mJoyDPos.y = 1;
446  }
447  if(event.jhat.value == SDL_HAT_RIGHTUP){
448  i = inputs[1+event.jhat.which];
449  cout<<"RightUp"<<endl;
450  i->mJoyDPos.x = 1;
451  i->mJoyDPos.y = -1;
452  }
453  if(event.jhat.value == SDL_HAT_RIGHTDOWN){
454  i = inputs[1+event.jhat.which];
455  cout<<"RightDown"<<endl;
456  i->mJoyDPos.x = 1;
457  i->mJoyDPos.y = 1;
458  }
459  if(event.jhat.value == SDL_HAT_LEFTUP){
460  i = inputs[1+event.jhat.which];
461  cout<<"LeftUp"<<endl;
462  i->mJoyDPos.x = -1;
463  i->mJoyDPos.y = -1;
464  }
465  if(event.jhat.value == SDL_HAT_LEFTDOWN){
466  i = inputs[1+event.jhat.which];
467  cout<<"LeftDown"<<endl;
468  i->mJoyDPos.x = -1;
469  i->mJoyDPos.y = 1;
470  }
471  }
472  else if(name == "MotioninJoy Virtual Game Controller"){
473  if(event.jhat.value == SDL_HAT_CENTERED){
474  //if button 11 down then it's a left up
475  if(i->mJoyStates[11])
476  {
477  i->mJoyDPos.x = -1;
478  i->mJoyDPos.y = -1;
479  cout<<"LeftUp"<<endl;
480  }
481  //if button 12 down it's rightdown
482  else if(i->mJoyStates[12])
483  {
484  i->mJoyDPos.x = 1;
485  i->mJoyDPos.y = 1;
486  cout<<"RightDown"<<endl;
487  }
488  //else centered
489  else
490  {
491  i->mJoyDPos.zero();
492  cout<<"Centered"<<endl;
493  }
494  }
495  if(event.jhat.value == SDL_HAT_LEFT){
496  i = inputs[1+event.jhat.which];
497  i->mJoyDPos.x = 1;
498  cout<<"JoyRight"<<endl;
499  }
500  if(event.jhat.value == SDL_HAT_RIGHT){
501  i = inputs[1+event.jhat.which];
502  cout<<"Down"<<endl;
503  i->mJoyDPos.y = 1;
504  }
505  if(event.jhat.value == SDL_HAT_UP){
506  i = inputs[1+event.jhat.which];
507  cout<<"Up"<<endl;
508  i->mJoyDPos.y = -1;
509  }
510  if(event.jhat.value == SDL_HAT_DOWN){
511  i = inputs[1+event.jhat.which];
512  cout<<"JoyLeft"<<endl;
513  i->mJoyDPos.x = -1;
514  }
515  if(event.jhat.value == SDL_HAT_RIGHTUP){
516  i = inputs[1+event.jhat.which];
517  cout<<"RightUp"<<endl;
518  i->mJoyDPos.x = 1;
519  i->mJoyDPos.y = -1;
520  }
521  if(event.jhat.value == SDL_HAT_RIGHTDOWN){
522  i = inputs[1+event.jhat.which];
523  cout<<"LeftDown"<<endl;
524  i->mJoyDPos.x = -1;
525  i->mJoyDPos.y = 1;
526  }
527  if(event.jhat.value == SDL_HAT_LEFTUP){
528  //this never gets hit?
529  i = inputs[1+event.jhat.which];
530  cout<<"wat"<<endl;
531  i->mJoyDPos.x = 1;
532  i->mJoyDPos.y = -1;
533  }
534  if(event.jhat.value == SDL_HAT_LEFTDOWN){
535  //this never gets hit either?
536  i = inputs[1+event.jhat.which];
537  cout<<"wat wat"<<endl;
538  i->mJoyDPos.x = -1;
539  i->mJoyDPos.y = 1;
540  }
541  }
543  auto fnc = *fn++;
544  fnc(event.jhat.which, DPad, inputs[1+event.jhat.which]->mJoyDPos);
545  }
546  break;
547  case SDL_JOYBALLMOTION:
548  i = inputs[1+event.jhat.which];
549  name = SDL_JoystickName(event.jbutton.which);
550  cout<<"ball "<<(int)event.jball.ball<<" triggered"<<endl;
551  cout<<"value:("<<(int)event.jball.xrel<<(int)event.jball.yrel<<')'<<endl;
552  break;
553  default:
554 
555  break;
556  }
557 }
558 
559 pair<int,int> Input::getDeviceCounts()
560 {
562  return make_pair(1,getNumJoysticks());
563 }
564 
566 {
567  return SDL_NumJoysticks();
568 }
569 
571 {
572  inputs.push_back(i);
573 }
574 
576 {
577  foritr(input, inputs){
578  if(*input == i){
579  inputs.erase(input);
580  return;
581  }
582  }
583 }
584 
585 void Input::addKeyDownCallback(void (*fn)(SDLKey, SDLMod)){
586  mKeyDownCallbacks.insert(fn);
587 }
588 
589 void Input::removeKeyDownCallback(void (*fn)(SDLKey, SDLMod)){
591  mKeyDownCallbacks.erase(fn);
592 }
593 
594 void Input::addKeyUpCallback(void (*fn)(SDLKey, SDLMod)){
595  mKeyUpCallbacks.insert(fn);
596 }
597 
598 void Input::removeKeyUpCallback(void (*fn)(SDLKey, SDLMod)){
599  mKeyUpCallbacks.erase(fn);
600 }
601 
602 void Input::addMouseDownCallback(void (*fn)(Uint8, MouseState)){
603  mMouseDownCallbacks.insert(fn);
604 }
605 
607  mMouseDownCallbacks.erase(fn);
608 }
609 
610 void Input::addMouseUpCallback(void (*fn)(Uint8, MouseState)){
611  mMouseUpCallbacks.insert(fn);
612 }
613 
614 void Input::removeMouseUpCallback(void (*fn)(Uint8, MouseState)){
615  mMouseUpCallbacks.erase(fn);
616 }
617 
619  mMouseMoveCallbacks.insert(fn);
620 }
621 
623  mMouseMoveCallbacks.erase(fn);
624 }
625 
627  mJoyButtonDownCallbacks.insert(fn);
628 }
629 
631  mJoyButtonDownCallbacks.erase(fn);
632 }
633 
634 void Input::addJoyButtonUpCallback(void (*fn)(Uint8, JoyButton)){
635  mJoyButtonUpCallbacks.insert(fn);
636 }
637 
639  mJoyButtonUpCallbacks.erase(fn);
640 }
641 
642 void Input::addJoyMoveCallback(void (*fn)(Uint8, JoyStick, Point2D)){
643  mJoyMoveCallbacks.insert(fn);
644 }
645 
647  mJoyMoveCallbacks.erase(fn);
648 }
649 
651  for(unsigned int i=1, end = inputs.size(); i < end; ++i){
652  Input* in = inputs[i];
653  if(in->pressed(b))
654  return true;
655  }
656  return false;
657 }
658 
660  for(unsigned int i=1, end = inputs.size(); i < end; ++i){
661  Input* in = inputs[i];
662  if(in->pressed(b))
663  return true;
664  }
665  return false;
666 }
667 
669  Point2D dir;
670  for(int i=1,end=inputs.size(); i<end;++i){
671  dir+= inputs[i]->getJoyMovement(s);
672  }
673  return dir;
674 }
675 
677 
679 
680 bool Input::pressed(SDLKey key, SDLMod mod)
681 {
682  pair<bool, SDLMod> p = mKeyStates[key];
683  return p.first && (p.second&0xFFF)==mod;// the 0xFFF is to ignore capslock and numlock
684 }
685 
686 bool Input::triggered(SDLKey key, int ms)
687 {
688  Uint32 val = mLastKeyStates[key];
689  return val<=0?false: SDL_GetTicks() - (ms==-1?TRIGGERTIME:ms) <= val && !doubleTapped(key, ms);
690 }
691 
692 bool Input::doubleTapped(SDLKey key, int ms)
693 {
694  Uint32 val = mLastKeyDoubleStates[key];
695  return val<=0?false: SDL_GetTicks() - (ms==-1?DOUBLECLICKTRIGGERTIME:ms) <= val;
696 }
697 
699 {
700  return mJoyStates[button];
701 }
702 
703 bool Input::triggered(JoyButton button, int ms)
704 {
705  if(mLastJoyStates.size()<(unsigned int)button)
706  return false;
707  Uint32 val = mLastJoyStates[button];
708  return val<=0?false: SDL_GetTicks() - (ms==-1?TRIGGERTIME:ms) <= val && !doubleTapped(button, ms);
709 }
710 
711 bool Input::doubleTapped(JoyButton button, int ms)
712 {
713  Uint32 val = mLastJoyDoubleStates[button];
714  return val<=0?false: SDL_GetTicks() - (ms==-1?DOUBLECLICKTRIGGERTIME:ms) <= val;
715 }
716 
717 bool Input::pressed(MouseButton b, int button)
718 {
719  unsigned int index = (int)b + button;
720  if(inputs[0]->mLastMouseStates.size()==0 || inputs[0]->mMouseButtonStates.size() <= index)
721  return false;
722  return inputs[0]->mMouseButtonStates[index].pressed;
723 }
724 
725 bool Input::triggered(MouseButton b, int button, int ms)
726 {
727  unsigned int index = (int)b + button;
728  if(inputs[0]->mLastMouseStates.size()==0 || inputs[0]->mMouseButtonStates.size() <= index)
729  return false;
730  MouseState m = inputs[0]->mLastMouseStates[index];
731  return m.time<=0?false: SDL_GetTicks() - (ms==-1?TRIGGERTIME:ms) <= m.time && !doubleTapped(b, button, ms);
732 }
733 
734 bool Input::doubleTapped(MouseButton b, int button, int ms)
735 {
736  unsigned int index = (int)b + button;
737  if(inputs[0]->mLastMouseStates.size()==0 || inputs[0]->mMouseButtonStates.size() <= index)
738  return false;
739  MouseState m = inputs[0]->mLastMouseDoubleStates[index];
740  return m.time<=0?false: SDL_GetTicks() - (ms==-1?DOUBLECLICKTRIGGERTIME:ms) <= m.time ;
741 }
742 
744 {
745  return s==JoyLeft ? mJoyLeftPos: s==JoyRight ? mJoyRightPos: mJoyDPos;
746 }
747 
748 vector<Input*> Input::inputs = vector<Input*>();
749 
750 set<void (*)(SDLKey, SDLMod)> Input::mKeyDownCallbacks = set<void (*)(SDLKey, SDLMod)>();
751 
752 set<void (*)(SDLKey, SDLMod)> Input::mKeyUpCallbacks = set<void (*)(SDLKey, SDLMod)>();
753 
754 set<void (*)(Uint8, Input::MouseState)> Input::mMouseDownCallbacks = set<void (*)(Uint8, MouseState)>();
755 
756 set<void (*)(Uint8, Input::MouseState)> Input::mMouseUpCallbacks = set<void (*)(Uint8, MouseState)>();
757 
758 set<void (*)(Input::MouseState)> Input::mMouseMoveCallbacks = set<void (*)(MouseState)>();
759 
760 set<void (*)(Uint8, JoyButton)> Input::mJoyButtonDownCallbacks = set<void (*)(Uint8, JoyButton)>();
761 
762 set<void (*)(Uint8, JoyButton)> Input::mJoyButtonUpCallbacks = set<void (*)(Uint8, JoyButton)>();
763 
764 set<void (*)(Uint8, JoyStick, Point2D)> Input::mJoyMoveCallbacks = set<void (*)(Uint8, JoyStick, Point2D)>();
765