2014-03-28 02:50:40 +01:00
using System ;
2017-04-30 15:42:09 +02:00
2015-02-08 22:51:52 +01:00
namespace DS4Windows
2014-03-28 02:50:40 +01:00
{
public class TouchpadEventArgs : EventArgs
{
public readonly Touch [ ] touches = null ;
2014-03-29 06:29:08 +01:00
public readonly System . DateTime timeStamp ;
2014-03-28 02:50:40 +01:00
public readonly bool touchButtonPressed ;
2014-03-29 06:29:08 +01:00
public TouchpadEventArgs ( System . DateTime utcTimestamp , bool tButtonDown , Touch t0 , Touch t1 = null )
2014-03-28 02:50:40 +01:00
{
if ( t1 ! = null )
{
touches = new Touch [ 2 ] ;
touches [ 0 ] = t0 ;
touches [ 1 ] = t1 ;
}
else if ( t0 ! = null )
{
touches = new Touch [ 1 ] ;
touches [ 0 ] = t0 ;
}
touchButtonPressed = tButtonDown ;
2014-03-29 06:29:08 +01:00
this . timeStamp = utcTimestamp ;
2014-03-28 02:50:40 +01:00
}
}
public class Touch
{
public readonly int hwX , hwY , deltaX , deltaY ;
public readonly byte touchID ;
public readonly Touch previousTouch ;
public Touch ( int X , int Y , byte tID , Touch prevTouch = null )
{
hwX = X ;
hwY = Y ;
touchID = tID ;
previousTouch = prevTouch ;
if ( previousTouch ! = null )
{
deltaX = X - previousTouch . hwX ;
deltaY = Y - previousTouch . hwY ;
}
}
}
public class DS4Touchpad
{
2014-03-29 06:29:08 +01:00
public event EventHandler < TouchpadEventArgs > TouchesBegan = null ; // finger one or two landed (or both, or one then two, or two then one; any touches[] count increase)
public event EventHandler < TouchpadEventArgs > TouchesMoved = null ; // deltaX/deltaY are set because one or both fingers were already down on a prior sensor reading
public event EventHandler < TouchpadEventArgs > TouchesEnded = null ; // all fingers lifted
public event EventHandler < TouchpadEventArgs > TouchButtonDown = null ; // touchpad pushed down until the button clicks
public event EventHandler < TouchpadEventArgs > TouchButtonUp = null ; // touchpad button released
public event EventHandler < EventArgs > TouchUnchanged = null ; // no status change for the touchpad itself... but other sensors may have changed, or you may just want to do some processing
2014-03-28 02:50:40 +01:00
public readonly static int TOUCHPAD_DATA_OFFSET = 35 ;
2014-03-29 06:29:08 +01:00
internal int lastTouchPadX1 , lastTouchPadY1 ,
2014-03-28 02:50:40 +01:00
lastTouchPadX2 , lastTouchPadY2 ; // tracks 0, 1 or 2 touches; we maintain touch 1 and 2 separately
2014-03-29 06:29:08 +01:00
internal bool lastTouchPadIsDown ;
internal bool lastIsActive1 , lastIsActive2 ;
internal byte lastTouchID1 , lastTouchID2 ;
internal byte [ ] previousPacket = new byte [ 8 ] ;
2014-03-28 02:50:40 +01:00
2014-03-29 06:29:08 +01:00
// We check everything other than the not bothering with not-very-useful TouchPacketCounter.
private bool PacketChanged ( byte [ ] data , int touchPacketOffset )
{
bool changed = false ;
for ( int i = 0 ; i < previousPacket . Length ; i + + )
{
byte oldValue = previousPacket [ i ] ;
previousPacket [ i ] = data [ i + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] ;
if ( previousPacket [ i ] ! = oldValue )
changed = true ;
}
return changed ;
}
public void handleTouchpad ( byte [ ] data , DS4State sensors , int touchPacketOffset = 0 )
2014-03-28 02:50:40 +01:00
{
bool touchPadIsDown = sensors . TouchButton ;
2014-03-29 06:29:08 +01:00
if ( ! PacketChanged ( data , touchPacketOffset ) & & touchPadIsDown = = lastTouchPadIsDown )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( TouchUnchanged ! = null )
TouchUnchanged ( this , EventArgs . Empty ) ;
return ;
}
byte touchID1 = ( byte ) ( data [ 0 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] & 0x7F ) ;
byte touchID2 = ( byte ) ( data [ 4 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] & 0x7F ) ;
int currentX1 = data [ 1 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] + ( ( data [ 2 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] & 0xF ) * 255 ) ;
int currentY1 = ( ( data [ 2 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] & 0xF0 ) > > 4 ) + ( data [ 3 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] * 16 ) ;
int currentX2 = data [ 5 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] + ( ( data [ 6 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] & 0xF ) * 255 ) ;
int currentY2 = ( ( data [ 6 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] & 0xF0 ) > > 4 ) + ( data [ 7 + TOUCHPAD_DATA_OFFSET + touchPacketOffset ] * 16 ) ;
TouchpadEventArgs args ;
if ( sensors . Touch1 | | sensors . Touch2 )
{
if ( ( sensors . Touch1 & & ! lastIsActive1 ) | | ( sensors . Touch2 & & ! lastIsActive2 ) )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( TouchesBegan ! = null )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( sensors . Touch1 & & sensors . Touch2 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX1 , currentY1 , touchID1 ) , new Touch ( currentX2 , currentY2 , touchID2 ) ) ;
else if ( sensors . Touch1 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX1 , currentY1 , touchID1 ) ) ;
else
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX2 , currentY2 , touchID2 ) ) ;
TouchesBegan ( this , args ) ;
2014-03-28 02:50:40 +01:00
}
}
2014-03-29 06:29:08 +01:00
else if ( sensors . Touch1 = = lastIsActive1 & & sensors . Touch2 = = lastIsActive2 & & TouchesMoved ! = null )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
Touch tPrev , t0 , t1 ;
if ( sensors . Touch1 & & sensors . Touch2 )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
tPrev = new Touch ( lastTouchPadX1 , lastTouchPadY1 , lastTouchID1 ) ;
t0 = new Touch ( currentX1 , currentY1 , touchID1 , tPrev ) ;
tPrev = new Touch ( lastTouchPadX2 , lastTouchPadY2 , lastTouchID2 ) ;
t1 = new Touch ( currentX2 , currentY2 , touchID2 , tPrev ) ;
}
else if ( sensors . Touch1 )
{
tPrev = new Touch ( lastTouchPadX1 , lastTouchPadY1 , lastTouchID1 ) ;
t0 = new Touch ( currentX1 , currentY1 , touchID1 , tPrev ) ;
t1 = null ;
2014-03-28 02:50:40 +01:00
}
else
2014-03-29 06:29:08 +01:00
{
tPrev = new Touch ( lastTouchPadX2 , lastTouchPadY2 , lastTouchID2 ) ;
t0 = new Touch ( currentX2 , currentY2 , touchID2 , tPrev ) ;
t1 = null ;
}
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , t0 , t1 ) ;
TouchesMoved ( this , args ) ;
2014-03-28 02:50:40 +01:00
}
2014-03-29 06:29:08 +01:00
if ( ! lastTouchPadIsDown & & touchPadIsDown & & TouchButtonDown ! = null )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( sensors . Touch1 & & sensors . Touch2 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX1 , currentY1 , touchID1 ) , new Touch ( currentX2 , currentY2 , touchID2 ) ) ;
else if ( sensors . Touch1 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX1 , currentY1 , touchID1 ) ) ;
2014-03-28 02:50:40 +01:00
else
2014-03-29 06:29:08 +01:00
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX2 , currentY2 , touchID2 ) ) ;
TouchButtonDown ( this , args ) ;
2014-03-28 02:50:40 +01:00
}
2014-03-29 06:29:08 +01:00
else if ( lastTouchPadIsDown & & ! touchPadIsDown & & TouchButtonUp ! = null )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( sensors . Touch1 & & sensors . Touch2 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX1 , currentY1 , touchID1 ) , new Touch ( currentX2 , currentY2 , touchID2 ) ) ;
else if ( sensors . Touch1 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX1 , currentY1 , touchID1 ) ) ;
else
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( currentX2 , currentY2 , touchID2 ) ) ;
2014-03-28 02:50:40 +01:00
2014-03-29 06:29:08 +01:00
TouchButtonUp ( this , args ) ;
2014-03-28 02:50:40 +01:00
}
2014-03-29 06:29:08 +01:00
if ( sensors . Touch1 )
{
lastTouchPadX1 = currentX1 ;
lastTouchPadY1 = currentY1 ;
}
if ( sensors . Touch2 )
{
lastTouchPadX2 = currentX2 ;
lastTouchPadY2 = currentY2 ;
}
2014-03-28 02:50:40 +01:00
lastTouchPadIsDown = touchPadIsDown ;
}
else
{
2014-03-29 06:29:08 +01:00
if ( touchPadIsDown & & ! lastTouchPadIsDown )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( TouchButtonDown ! = null )
TouchButtonDown ( this , new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , null , null ) ) ;
2014-03-28 02:50:40 +01:00
}
2014-03-29 06:29:08 +01:00
else if ( ! touchPadIsDown & & lastTouchPadIsDown )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( TouchButtonUp ! = null )
TouchButtonUp ( this , new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , null , null ) ) ;
2014-03-28 02:50:40 +01:00
}
2014-03-29 06:29:08 +01:00
if ( ( lastIsActive1 | | lastIsActive2 ) & & TouchesEnded ! = null )
2014-03-28 02:50:40 +01:00
{
2014-03-29 06:29:08 +01:00
if ( lastIsActive1 & & lastIsActive2 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( lastTouchPadX1 , lastTouchPadY1 , touchID1 ) , new Touch ( lastTouchPadX2 , lastTouchPadY2 , touchID2 ) ) ;
else if ( lastIsActive1 )
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( lastTouchPadX1 , lastTouchPadY1 , touchID1 ) ) ;
else
args = new TouchpadEventArgs ( sensors . ReportTimeStamp , sensors . TouchButton , new Touch ( lastTouchPadX2 , lastTouchPadY2 , touchID2 ) ) ;
TouchesEnded ( this , args ) ;
2014-03-28 02:50:40 +01:00
}
}
2014-03-29 06:29:08 +01:00
lastIsActive1 = sensors . Touch1 ;
2014-03-28 02:50:40 +01:00
lastIsActive2 = sensors . Touch2 ;
2014-03-29 06:29:08 +01:00
lastTouchID1 = touchID1 ;
2014-03-28 02:50:40 +01:00
lastTouchID2 = touchID2 ;
lastTouchPadIsDown = touchPadIsDown ;
}
}
}