@@ -82,6 +82,8 @@ var LibrarySDL = {
82
82
83
83
DOMEventToSDLEvent : { } ,
84
84
85
+ TOUCH_DEFAULT_ID : 0 , // Our default deviceID for touch events (we get nothing from the browser)
86
+
85
87
keyCodes : { // DOM code ==> SDL code. See https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/KeyboardEvent and SDL_keycode.h
86
88
// For keys that don't have unicode value, we map DOM codes with the corresponding scan codes + 1024 (using "| 1 << 10")
87
89
16 : 225 | 1 << 10 , // shift
@@ -417,50 +419,104 @@ var LibrarySDL = {
417
419
}
418
420
} ,
419
421
420
- touchX: 0 , touchY : 0 ,
422
+ // the browser sends out touchstart events with the whole group of touches
423
+ // even if we received a previous touchstart for a specific touch identifier.
424
+ // You can test this by pressing one finger to the screen, then another. You'll
425
+ // receive two touchstart events, the first with a touches count of 1 the second
426
+ // with a touches count of two.
427
+ // SDL sends out a new touchstart event for only each newly started touch so to
428
+ // emulate this, we keep track of previously started touches.
429
+ downFingers: { } ,
421
430
savedKeydown : null ,
422
431
423
432
receiveEvent : function ( event ) {
424
433
switch ( event . type ) {
425
- case 'touchstart' :
434
+ case 'touchstart' : case 'touchmove' : {
426
435
event . preventDefault ( ) ;
427
- var touch = event . touches [ 0 ] ;
428
- touchX = touch . pageX ;
429
- touchY = touch . pageY ;
430
- var event = {
431
- type : 'mousedown' ,
432
- button : 0 ,
433
- pageX : touchX ,
434
- pageY : touchY
436
+
437
+ var touches = [ ] ;
438
+
439
+ // Clear out any touchstart events that we've already processed
440
+ if ( event . type === 'touchstart' ) {
441
+ for ( var i = 0 ; i < event . touches . length ; i ++ ) {
442
+ var touch = event . touches [ i ] ;
443
+ if ( SDL . downFingers [ touch . identifier ] != true ) {
444
+ SDL . downFingers [ touch . identifier ] = true ;
445
+ touches . push ( touch ) ;
446
+ }
447
+ }
448
+ } else {
449
+ touches = event . touches ;
450
+ }
451
+
452
+ var firstTouch = touches [ 0 ] ;
453
+ if ( event . type == 'touchstart' ) {
454
+ SDL . DOMButtons [ 0 ] = 1 ;
435
455
} ;
436
- SDL . DOMButtons [ 0 ] = 1 ;
437
- SDL . events . push ( event ) ;
438
- break ;
439
- case 'touchmove' :
440
- event . preventDefault ( ) ;
441
- var touch = event . touches [ 0 ] ;
442
- touchX = touch . pageX ;
443
- touchY = touch . pageY ;
444
- event = {
445
- type : 'mousemove' ,
456
+ var mouseEventType ;
457
+ switch ( event . type ) {
458
+ case 'touchstart' : mouseEventType = 'mousedown' ; break ;
459
+ case 'touchmove' : mouseEventType = 'mousemove' ; break ;
460
+ }
461
+ var mouseEvent = {
462
+ type : mouseEventType ,
446
463
button : 0 ,
447
- pageX : touchX ,
448
- pageY : touchY
464
+ pageX : firstTouch . clientX ,
465
+ pageY : firstTouch . clientY
466
+ } ;
467
+ SDL . events . push ( mouseEvent ) ;
468
+
469
+ for ( i = 0 ; i < touches . length ; i ++ ) {
470
+ var touch = touches [ i ] ;
471
+ SDL . events . push ( {
472
+ type : event . type ,
473
+ touch : touch
474
+ } ) ;
449
475
} ;
450
- SDL . events . push ( event ) ;
451
476
break ;
452
- case 'touchend' :
477
+ }
478
+ case 'touchend' : {
453
479
event . preventDefault ( ) ;
454
- event = {
480
+
481
+ // Remove the entry in the SDL.downFingers hash
482
+ // because the finger is no longer down.
483
+ for ( var i = 0 ; i < event . changedTouches . length ; i ++ ) {
484
+ var touch = event . changedTouches [ i ] ;
485
+ if ( SDL . downFingers [ touch . identifier ] === true ) {
486
+ delete SDL . downFingers [ touch . identifier ] ;
487
+ }
488
+ }
489
+
490
+ var mouseEvent = {
455
491
type : 'mouseup' ,
456
492
button : 0 ,
457
- pageX : touchX ,
458
- pageY : touchY
493
+ pageX : event . changedTouches [ 0 ] . clientX ,
494
+ pageY : event . changedTouches [ 0 ] . clientY
459
495
} ;
460
496
SDL . DOMButtons [ 0 ] = 0 ;
461
- SDL . events . push ( event ) ;
497
+ SDL . events . push ( mouseEvent ) ;
498
+
499
+ for ( i = 0 ; i < event . changedTouches . length ; i ++ ) {
500
+ var touch = event . changedTouches [ i ] ;
501
+ SDL . events . push ( {
502
+ type : 'touchend' ,
503
+ touch : touch
504
+ } ) ;
505
+ } ;
462
506
break ;
507
+ }
463
508
case 'mousemove' :
509
+ if ( SDL . DOMButtons [ 0 ] === 1 ) {
510
+ SDL . events . push ( {
511
+ type : 'touchmove' ,
512
+ touch : {
513
+ identifier : 0 ,
514
+ deviceID : { { { cDefine ( 'SDL_TOUCH_MOUSEID' ) } } } ,
515
+ pageX : event . pageX ,
516
+ pageY : event . pageY
517
+ }
518
+ } ) ;
519
+ }
464
520
if ( Browser . pointerLock ) {
465
521
// workaround for firefox bug 750111
466
522
if ( 'mozMovementX' in event ) {
@@ -502,13 +558,31 @@ var LibrarySDL = {
502
558
} ;
503
559
} else if ( event . type == 'mousedown' ) {
504
560
SDL . DOMButtons [ event . button ] = 1 ;
561
+ SDL . events . push ( {
562
+ type : 'touchstart' ,
563
+ touch : {
564
+ identifier : 0 ,
565
+ deviceID : { { { cDefine ( 'SDL_TOUCH_MOUSEID' ) } } } ,
566
+ pageX : event . pageX ,
567
+ pageY : event . pageY
568
+ }
569
+ } ) ;
505
570
} else if ( event . type == 'mouseup' ) {
506
571
// ignore extra ups, can happen if we leave the canvas while pressing down, then return,
507
572
// since we add a mouseup in that case
508
573
if ( ! SDL . DOMButtons [ event . button ] ) {
509
574
return ;
510
575
}
511
576
577
+ SDL . events . push ( {
578
+ type : 'touchend' ,
579
+ touch : {
580
+ identifier : 0 ,
581
+ deviceID : { { { cDefine ( 'SDL_TOUCH_MOUSEID' ) } } } ,
582
+ pageX : event . pageX ,
583
+ pageY : event . pageY
584
+ }
585
+ } ) ;
512
586
SDL . DOMButtons [ event . button ] = 0 ;
513
587
}
514
588
@@ -600,6 +674,10 @@ var LibrarySDL = {
600
674
event . handled = true ;
601
675
602
676
switch ( event . type ) {
677
+ case 'touchstart' : case 'touchend' : case 'touchmove' : {
678
+ Browser . calculateMouseEvent ( event ) ;
679
+ break ;
680
+ }
603
681
case 'keydown' : case 'keyup' : {
604
682
var down = event . type === 'keydown' ;
605
683
var code = event . keyCode ;
@@ -690,20 +768,50 @@ var LibrarySDL = {
690
768
if ( event . type != 'mousemove' ) {
691
769
var down = event . type === 'mousedown' ;
692
770
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . type , 'SDL.DOMEventToSDLEvent[event.type]' , 'i32' ) } } } ;
771
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . timestamp , '0' , 'i32' ) } } } ;
772
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . windowID , '0' , 'i32' ) } } } ;
773
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . which , '0' , 'i32' ) } } } ;
693
774
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . button , 'event.button+1' , 'i8' ) } } } ; // DOM buttons are 0-2, SDL 1-3
694
775
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . state , 'down ? 1 : 0' , 'i8' ) } } } ;
695
776
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . x , 'Browser.mouseX' , 'i32' ) } } } ;
696
777
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseButtonEvent . y , 'Browser.mouseY' , 'i32' ) } } } ;
697
778
} else {
698
779
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . type , 'SDL.DOMEventToSDLEvent[event.type]' , 'i32' ) } } } ;
699
- { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . state , 'SDL.buttonState' , 'i8' ) } } } ;
780
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . timestamp , '0' , 'i32' ) } } } ;
781
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . windowID , '0' , 'i32' ) } } } ;
782
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . which , '0' , 'i32' ) } } } ;
783
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . state , 'SDL.buttonState' , 'i32' ) } } } ;
700
784
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . x , 'Browser.mouseX' , 'i32' ) } } } ;
701
785
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . y , 'Browser.mouseY' , 'i32' ) } } } ;
702
786
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . xrel , 'Browser.mouseMovementX' , 'i32' ) } } } ;
703
787
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_MouseMotionEvent . yrel , 'Browser.mouseMovementY' , 'i32' ) } } } ;
704
788
}
705
789
break ;
706
790
}
791
+ case 'touchstart' : case 'touchend' : case 'touchmove' : {
792
+ var touch = event . touch ;
793
+ var w = Module [ 'canvas' ] . width ;
794
+ var h = Module [ 'canvas' ] . height ;
795
+ var x = Browser . touches [ touch . identifier ] . x / w ;
796
+ var y = Browser . touches [ touch . identifier ] . y / h ;
797
+ var lx = Browser . lastTouches [ touch . identifier ] . x / w ;
798
+ var ly = Browser . lastTouches [ touch . identifier ] . y / h ;
799
+ var dx = x - lx ;
800
+ var dy = y - ly ;
801
+ if ( touch [ 'deviceID' ] === undefined )
802
+ touch . deviceID = SDL . TOUCH_DEFAULT_ID ;
803
+ if ( dx === 0 && dy === 0 && event . type === 'touchmove' ) return ; // don't send these if nothing happened
804
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . type , 'SDL.DOMEventToSDLEvent[event.type]' , 'i32' ) } } } ;
805
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . timestamp , '0' , 'i32' ) } } } ; // XXX michaeljbishop - Unimplemented for now
806
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . touchId , 'touch.deviceID' , 'i64' ) } } } ;
807
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . fingerId , 'touch.identifier' , 'i64' ) } } } ;
808
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . x , 'x' , 'float' ) } } } ;
809
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . y , 'y' , 'float' ) } } } ;
810
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . dx , 'dx' , 'float' ) } } } ;
811
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . dy , 'dy' , 'float' ) } } } ;
812
+ { { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_TouchFingerEvent . pressure , 'touch.force' , 'float' ) } } } ;
813
+ break ;
814
+ }
707
815
case 'unload' : {
708
816
{ { { makeSetValue ( 'ptr' , C_STRUCTS . SDL_KeyboardEvent . type , 'SDL.DOMEventToSDLEvent[event.type]' , 'i32' ) } } } ;
709
817
break ;
@@ -948,14 +1056,17 @@ var LibrarySDL = {
948
1056
SDL . keyboardState = _malloc ( 0x10000 ) ; // Our SDL needs 512, but 64K is safe for older SDLs
949
1057
_memset ( SDL . keyboardState , 0 , 0x10000 ) ;
950
1058
// Initialize this structure carefully for closure
951
- SDL . DOMEventToSDLEvent [ 'keydown' ] = 0x300 /* SDL_KEYDOWN */ ;
952
- SDL . DOMEventToSDLEvent [ 'keyup' ] = 0x301 /* SDL_KEYUP */ ;
953
- SDL . DOMEventToSDLEvent [ 'keypress' ] = 0x303 /* SDL_TEXTINPUT */ ;
954
- SDL . DOMEventToSDLEvent [ 'mousedown' ] = 0x401 /* SDL_MOUSEBUTTONDOWN */ ;
955
- SDL . DOMEventToSDLEvent [ 'mouseup' ] = 0x402 /* SDL_MOUSEBUTTONUP */ ;
956
- SDL . DOMEventToSDLEvent [ 'mousemove' ] = 0x400 /* SDL_MOUSEMOTION */ ;
957
- SDL . DOMEventToSDLEvent [ 'unload' ] = 0x100 /* SDL_QUIT */ ;
958
- SDL . DOMEventToSDLEvent [ 'resize' ] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */ ;
1059
+ SDL . DOMEventToSDLEvent [ 'keydown' ] = 0x300 /* SDL_KEYDOWN */ ;
1060
+ SDL . DOMEventToSDLEvent [ 'keyup' ] = 0x301 /* SDL_KEYUP */ ;
1061
+ SDL . DOMEventToSDLEvent [ 'keypress' ] = 0x303 /* SDL_TEXTINPUT */ ;
1062
+ SDL . DOMEventToSDLEvent [ 'mousedown' ] = 0x401 /* SDL_MOUSEBUTTONDOWN */ ;
1063
+ SDL . DOMEventToSDLEvent [ 'mouseup' ] = 0x402 /* SDL_MOUSEBUTTONUP */ ;
1064
+ SDL . DOMEventToSDLEvent [ 'mousemove' ] = 0x400 /* SDL_MOUSEMOTION */ ;
1065
+ SDL . DOMEventToSDLEvent [ 'touchstart' ] = 0x700 /* SDL_FINGERDOWN */ ;
1066
+ SDL . DOMEventToSDLEvent [ 'touchend' ] = 0x701 /* SDL_FINGERUP */ ;
1067
+ SDL . DOMEventToSDLEvent [ 'touchmove' ] = 0x702 /* SDL_FINGERMOTION */ ;
1068
+ SDL . DOMEventToSDLEvent [ 'unload' ] = 0x100 /* SDL_QUIT */ ;
1069
+ SDL . DOMEventToSDLEvent [ 'resize' ] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */ ;
959
1070
// These are not technically DOM events; the HTML gamepad API is poll-based.
960
1071
// However, we define them here, as the rest of the SDL code assumes that
961
1072
// all SDL events originate as DOM events.
@@ -1025,7 +1136,7 @@ var LibrarySDL = {
1025
1136
} ,
1026
1137
1027
1138
SDL_SetVideoMode : function ( width , height , depth , flags ) {
1028
- [ 'mousedown' , 'mouseup' , 'mousemove' , 'DOMMouseScroll' , 'mousewheel' , 'mouseout' ] . forEach ( function ( event ) {
1139
+ [ 'touchstart' , 'touchend' , 'touchmove' , ' mousedown', 'mouseup' , 'mousemove' , 'DOMMouseScroll' , 'mousewheel' , 'mouseout' ] . forEach ( function ( event ) {
1029
1140
Module [ 'canvas' ] . addEventListener ( event , SDL . receiveEvent , true ) ;
1030
1141
} ) ;
1031
1142
@@ -1476,20 +1587,28 @@ var LibrarySDL = {
1476
1587
return 0 ;
1477
1588
} ,
1478
1589
1479
- SDL_PeepEvents : function ( events , numEvents , action , from , to ) {
1590
+ SDL_PeepEvents : function ( events , requestedEventCount , action , from , to ) {
1480
1591
switch ( action ) {
1481
1592
case 2 : { // SDL_GETEVENT
1482
- assert ( numEvents == 1 ) ;
1483
- var got = 0 ;
1484
- while ( SDL . events . length > 0 && numEvents > 0 ) {
1485
- var type = SDL . DOMEventToSDLEvent [ SDL . events [ 0 ] . type ] ;
1486
- if ( type < from || type > to ) break ;
1487
- SDL . makeCEvent ( SDL . events . shift ( ) , events ) ;
1488
- got ++ ;
1489
- numEvents -- ;
1490
- // events += sizeof(..)
1593
+ // We only handle 1 event right now
1594
+ assert ( requestedEventCount == 1 ) ;
1595
+
1596
+ var index = 0 ;
1597
+ var retrievedEventCount = 0 ;
1598
+ // this should look through the entire queue until it has filled up the events
1599
+ // array
1600
+ while ( index < SDL . events . length && retrievedEventCount < requestedEventCount ) {
1601
+ var event = SDL . events [ index ] ;
1602
+ var type = SDL . DOMEventToSDLEvent [ event . type ] ;
1603
+ if ( from <= type && type <= to ) {
1604
+ SDL . makeCEvent ( event , events ) ;
1605
+ SDL . events . splice ( index , 1 ) ;
1606
+ retrievedEventCount ++ ;
1607
+ } else {
1608
+ index ++ ;
1609
+ }
1491
1610
}
1492
- return got ;
1611
+ return retrievedEventCount ;
1493
1612
}
1494
1613
default : throw 'SDL_PeepEvents does not yet support that action: ' + action ;
1495
1614
}
0 commit comments