Multitouch support implemented and working for SDL2 backend.

This commit is contained in:
spartanj@gmail.com
2012-06-03 23:54:01 -03:00
parent cd8a9486f9
commit 26da071857
12 changed files with 393 additions and 38 deletions

View File

@@ -44,6 +44,10 @@
#if !defined( EE_GLES1 ) && !defined( EE_GLES2 )
#define EE_GLES2
#endif
#ifndef EE_PLATFORM_TOUCH
#define EE_PLATFORM_TOUCH
#endif
#endif
#if defined ( linux ) || defined( __linux__ ) \

View File

@@ -65,7 +65,11 @@ void cEETest::Init() {
PAK = eeNew( cZip, () );
PAK->Open( MyPath + "data/ee.zip" );
#if EE_PLATFORM == EE_PLATFORM_IOS
mWindow = EE->CreateWindow( WindowSettings( 960, 640, BitColor, WindowStyle::NoBorder ), ContextSettings( VSync, GLv_default, true, 0, 0 ) );
#else
mWindow = EE->CreateWindow( WindowSettings( mWidth, mHeight, BitColor, Style, "ee.png" ), ContextSettings( VSync, GLVer, true, 0, 0 ) );
#endif
run = ( mWindow->Created() && PAK->IsOpen() );
@@ -745,15 +749,19 @@ void cEETest::QuitClick( const cUIEvent * Event ) {
}
}
void cEETest::ShowMenu() {
if ( Menu->Show() ) {
eeVector2i Pos = mWindow->GetInput()->GetMousePos();
cUIMenu::FixMenuPos( Pos , Menu );
Menu->Pos( Pos );
}
}
void cEETest::MainClick( const cUIEvent * Event ) {
const cUIEventMouse * MouseEvent = reinterpret_cast<const cUIEventMouse*> ( Event );
if ( MouseEvent->Flags() & EE_BUTTON_RMASK ) {
if ( Menu->Show() ) {
eeVector2i Pos = MouseEvent->Pos();
cUIMenu::FixMenuPos( Pos , Menu );
Menu->Pos( Pos );
}
ShowMenu();
}
}
@@ -1376,6 +1384,15 @@ void cEETest::Input() {
if ( KM->IsKeyUp(KEY_6) && KM->ControlPressed() )
SetScreen( 5 );
#ifdef EE_PLATFORM_TOUCH
std::list<cInputFinger*> Fingers = KM->GetFingersDown();
std::list<cInputFinger*> FingersDown = KM->GetFingersWasDown();
if ( Fingers.size() == 1 && FingersDown.size() == 1 ) {
ShowMenu();
}
#endif
cJoystick * Joy = JM->GetJoystick(0);
if ( mJoyEnabled && NULL != Joy ) {
@@ -1567,9 +1584,20 @@ void cEETest::Particles() {
#define GRABABLE_MASK_BIT (1<<31)
#define NOT_GRABABLE_MASK (~GRABABLE_MASK_BIT)
void cEETest::Demo1Create() {
void cEETest::CreateJointAndBody() {
#ifndef EE_PLATFORM_TOUCH
mMouseJoint = NULL;
mMouseBody = eeNew( cBody, ( INFINITY, INFINITY ) );
#else
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
mMouseJoint[i] = NULL;
mMouseBody[i] = eeNew( cBody, ( INFINITY, INFINITY ) );
}
#endif
}
void cEETest::Demo1Create() {
CreateJointAndBody();
Physics::cShape::ResetShapeIdCounter();
@@ -1629,8 +1657,19 @@ void cEETest::Demo1Update() {
}
void cEETest::Demo1Destroy() {
void cEETest::DestroyBody() {
#ifndef EE_PLATFORM_TOUCH
eeSAFE_DELETE( mMouseBody );
#else
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
eeSAFE_DELETE( mMouseBody[i] );
}
#endif
}
void cEETest::Demo1Destroy() {
DestroyBody();
eeSAFE_DELETE( mSpace );
}
@@ -1657,10 +1696,19 @@ void cEETest::blockerSeparate( cArbiter *arb, cSpace * space, void *unused ) {
void cEETest::postStepRemove( cSpace *space, void * tshape, void * unused ) {
Physics::cShape * shape = reinterpret_cast<Physics::cShape*>( tshape );
#ifndef EE_PLATFORM_TOUCH
if ( NULL != mMouseJoint && ( mMouseJoint->A() == shape->Body() || mMouseJoint->B() == shape->Body() ) ) {
mSpace->RemoveConstraint( mMouseJoint );
eeSAFE_DELETE( mMouseJoint );
}
#else
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
if ( NULL != mMouseJoint[i] && ( mMouseJoint[i]->A() == shape->Body() || mMouseJoint[i]->B() == shape->Body() ) ) {
mSpace->RemoveConstraint( mMouseJoint[i] );
eeSAFE_DELETE( mMouseJoint[i] );
}
}
#endif
mSpace->RemoveBody( shape->Body() );
mSpace->RemoveShape( shape );
@@ -1681,8 +1729,7 @@ cpBool cEETest::catcherBarBegin(cArbiter *arb, Physics::cSpace *space, void *unu
}
void cEETest::Demo2Create() {
mMouseJoint = NULL;
mMouseBody = eeNew( cBody, ( INFINITY, INFINITY ) );
CreateJointAndBody();
Physics::cShape::ResetShapeIdCounter();
@@ -1737,7 +1784,7 @@ void cEETest::Demo2Update() {
}
void cEETest::Demo2Destroy() {
eeSAFE_DELETE( mMouseBody );
DestroyBody();
eeSAFE_DELETE( mSpace );
}
@@ -1780,7 +1827,8 @@ void cEETest::PhysicsCreate() {
ChangeDemo( 0 );
}
void cEETest::PhysicsUpdate() {
void cEETest::PhysicsUpdate() {
#ifndef EE_PLATFORM_TOUCH
mMousePoint = cVectNew( KM->GetMousePosf().x, KM->GetMousePosf().y );
cVect newPoint = tovect( cpvlerp( tocpv( mMousePoint_last ), tocpv( mMousePoint ), 0.25 ) );
mMouseBody->Pos( newPoint );
@@ -1804,6 +1852,34 @@ void cEETest::PhysicsUpdate() {
mSpace->RemoveConstraint( mMouseJoint );
eeSAFE_DELETE( mMouseJoint );
}
#else
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
cInputFinger * Finger = KM->GetFingerIndex(i);
mMousePoint[i] = cVectNew( Finger->x, Finger->y );
cVect newPoint = tovect( cpvlerp( tocpv( mMousePoint_last[i] ), tocpv( mMousePoint[i] ), 0.25 ) );
mMouseBody[i]->Pos( newPoint );
mMouseBody[i]->Vel( ( newPoint - mMousePoint_last[i] ) * (cpFloat)mWindow->FPS() );
mMousePoint_last[i] = newPoint;
if ( Finger->IsDown() ) {
if ( NULL == mMouseJoint[i] ) {
cVect point = cVectNew( Finger->x, Finger->y );
Physics::cShape * shape = mSpace->PointQueryFirst( point, GRABABLE_MASK_BIT, CP_NO_GROUP );
if( NULL != shape ){
mMouseJoint[i] = eeNew( cPivotJoint, ( mMouseBody[i], shape->Body(), cVectZero, shape->Body()->World2Local( point ) ) );
mMouseJoint[i]->MaxForce( 50000.0f );
mSpace->AddConstraint( mMouseJoint[i] );
}
}
} else if ( NULL != mMouseJoint[i] ) {
mSpace->RemoveConstraint( mMouseJoint[i] );
eeSAFE_DELETE( mMouseJoint[i] );
}
}
#endif
mDemo[ mCurDemo ].update();
mSpace->Update();

View File

@@ -59,11 +59,11 @@ enum CollisionTypes {
CATCH_SENSOR_TYPE
};
typedef struct Emitter {
struct Emitter {
int queue;
int blocked;
cVect position;
} Emitter;
};
class cEETest : private cThread {
public:
@@ -235,10 +235,19 @@ class cEETest : private cThread {
cTextCache mInfoText;
cSpace * mSpace;
#ifndef EE_PLATFORM_TOUCH
cBody * mMouseBody;
cVect mMousePoint;
cVect mMousePoint_last;
cConstraint * mMouseJoint;
#else
cBody * mMouseBody[ EE_MAX_FINGERS ];
cVect mMousePoint[ EE_MAX_FINGERS ];
cVect mMousePoint_last[ EE_MAX_FINGERS ];
cConstraint * mMouseJoint[ EE_MAX_FINGERS ];
#endif
void PhysicsCreate();
void PhysicsUpdate();
void PhysicsDestroy();
@@ -258,6 +267,8 @@ class cEETest : private cThread {
void Demo2Update();
void Demo2Destroy();
void ShowMenu();
Emitter emitterInstance;
void ChangeDemo( Uint32 num );
@@ -282,6 +293,10 @@ class cEETest : private cThread {
void OnETGEditorClose();
void CreateETGEditor();
void CreateJointAndBody();
void DestroyBody();
};
#endif

View File

@@ -28,6 +28,10 @@ void cUIPopUpMenu::SetTheme( cUITheme * Theme ) {
bool cUIPopUpMenu::Show() {
if ( !Visible() || 0.f == mAlpha ) {
#ifdef EE_PLATFORM_TOUCH
mTE.Reset();
#endif
Enabled( true );
Visible( true );
@@ -81,14 +85,20 @@ Uint32 cUIPopUpMenu::OnMessage( const cUIMessage * Msg ) {
switch ( Msg->Msg() ) {
case cUIMessage::MsgMouseUp:
{
if ( !Msg->Sender()->IsType( UI_TYPE_MENUSUBMENU ) && ( Msg->Flags() & EE_BUTTONS_LRM ) ) {
SendCommonEvent( cUIEvent::EventOnHideByClick );
#ifdef EE_PLATFORM_TOUCH
if ( mTE.Elapsed() > 250.f ) {
#endif
if ( !Msg->Sender()->IsType( UI_TYPE_MENUSUBMENU ) && ( Msg->Flags() & EE_BUTTONS_LRM ) ) {
SendCommonEvent( cUIEvent::EventOnHideByClick );
if ( Visible() )
cUIManager::instance()->MainControl()->SetFocus();
if ( Visible() )
cUIManager::instance()->MainControl()->SetFocus();
Hide();
Hide();
}
#ifdef EE_PLATFORM_TOUCH
}
#endif
}
}

View File

@@ -24,6 +24,10 @@ class EE_API cUIPopUpMenu : public cUIMenu {
virtual void OnComplexControlFocusLoss();
virtual Uint32 OnMessage( const cUIMessage * Msg );
#ifdef EE_PLATFORM_TOUCH
cTimeElapsed mTE;
#endif
};
}}

View File

@@ -28,6 +28,8 @@ void cInputSDL::Update() {
CleanStates();
/** TODO: Filter by windowId */
while ( SDL_PollEvent( &SDLEvent ) ) {
switch( SDLEvent.type ) {
case SDL_WINDOWEVENT:
@@ -202,38 +204,49 @@ void cInputSDL::Update() {
EEEvent.Type = InputEvent::MouseButtonUp;
EEEvent.button.state = 0;
break;
}/*
case SDL_FINGERDOWN:
{
EEEvent.Type = InputEvent::FingerDown;
EEEvent.finger.button = 1;
EEEvent.finger.which = SDLEvent.tfinger.windowID;
EEEvent.finger.state = SDLEvent.tfinger.state;
EEEvent.finger.x = SDLEvent.tfinger.x;
EEEvent.finger.y = SDLEvent.tfinger.y;
break;
}
case SDL_FINGERMOTION:
{
EEEvent.Type = InputEvent::FingerMotion;
EEEvent.finger.which = SDLEvent.tfinger.windowID;
EEEvent.finger.timestamp = SDLEvent.tfinger.timestamp;
EEEvent.finger.touchId = SDLEvent.tfinger.touchId;
EEEvent.finger.fingerId = SDLEvent.tfinger.fingerId;
EEEvent.finger.state = SDLEvent.tfinger.state;
EEEvent.finger.x = SDLEvent.tfinger.x;
EEEvent.finger.y = SDLEvent.tfinger.y;
EEEvent.finger.xrel = SDLEvent.tfinger.dx;
EEEvent.finger.yrel = SDLEvent.tfinger.dy;
EEEvent.finger.dx = SDLEvent.tfinger.dx;
EEEvent.finger.dy = SDLEvent.tfinger.dy;
EEEvent.finger.pressure = SDLEvent.tfinger.pressure;
break;
}
case SDL_FINGERDOWN:
{
EEEvent.Type = InputEvent::FingerDown;
EEEvent.finger.timestamp = SDLEvent.tfinger.timestamp;
EEEvent.finger.touchId = SDLEvent.tfinger.touchId;
EEEvent.finger.fingerId = SDLEvent.tfinger.fingerId;
EEEvent.finger.state = SDLEvent.tfinger.state;
EEEvent.finger.x = SDLEvent.tfinger.x;
EEEvent.finger.y = SDLEvent.tfinger.y;
EEEvent.finger.dx = SDLEvent.tfinger.dx;
EEEvent.finger.dy = SDLEvent.tfinger.dy;
EEEvent.finger.pressure = SDLEvent.tfinger.pressure;
break;
}
case SDL_FINGERUP:
{
EEEvent.Type = InputEvent::FingerUp;
EEEvent.finger.button = 1;
EEEvent.finger.which = SDLEvent.tfinger.windowID;
EEEvent.finger.timestamp = SDLEvent.tfinger.timestamp;
EEEvent.finger.touchId = SDLEvent.tfinger.touchId;
EEEvent.finger.fingerId = SDLEvent.tfinger.fingerId;
EEEvent.finger.state = SDLEvent.tfinger.state;
EEEvent.finger.x = SDLEvent.tfinger.x;
EEEvent.finger.y = SDLEvent.tfinger.y;
EEEvent.finger.dx = SDLEvent.tfinger.dx;
EEEvent.finger.dy = SDLEvent.tfinger.dy;
EEEvent.finger.pressure = SDLEvent.tfinger.pressure;
break;
}*/
}
case SDL_JOYAXISMOTION:
{
EEEvent.Type = InputEvent::JoyAxisMotion;

View File

@@ -29,6 +29,8 @@ void cInput::CleanStates() {
mLastPressTrigger = mPressTrigger;
mClickTrigger = 0;
mDoubleClickTrigger = 0;
ResetFingerWasDown();
}
void cInput::SendEvent( InputEvent * Event ) {
@@ -149,6 +151,49 @@ void cInput::ProcessEvent( InputEvent * Event ) {
break;
}
case InputEvent::FingerDown:
{
cInputFinger * Finger = GetFingerId( Event->finger.fingerId );
Finger->WriteLast();
Finger->x = (Uint16)( ( (eeFloat)Event->finger.x / (eeFloat)32768 ) * (eeFloat)mWindow->GetWidth() );
Finger->y = (Uint16)( ( (eeFloat)Event->finger.y / (eeFloat)32768 ) * (eeFloat)mWindow->GetHeight() );
Finger->pressure = Event->finger.pressure;
Finger->down = true;
Finger->xdelta = Event->finger.dx;
Finger->ydelta = Event->finger.dy;
break;
}
case InputEvent::FingerUp:
{
cInputFinger * Finger = GetFingerId( Event->finger.fingerId );
Finger->WriteLast();
Finger->x = (Uint16)( ( (eeFloat)Event->finger.x / (eeFloat)32768 ) * (eeFloat)mWindow->GetWidth() );
Finger->y = (Uint16)( ( (eeFloat)Event->finger.y / (eeFloat)32768 ) * (eeFloat)mWindow->GetHeight() );
Finger->pressure = Event->finger.pressure;
Finger->down = false;
Finger->was_down = true;
Finger->xdelta = Event->finger.dx;
Finger->ydelta = Event->finger.dy;
break;
}
case InputEvent::FingerMotion:
{
cInputFinger * Finger = GetFingerId( Event->finger.fingerId );
Finger->WriteLast();
Finger->x = (Uint16)( ( (eeFloat)Event->finger.x / (eeFloat)32768 ) * (eeFloat)mWindow->GetWidth() );
Finger->y = (Uint16)( ( (eeFloat)Event->finger.y / (eeFloat)32768 ) * (eeFloat)mWindow->GetHeight() );
Finger->pressure = Event->finger.pressure;
Finger->down = true;
Finger->xdelta = Event->finger.dx;
Finger->ydelta = Event->finger.dy;
break;
}
case InputEvent::VideoResize:
{
mWindow->Size( Event->resize.w, Event->resize.h, mWindow->Windowed() );
@@ -164,6 +209,40 @@ void cInput::ProcessEvent( InputEvent * Event ) {
SendEvent( Event );
}
cInputFinger * cInput::GetFingerId( const Int64 &fingerId ) {
Uint32 i;
for ( i = 0; i < EE_MAX_FINGERS; i++ ) {
if ( mFingers[i].id == fingerId ) {
return &mFingers[i];
}
}
for ( i = 0; i < EE_MAX_FINGERS; i++ ) {
if ( -1 == mFingers[i].id ) {
mFingers[i].id = fingerId;
return &mFingers[i];
}
}
//! Find first unused
for ( i = 0; i < EE_MAX_FINGERS; i++ ) {
if ( !mFingers[i].down ) {
mFingers[i].id = fingerId;
return &mFingers[i];
}
}
return NULL;
}
void cInput::ResetFingerWasDown() {
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
mFingers[i].was_down = false;
}
}
bool cInput::GetKey( Uint8 * Key, Uint8 Pos ) {
if ( ( * Key ) & ( 1 << Pos ) )
return true;
@@ -356,4 +435,43 @@ cJoystickManager * cInput::GetJoystickManager() const {
return mJoystickManager;
}
cInputFinger * cInput::GetFingerIndex( const Uint32 &Index ) {
eeASSERT( Index < EE_MAX_FINGERS );
return &mFingers[Index];
}
cInputFinger * cInput::GetFinger( const Int64 &fingerId ) {
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
if ( mFingers[i].id == fingerId ) {
return &mFingers[i];
}
}
return NULL;
}
std::list<cInputFinger *> cInput::GetFingersDown() {
std::list<cInputFinger *> fDown;
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
if ( mFingers[i].down ) {
fDown.push_back( &mFingers[i] );
}
}
return fDown;
}
std::list<cInputFinger *> cInput::GetFingersWasDown() {
std::list<cInputFinger *> fDown;
for ( Uint32 i = 0; i < EE_MAX_FINGERS; i++ ) {
if ( mFingers[i].was_down ) {
fDown.push_back( &mFingers[i] );
}
}
return fDown;
}
}}

View File

@@ -6,6 +6,7 @@
#include "inputhelper.hpp"
#include "inputevent.hpp"
#include "cjoystickmanager.hpp"
#include "cinputfinger.hpp"
namespace EE { namespace Window {
@@ -149,11 +150,24 @@ class EE_API cInput {
/** Set the double click interval in milliseconds */
void DoubleClickInterval( const Uint32& Interval );
/** Clean the keyboard and mouse states */
void CleanStates();
/** Send an input event to the window */
void SendEvent( InputEvent * Event );
/** @return The joystick manager */
cJoystickManager * GetJoystickManager() const;
const Uint32& GetFingerCount();
cInputFinger * GetFingerIndex( const Uint32& Index );
cInputFinger * GetFinger( const Int64& fingerId );
std::list<cInputFinger *> GetFingersDown();
std::list<cInputFinger *> GetFingersWasDown();
protected:
friend class cWindow;
@@ -183,6 +197,7 @@ class EE_API cInput {
Uint32 mNumCallBacks;
eeFloat mMouseSpeed;
bool mInputGrabed;
cInputFinger mFingers[ EE_MAX_FINGERS ];
std::map<Uint32, InputCallback> mCallbacks;
@@ -191,6 +206,10 @@ class EE_API cInput {
void PushKey( Uint8 * Key, Uint8 Pos, bool BitWrite );
void ProcessEvent( InputEvent * Event );
cInputFinger * GetFingerId( const Int64& fingerId );
void ResetFingerWasDown();
};
}}

View File

@@ -0,0 +1,38 @@
#include "cinputfinger.hpp"
namespace EE { namespace Window {
cInputFinger::cInputFinger() :
id(-1),
x(0),
y(0),
pressure(0),
xdelta(0),
ydelta(0),
last_x(0),
last_y(0),
last_pressure(0),
down(false),
was_down(false)
{
}
bool cInputFinger::IsDown() {
return down;
}
bool cInputFinger::WasDown() {
return was_down;
}
eeVector2i cInputFinger::Pos() {
return eeVector2i( x, y );
}
void cInputFinger::WriteLast() {
last_x = x;
last_y = y;
last_pressure = pressure;
}
}}

View File

@@ -0,0 +1,39 @@
#ifndef EE_WINDOW_CINPUTFINGER_HPP
#define EE_WINDOW_CINPUTFINGER_HPP
#include "base.hpp"
namespace EE { namespace Window {
#define EE_MAX_FINGERS (10)
class cInputFinger {
public:
cInputFinger();
Int64 id;
Uint16 x;
Uint16 y;
Uint16 pressure;
Uint16 xdelta;
Uint16 ydelta;
Uint16 last_x;
Uint16 last_y;
Uint16 last_pressure;
bool down;
bool was_down;
bool IsDown();
bool WasDown();
eeVector2i Pos();
protected:
friend class cInput;
void WriteLast();
};
}}
#endif

View File

@@ -42,7 +42,21 @@ class InputEvent {
Uint8 which; /** The mouse device index */
Uint8 button; /** The mouse button index */
Uint8 state; /** EE_PRESSED or EE_RELEASED */
Int16 x, y; /** The X/Y coordinates of the mouse at press time */
Int16 x, y; /** The X/Y coordinates of the mouse at press time */
};
/** Touch finger motion/finger event structure */
struct FingerEvent
{
Uint32 timestamp;
Int64 touchId; /** The touch device id */
Int64 fingerId; /** The finger id */
Uint8 state; /** The current button state */
Uint16 x; /** The x coordinate of the touch */
Uint16 y; /** The y coordinate of the touch */
Int16 dx; /** Change in x coordinate during this motion event */
Int16 dy; /** Change in y coordinate during this motion event */
Uint16 pressure; /** The pressure of the touch */
};
/** Joystick axis motion event structure */
@@ -56,8 +70,8 @@ class InputEvent {
struct JoyBallEvent {
Uint8 which; /** The joystick device index */
Uint8 ball; /** The joystick trackball index */
Int16 xrel; /** The relative motion in the X direction */
Int16 yrel; /** The relative motion in the Y direction */
Int16 xrel; /** The relative motion in the X direction */
Int16 yrel; /** The relative motion in the Y direction */
};
/** Joystick hat position change event structure */
@@ -103,7 +117,6 @@ class InputEvent {
void *data2; /** User defined data pointer */
};
/** If you want to use this event, you should include EE_syswm.h */
struct SysWMmsg;
typedef struct SysWMmsg SysWMmsg;
struct SysWMEvent {
@@ -123,6 +136,9 @@ class InputEvent {
JoyHatMotion,
JoyButtonDown,
JoyButtonUp,
FingerMotion,
FingerDown,
FingerUp,
Quit,
SysWM,
VideoResize,
@@ -140,6 +156,7 @@ class InputEvent {
KeyboardEvent key;
MouseMotionEvent motion;
MouseButtonEvent button;
FingerEvent finger;
JoyAxisEvent jaxis;
JoyBallEvent jball;
JoyHatEvent jhat;