예제 #1
0
//callback
extern int32_t __android_handle_input(struct android_app* app, AInputEvent* event){

		/*
		Input source
		*/
		int nSourceId = AInputEvent_getSource( event );
		//not supported device?
		if (!(nSourceId == AINPUT_SOURCE_TOUCHPAD  || 
			  nSourceId == AINPUT_SOURCE_KEYBOARD || 
			  nSourceId == AINPUT_SOURCE_TOUCHSCREEN))
	    	return 0;  
	    //keyboard
	    if(nSourceId == AINPUT_SOURCE_KEYBOARD)
	    {
		    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) 
		    { //keybord down
				 //get key code
				 unsigned int keyAction =  AKeyEvent_getAction(event);
				 //
				 if( keyDown && keyAction == AKEY_EVENT_ACTION_DOWN )
				 {
				 	keyDown(app->userData,AKeyEvent_getKeyCode(event));
				 }
				 else if( keyUp && keyAction == AKEY_EVENT_ACTION_UP )
				 {
				 	keyUp(app->userData,AKeyEvent_getKeyCode(event));
				 }
				 else 
				 {
				 	return 0;
				 }
				 return 1;
			}
			return 0;
		}
	    //action
	    unsigned int unmaskAction = AMotionEvent_getAction(event);
	    //base action
		unsigned int action = unmaskAction & AMOTION_EVENT_ACTION_MASK; 
		//pointer action
        unsigned int actionPointerIndex = (unmaskAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK);
        			 actionPointerIndex >>= AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
        
		if (action == AMOTION_EVENT_ACTION_DOWN) { //all down
			if(fingerDown){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
						unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
						fingerDown(app->userData,pointerFingerId,
												 AMotionEvent_getX(event, i),
												 AMotionEvent_getY(event, i),
												 AMotionEvent_getPressure(event, i));
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_POINTER_DOWN ) { //one down
			if(fingerDown){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
					unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
					if( pointerFingerId==actionPointerIndex ) {
						fingerDown(app->userData,pointerFingerId,
												 AMotionEvent_getX(event, i),
												 AMotionEvent_getY(event, i),
												 AMotionEvent_getPressure(event, i));
					}
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_UP) { //up all			
			if(fingerUp){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
					unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
					fingerUp(app->userData,pointerFingerId,
									       AMotionEvent_getX(event, i),
										   AMotionEvent_getY(event, i),
										   AMotionEvent_getPressure(event, i));
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_POINTER_UP) { //up one			
			if(fingerUp){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
					unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
					if( pointerFingerId==actionPointerIndex ) {
						fingerUp(app->userData,pointerFingerId,
										       AMotionEvent_getX(event, i),
											   AMotionEvent_getY(event, i),
											   AMotionEvent_getPressure(event, i));
					}
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_MOVE) { //move
			if(fingerMove){
				int count = AMotionEvent_getPointerCount(event);
				int i = 0;
				for(;i < count ; i++) {
						unsigned int pointerFingerId = AMotionEvent_getPointerId(event, i);
						fingerMove(app->userData,pointerFingerId,
												 AMotionEvent_getX(event, i),
												 AMotionEvent_getY(event, i),
												 AMotionEvent_getPressure(event, i));
				}
			}
		} else if (action == AMOTION_EVENT_ACTION_CANCEL) {                                  
		} else {
			return 0;
		}
	return 1;
}
예제 #2
0
파일: android_input.c 프로젝트: cfr/qfusion
/*
* IN_Android_OnInputEvent
*/
static int32_t IN_Android_OnInputEvent( struct android_app *app, AInputEvent *event )
{
	int32_t type = AInputEvent_getType( event );
	int64_t time;

	if( type == AINPUT_EVENT_TYPE_KEY )
	{
		int32_t keycode = AKeyEvent_getKeyCode( event );
		int key;

		if( keycode >= ( sizeof( s_android_scantokey ) / sizeof( s_android_scantokey[0] ) ) )
			return 0;

		if( ( keycode >= AKEYCODE_DPAD_UP ) && ( keycode <= AKEYCODE_DPAD_RIGHT ) &&
			( AInputEvent_getSource( event ) == AINPUT_SOURCE_KEYBOARD ) )
		{
			key = keycode + ( K_UPARROW - AKEYCODE_DPAD_UP );
		}
		else
		{
			key = s_android_scantokey[keycode];
		}
		if( !key )
			return 0;

		time = AKeyEvent_getEventTime( event ) / ( ( int64_t )1000000 );

		switch( AKeyEvent_getAction( event ) )
		{
		case AKEY_EVENT_ACTION_DOWN:
		case AKEY_EVENT_ACTION_MULTIPLE:
			if( ( key == K_ESCAPE ) && IN_Android_HideSoftKeyboard() ) // Instead of broken AInputQueue_preDispatchEvent.
				return 1;

			Key_Event( key, true, time );

			if( Key_IsDown( K_LCTRL ) || Key_IsDown( K_RCTRL ) )
			{
				if( key == 'v' )
					Key_CharEvent( KC_CTRLV, KC_CTRLV );
				else if( key == 'c' )
					Key_CharEvent( KC_CTRLC, KC_CTRLC );
				else
					Key_CharEvent( key, IN_Android_KeyEvent2UCS( event ) );
			}
			else
			{
				Key_CharEvent( key, IN_Android_KeyEvent2UCS( event ) );
			}
			break;

		case AKEY_EVENT_ACTION_UP:
			Key_Event( key, false, time );
			break;
		}

		return 1;
	}

	if( type == AINPUT_EVENT_TYPE_MOTION )
	{
		int32_t action = AMotionEvent_getAction( event );
		int32_t source = AInputEvent_getSource( event );
		int x, y;

		time = AMotionEvent_getEventTime( event ) / ( ( int64_t )1000000 );

		switch( source )
		{
		case AINPUT_SOURCE_TOUCHSCREEN:
			{
				touchevent_t type;
				size_t i, pointerCount = 0, p;

				switch( action & AMOTION_EVENT_ACTION_MASK )
				{
				case AMOTION_EVENT_ACTION_DOWN:
				case AMOTION_EVENT_ACTION_POINTER_DOWN:
					type = TOUCH_DOWN;
					pointerCount = 1;
					break;
				case AMOTION_EVENT_ACTION_POINTER_UP:
					type = TOUCH_UP;
					pointerCount = 1;
					break;
				case AMOTION_EVENT_ACTION_MOVE:
					type = TOUCH_MOVE;
					pointerCount = AMotionEvent_getPointerCount( event );
					break;
				case AMOTION_EVENT_ACTION_UP:
				case AMOTION_EVENT_ACTION_CANCEL:
				case AMOTION_EVENT_ACTION_OUTSIDE:
					type = TOUCH_UP;
					pointerCount = AMotionEvent_getPointerCount( event );
					break;
				}

				p = action >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
				for( i = 0; i < pointerCount; ++i, ++p )
				{
					if( IN_Android_EventToWindowCoordinates( event, p, &x, &y ) )
						CL_TouchEvent( AMotionEvent_getPointerId( event, p ), type, x, y, time );
				}
			}
			break;

		case AINPUT_SOURCE_JOYSTICK:
			{
				float hatXValue = AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_HAT_X, 0 );
				float hatYValue = AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_HAT_Y, 0 );
				int hatX = 0, hatY = 0;
				static int oldHatX = 0, oldHatY = 0;
				bool leftTrigger, rightTrigger;
				static bool oldLeftTrigger = false, oldRightTrigger = false;

				in_android_thumbsticks[0] = AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_X, 0 );
				in_android_thumbsticks[1] = AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_Y, 0 );
				in_android_thumbsticks[2] = AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_Z, 0 );
				in_android_thumbsticks[3] = AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_RZ, 0 );

				hatX = ( hatXValue > 0.5f ) - ( hatXValue < -0.5f );
				hatY = ( hatYValue > 0.5f ) - ( hatYValue < -0.5f );
				if( hatX != oldHatX )
				{
					if( oldHatX )
						Key_Event( K_DPAD_LEFT + ( oldHatX > 0 ), false, time );
					if( hatX )
						Key_Event( K_DPAD_LEFT + ( hatX > 0 ), true, time );
					oldHatX = hatX;
				}
				if( hatY != oldHatY )
				{
					if( oldHatY )
						Key_Event( K_DPAD_UP + ( oldHatY > 0 ), false, time );
					if( hatY )
						Key_Event( K_DPAD_UP + ( hatY > 0 ), true, time );
					oldHatY = hatY;
				}

				leftTrigger = ( AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_BRAKE, 0 ) > ( 30.0f / 255.0f ) )
					|| ( AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_LTRIGGER, 0 ) > ( 30.0f / 255.0f ) );
				rightTrigger = ( AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_GAS, 0 ) > ( 30.0f / 255.0f ) )
					|| ( AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_RTRIGGER, 0 ) > ( 30.0f / 255.0f ) );
				if( leftTrigger != oldLeftTrigger )
				{
					Key_Event( K_LTRIGGER, leftTrigger, time );
					oldLeftTrigger = leftTrigger;
				}
				if( rightTrigger != oldRightTrigger )
				{
					Key_Event( K_RTRIGGER, rightTrigger, time );
					oldRightTrigger = rightTrigger;
				}
			}
			break;

		case AINPUT_SOURCE_MOUSE:
			{
				switch( action )
				{
				case AMOTION_EVENT_ACTION_DOWN:
					Key_MouseEvent( K_MOUSE1, true, time );
					break;
				case AMOTION_EVENT_ACTION_UP:
					Key_MouseEvent( K_MOUSE1, false, time );
					break;
				case AMOTION_EVENT_ACTION_HOVER_MOVE:
				case AMOTION_EVENT_ACTION_MOVE:
					if( IN_Android_EventToWindowCoordinates( event, 0, &x, &y ) )
						CL_MouseSet( x, y, false );
					break;
				}
			}
			break;
		}

		return 1;
	}
예제 #3
0
/**
 * Process the next input event.
 */
int32_t Engine::handleInput(AInputEvent* event) {
    if (mCallbacks && mGamepad->pollGamepads(event, mPadChangedMask))
        return true;
    else if (NULL==mCallbacks)
        return false;

    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
        bool handled = false;
        int32_t pointerCount = AMotionEvent_getPointerCount(event);
        int32_t action = amotion_getActionMasked(event);
        int32_t pointerIndex = amotion_getActionIndex(event);

        float x=0, y=0;
        NvPointerEvent p[20]; // !!!!!TBD  should use linkedlist or app-member struct or something?  TODO
        NvInputDeviceType::Enum dev = NvInputDeviceType::TOUCH;
        // loop over pointercount and copy data
        // !!!!TBD TODO, might need to ensure that p[0] is always the data from the first-finger-touched ID...
        for (int i=0; i<pointerCount; i++) {
            x = AMotionEvent_getX(event, i);
            y = AMotionEvent_getY(event, i);
            p[i].m_x = x;
            p[i].m_y = y;
            p[i].m_id = AMotionEvent_getPointerId(event, i);
            // then figure out tool/device enum...
            int32_t tool = AMotionEvent_getToolType(event, i);
            if (tool==AMOTION_EVENT_TOOL_TYPE_STYLUS ||
                tool==AMOTION_EVENT_TOOL_TYPE_ERASER)//!!!!TBD TODO
                dev = NvInputDeviceType::STYLUS;
            else if (tool==AMOTION_EVENT_TOOL_TYPE_MOUSE)
                dev = NvInputDeviceType::MOUSE;
            else
                dev = NvInputDeviceType::TOUCH;
            // else we assume == FINGER... if unknown, treat as FINGER. TODO.
            p[i].m_device = dev;
        }

        mState.x = x;
        mState.y = y;
    
        NvPointerActionType::Enum pact;

        switch(action)
        {
        case AMOTION_EVENT_ACTION_DOWN:
            pact = NvPointerActionType::DOWN;
            break;
        case AMOTION_EVENT_ACTION_POINTER_DOWN:
            pact = NvPointerActionType::EXTRA_DOWN;
            break;
        case AMOTION_EVENT_ACTION_UP:
            pact = NvPointerActionType::UP;
            break;
        case AMOTION_EVENT_ACTION_POINTER_UP:
            pact = NvPointerActionType::EXTRA_UP;
            break;
        case AMOTION_EVENT_ACTION_MOVE:
            pact = NvPointerActionType::MOTION;
            break;
        case AMOTION_EVENT_ACTION_CANCEL:
            pact = NvPointerActionType::UP;
            pointerCount = 0; // clear.
            break;
        }

        const int64_t timestamp = AMotionEvent_getEventTime((const AInputEvent*)event);
        handled = mCallbacks->pointerInput(dev, pact, 0, pointerCount, p, timestamp);
        // return code handling...
        if (pact==NvPointerActionType::UP)
            return 1;
        return handled ? 1 : 0;
    } else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) {
        bool handled = false;
        int32_t source = AInputEvent_getSource(event);
        int32_t code = AKeyEvent_getKeyCode((const AInputEvent*)event);
        int32_t action = AKeyEvent_getAction((const AInputEvent*)event);

        bool down = (action != AKEY_EVENT_ACTION_UP) ? true : false;

        if (mCallbacks) {
            handled = mCallbacks->keyInput(code, 
                down ? NvKeyActionType::DOWN : NvKeyActionType::UP);

            if (!handled && down) {
                uint8_t c = mapAndroidCodeToChar(code);
                if (c)
                    handled = mCallbacks->characterInput(c);
            }
        }

        return handled ? 1 : 0;
    }

    return 0;
}
예제 #4
0
/**
 * Process the next input event.
 */
static int32_t engine_handle_input(struct android_app *app, AInputEvent *event) {
	struct engine *engine = (struct engine *)app->userData;

	if (!engine->os)
		return 0;

	switch (AInputEvent_getType(event)) {

		case AINPUT_EVENT_TYPE_KEY: {

			int ac = AKeyEvent_getAction(event);
			switch (ac) {

				case AKEY_EVENT_ACTION_DOWN: {

					int32_t code = AKeyEvent_getKeyCode(event);
					if (code == AKEYCODE_BACK) {

						//AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
						if (engine->os)
							engine->os->main_loop_request_quit();
						return 1;
					}

				} break;
				case AKEY_EVENT_ACTION_UP: {

				} break;
			}

		} break;
		case AINPUT_EVENT_TYPE_MOTION: {

			Vector<OS_Android::TouchPos> touchvec;

			int pc = AMotionEvent_getPointerCount(event);

			touchvec.resize(pc);

			for (int i = 0; i < pc; i++) {

				touchvec[i].pos.x = AMotionEvent_getX(event, i);
				touchvec[i].pos.y = AMotionEvent_getY(event, i);
				touchvec[i].id = AMotionEvent_getPointerId(event, i);
			}

			//System.out.printf("gaction: %d\n",event.getAction());
			int pidx = (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> 8;
			switch (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) {

				case AMOTION_EVENT_ACTION_DOWN: {
					engine->os->process_touch(0, 0, touchvec);

					//System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
				} break;
				case AMOTION_EVENT_ACTION_MOVE: {
					engine->os->process_touch(1, 0, touchvec);
					/*
					for(int i=0;i<event.getPointerCount();i++) {
						System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i));
					}
					*/
				} break;
				case AMOTION_EVENT_ACTION_POINTER_UP: {

					engine->os->process_touch(4, pidx, touchvec);
					//System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
				} break;
				case AMOTION_EVENT_ACTION_POINTER_DOWN: {
					engine->os->process_touch(3, pidx, touchvec);
					//System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
				} break;
				case AMOTION_EVENT_ACTION_CANCEL:
				case AMOTION_EVENT_ACTION_UP: {
					engine->os->process_touch(2, 0, touchvec);
					/*
					for(int i=0;i<event.getPointerCount();i++) {
						System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i));
					}
					*/
				} break;
			}

			return 1;
		} break;
	}

	return 0;
}
예제 #5
0
int32_t on_motion_event(android_app *app, AInputEvent *event)
{
    /*
    AMotionEvent_getAction();
    AMotionEvent_getEventTime();
    AMotionEvent_getPointerCount();
    AMotionEvent_getPointerId();
    AMotionEvent_getX();
    AMotionEvent_getY();

    AMOTION_EVENT_ACTION_DOWN
    AMOTION_EVENT_ACTION_UP
    AMOTION_EVENT_ACTION_MOVE
    AMOTION_EVENT_ACTION_CANCEL
    AMOTION_EVENT_ACTION_POINTER_DOWN
    AMOTION_EVENT_ACTION_POINTER_UP
    */
    user_data *p = (user_data *)app->userData;
    pan_state *pan = &p->motion.pan;

    pan->stick = {};

    uint action = AMotionEvent_getAction(event);
    uint num_pointers = AMotionEvent_getPointerCount(event);
    if (num_pointers != 2 || action == AMOTION_EVENT_ACTION_UP || action == AMOTION_EVENT_ACTION_CANCEL)
    {
        if (pan->in_pan)
        {
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "ending pan");
        }
        pan->in_pan = 0;
    }
    else
    {
        uint pointer_id_0 = AMotionEvent_getPointerId(event, 0);
        uint pointer_id_1 = AMotionEvent_getPointerId(event, 1);
        v2 pointer_pos_0 = {AMotionEvent_getX(event, pointer_id_0), AMotionEvent_getY(event, pointer_id_0)};
        v2 pointer_pos_1 = {AMotionEvent_getX(event, pointer_id_1), AMotionEvent_getY(event, pointer_id_1)};
        v2 center_pos = (pointer_pos_0 + pointer_pos_1) * 0.5f;

        if (!pan->in_pan)
        {
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "starting pan");
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "pointer_pos_0: %0.2f, %0.2f", pointer_pos_0.X, pointer_pos_0.Y);
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "pointer_pos_1: %0.2f, %0.2f", pointer_pos_1.X, pointer_pos_1.Y);
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "center_pos: %0.2f, %0.2f", center_pos.X, center_pos.Y);
            pan->in_pan = 1;
            pan->start_pos = center_pos;
        }

        if (pan->in_pan)
        {
            v2 distance = center_pos - pan->start_pos;
            if ((abs(distance.X) > 100) || (abs(distance.Y) > 100))
            {
                if (abs(distance.X) > 100)
                {
                    pan->stick.X = distance.X > 0 ? 1.0 : -1.0;
                }
                if (abs(distance.Y) > 100)
                {
                    pan->stick.Y = distance.Y < 0 ? 1.0 : -1.0;
                }
            }
            __android_log_print(ANDROID_LOG_INFO, p->app_name, "pan->stick: %0.2f, %0.2f", pan->stick.X, pan->stick.Y);
        }
    }
    return 1;
}
예제 #6
0
/**
 * Process the next input event.
 */
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
	struct engine* androidEngine = (struct engine*)app->userData;

	int touchCount = 0;
	static int previousTouchCount;
	int numButton;
	touch_t* touch;
	touch_t* currentTouchSet;

	struct TOUCHSTATE *touchstate = 0;
	struct TOUCHSTATE *prev_touchstate = 0;

	int nSourceId = AInputEvent_getSource( event );

	if (nSourceId == AINPUT_SOURCE_TOUCHPAD)
   		touchstate = engine.touchstate_pad; // GJT: For Xperia Play...and other devices?
	else if (nSourceId == AINPUT_SOURCE_TOUCHSCREEN)
    	touchstate = engine.touchstate_screen;
    else
    	return 0; // GJT: Volume? Keyboard? Let the system handle it...

	if (engine.menuVisible)
	{
		numButton = MENU_GetNumButtonsTouches();
		currentTouchSet = MENU_GetCurrentButtonTouches();		
	}
	else 
	{
		numButton = NUM_BUTTONS;
		currentTouchSet = touches;
	}

	if (engine.menuVisible || engine.controlMode == CONTROL_MODE_VIRT_PAD)
	{
		size_t pointerCount =  AMotionEvent_getPointerCount(event);
		size_t i;
		for (i = 0; i < pointerCount; i++) 
		{
            size_t pointerId = AMotionEvent_getPointerId(event, i);
	        size_t action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK;
		
			touchstate[pointerId].x = AMotionEvent_getX( event, i );
			touchstate[pointerId].y = AMotionEvent_getY( event, i );
			
			LOGI("DEBUG BEFORE x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);

			// Transforming from whatever screen resolution we have to the original iPhone 320*480
			touchstate[pointerId].x = ( touchstate[pointerId].x - renderer.viewPortDimensions[VP_X] ) * commScale[X] ;
			touchstate[pointerId].y = ( touchstate[pointerId].y - renderer.viewPortDimensions[VP_Y] ) * commScale[Y] ;

			LOGI("DEBUG AFTER  x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);

			touchCount++;

			// find which one it is closest to
			int		minDist = INT_MAX; // allow up to 64 unit moves to be drags
			int		minIndex = -1;
			int dist;
			touch_t	*t2 = currentTouchSet;
			int i;

			for ( i = 0 ; i < numButton ; i++ ) 
			{
				dist = SQUARE( t2->iphone_coo_SysPos[X] - touchstate[pointerId].x )  + SQUARE( t2->iphone_coo_SysPos[Y] - touchstate[pointerId].y ) ;

				LOGI("DEBUG dist %i minDist %i", dist, minDist);
				if ( dist < minDist ) {
					minDist = dist;
					minIndex = i;
					touch = t2;
				}
				t2++;
			}

			if ( minIndex != -1 ) 
			{
				if (action == AMOTION_EVENT_ACTION_UP) 
				{
					touch->down = 0;
				}
				else 
				{
					if (action == AMOTION_EVENT_ACTION_DOWN) 
					{
					}
					touch->down = 1;
					touch->dist[X] = MIN(1,(touchstate[pointerId].x - touches[minIndex].iphone_coo_SysPos[X])/touches[minIndex].iphone_size);
					touch->dist[Y] = MIN(1,(touches[minIndex].iphone_coo_SysPos[Y] - touchstate[pointerId].y)/touches[minIndex].iphone_size);
					LOGI("DEBUG minIndexIphone %i", touches[minIndex].iphone_size);
				}
			}
		}

		LOGI("DEBUG touchcount %i previous %i", touchCount, previousTouchCount);
		if ( touchCount == 5 && previousTouchCount != 5 ) 
		{
			MENU_Set(MENU_HOME);
			engine.requiredSceneId = 0;
		}
	
		previousTouchCount = touchCount;

		return 1;
	}

	else
	{
		size_t pointerCount =  AMotionEvent_getPointerCount(event);
		size_t i;

		for (i = 0; i < pointerCount; i++) 
		{
			size_t pointerCount =  AMotionEvent_getPointerCount(event);
			size_t pointerId = AMotionEvent_getPointerId(event, i);
	        size_t action = AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK;
	        size_t pointerIndex = i;
		
			int historySize = AMotionEvent_getHistorySize(event);

			touchstate[pointerId].x = AMotionEvent_getX( event, pointerIndex );
			touchstate[pointerId].y = AMotionEvent_getY( event, pointerIndex );

			LOGI("DEBUG history %i", historySize);

			LOGI("DEBUG nomenu x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);
			if (historySize > 0)
			{
				//prev_touchstate[pointerId].x = AMotionEvent_getX( event, pointerIndex );
				//prev_touchstate[pointerId].y = AMotionEvent_getY( event, pointerIndex );

				LOGI("DEBUG nomenu prevx %f prevy %f", prev_touchstate[pointerId].x, prev_touchstate[pointerId].y);
			}
			//Transforming from whatever screen resolution we have to the original iPHone 320*480
			/*touchstate[pointerId].x = ( touchstate[pointerId].x- renderer.viewPortDimensions[VP_X] ) * commScale[X] ;//* renderer.resolution ;
			touchstate[pointerId].y = ( touchstate[pointerId].y- renderer.viewPortDimensions[VP_Y] ) * commScale[Y] ;//* renderer.resolution;
			
			prev_touchstate[pointerId].x = ( prev_touchstate[pointerId].x- renderer.viewPortDimensions[VP_X] ) * commScale[X] ;//* renderer.resolution ;
			prev_touchstate[pointerId].y = ( prev_touchstate[pointerId].y- renderer.viewPortDimensions[VP_Y] ) * commScale[Y] ;//* renderer.resolution;*/
			
			
			touchCount++;					

			if (action == AMOTION_EVENT_ACTION_UP) 
			{
				if (touchCount == 1) //Last finger ended
					touches[BUTTON_FIRE].down = 0;
			}
			else 
			{
				if (action == AMOTION_EVENT_ACTION_MOVE) 
				{
					//printf("m\n");
								LOGI("DEBUG MOVE x %f y %f", touchstate[pointerId].x, touchstate[pointerId].y);
			//LOGI("DEBUG MOVE prevx %f prevy %f", prev_touchstate[pointerId].x, prev_touchstate[pointerId].y);

					touches[BUTTON_MOVE].down = 1;
					//touches[BUTTON_MOVE].dist[X] = (touchstate[pointerId].x - prev_touchstate[pointerId].x)*40/(float)320;
					//touches[BUTTON_MOVE].dist[Y] = (touchstate[pointerId].y - prev_touchstate[pointerId].y)*-40/(float)480;
					
				}
				if (action == AMOTION_EVENT_ACTION_DOWN)
				{
					int currTime = E_Sys_Milliseconds();
					if (currTime-lastTouchBegan < 200)
						touches[BUTTON_GHOST].down = 1;
					
					lastTouchBegan = currTime ;
					
					touches[BUTTON_FIRE].down = 1;
				}
				
				
			}
		}

		if ( touchCount == 5 && previousTouchCount != 5 ) 
		{
			MENU_Set(MENU_HOME);
			engine.requiredSceneId=0;
		}
	
		previousTouchCount = touchCount;

		return 1;
	}
	return 0;
}
예제 #7
0
int Engine::handleInput(AInputEvent* event)
{
	if( !event )
		return 0;
    //We only handle motion events (touchscreen) and key (button/key) events
	int32_t eventType = AInputEvent_getType(event);
	if (eventType == AINPUT_EVENT_TYPE_MOTION)
	{
		int32_t actionUnmasked = AMotionEvent_getAction(event);
		int32_t action = (actionUnmasked & AMOTION_EVENT_ACTION_MASK);	
		static int	l_siIgnoreTime = 0;
		bool	l_bTouch = false;
		if(AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN || AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_MULTIPLE )
		{
			l_bTouch = true;
		}
		if( cGameApp::m_sbGamePause )
			l_siIgnoreTime = 1;
		if( g_pAndroidTestApp && !cGameApp::m_sbGamePause && l_siIgnoreTime == 0 )
		{
			if(g_pAndroidTestApp->m_sbDoMultiTouch)
			{
				int numEvents = AMotionEvent_getPointerCount(event);
				for (int index=0; index<numEvents; index++)
				{
					int		id = AMotionEvent_getPointerId(event, index);
					float	l_fPosX = AMotionEvent_getX(event, index);
					float	l_fPosY = AMotionEvent_getY(event, index);
					float	l_fpressure = AMotionEvent_getPressure(event, index);
					float	l_fSize =AMotionEvent_getSize(event, index);
					g_pAndroidTestApp->m_spMultiTouchPoints->Touch(l_bTouch,(int)l_fPosX,(int)l_fPosY,id);
					g_pAndroidTestApp->TouchSignalProcess(l_fPosX,l_fPosY,l_bTouch);
				}
				g_pAndroidTestApp->m_spMultiTouchPoints->Update(0);
			}
			else
			{
				int32_t iX = AMotionEvent_getX(event, 0);
				int32_t iY = AMotionEvent_getY(event, 0);
				g_pAndroidTestApp->TouchSignalProcess(iX,iY,l_bTouch);
			}
		}
		if( l_siIgnoreTime > 0 )
		{
			if( l_bTouch == false )
				l_siIgnoreTime = 0;
		}

		//int32_t action = AMOTION_EVENT_ACTION_MASK & AMotionEvent_getAction((const AInputEvent*)event);
		// A tap on the screen takes us out of autopause into gameplay mode if
		// we were paused.  No other touch processing is done.
		if (action == AMOTION_EVENT_ACTION_DOWN)
		{
			setGameplayMode(true);
			g_pAndroidTestApp->m_spMultiTouchPoints->Init();
		}
		//,
		return 1;
	} 
	else
	if (eventType == AINPUT_EVENT_TYPE_KEY) 
	{
		int32_t code = AKeyEvent_getKeyCode((const AInputEvent*)event);
		int32_t action = AKeyEvent_getAction((const AInputEvent*)event);

		// if we are in gameplay mode, we eat the back button and move into
		// pause mode.  If we are already in pause mode, we allow the back
		// button to be handled by the OS, which means we'll be shut down
		if ((code == AKEYCODE_BACK) && mGameplayMode)
		{
			setGameplayMode(false);
			return 1;
		}

		std::string	l_strDebugInfo = "Code:";
		l_strDebugInfo += ValueToString(code);
		l_strDebugInfo += "___Action";
		l_strDebugInfo += ValueToString(action);
		cGameApp::OutputDebugInfoString(l_strDebugInfo);

		bool	l_bVaildKey = false;
		bool	l_bKeyDown = action==0?true:false;
		if((code >= AKEYCODE_A && code <= AKEYCODE_Z))
		{//windows 65-90
			code -= AKEYCODE_A;
			code += 65;
			l_bVaildKey = true;
		}
		else
		if((code >= AKEYCODE_0 && code <= AKEYCODE_9))
		{//windows 45-97
			code -= AKEYCODE_0;
			code += 45;
			l_bVaildKey = true;
		}
		if( l_bVaildKey )
		{
			if( l_bKeyDown )
			{
				g_pAndroidTestApp->KeyDown((char)code);
			}
			else
			{
				g_pAndroidTestApp->KeyUp((char)code);
			}
		}
	}

    return 0;
}
예제 #8
0
/**
 * Process the next input event.
 */
static
int32_t
engine_handle_input( struct android_app* app, AInputEvent* event )
{
	JNIEnv *jni;
	(*jVM)->AttachCurrentThread(jVM, &jni, NULL);

	struct ENGINE* engine = (struct ENGINE*)app->userData;
    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY){
        int device = AInputEvent_getDeviceId(event);
        int action = AKeyEvent_getAction(event);
        int keyCode = AKeyEvent_getKeyCode(event);
        if(jni && g_pActivity){
            if((*jni)->ExceptionCheck(jni)) {
                (*jni)->ExceptionDescribe(jni);
                (*jni)->ExceptionClear(jni);
            }
            (*jni)->CallIntMethod(jni, g_pActivity, javaOnNDKKey, device, keyCode, action, AKeyEvent_getMetaState(event));
            if (!(keyCode == AKEYCODE_MENU || keyCode == AKEYCODE_BACK || keyCode == AKEYCODE_BUTTON_THUMBR || keyCode == AKEYCODE_VOLUME_UP || keyCode == AKEYCODE_VOLUME_DOWN || keyCode == AKEYCODE_BUTTON_SELECT)) {
                return 1;
            }
        }
    } else if( AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION ) {
        int device = AInputEvent_getDeviceId( event );
        int nSourceId		= AInputEvent_getSource( event );
        int nPointerCount	= AMotionEvent_getPointerCount( event );
        int n;

        jboolean newTouch = JNI_TRUE;
        for( n = 0 ; n < nPointerCount ; ++n )
        {
            int nPointerId	= AMotionEvent_getPointerId( event, n );
            int nAction		= AMOTION_EVENT_ACTION_MASK & AMotionEvent_getAction( event );
            int nRawAction	= AMotionEvent_getAction( event );

            struct TOUCHSTATE *touchstate = 0;
            if( nSourceId == AINPUT_SOURCE_TOUCHPAD ) {
                touchstate = engine->touchstate_pad;
            } else {
                touchstate = engine->touchstate_screen;
            }

            if( nAction == AMOTION_EVENT_ACTION_POINTER_DOWN || nAction == AMOTION_EVENT_ACTION_POINTER_UP )
            {
                int nPointerIndex = (AMotionEvent_getAction( event ) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
                nPointerId = AMotionEvent_getPointerId( event, nPointerIndex );
            }

            if( nAction == AMOTION_EVENT_ACTION_DOWN || nAction == AMOTION_EVENT_ACTION_POINTER_DOWN )
            {
                touchstate[nPointerId].down = 1;
            }
            else if( nAction == AMOTION_EVENT_ACTION_UP || nAction == AMOTION_EVENT_ACTION_POINTER_UP || nAction == AMOTION_EVENT_ACTION_CANCEL )
            {
                touchstate[nPointerId].down = 0;
            }

            if (touchstate[nPointerId].down == 1)
            {
                touchstate[nPointerId].x = AMotionEvent_getX( event, n );
                touchstate[nPointerId].y = AMotionEvent_getY( event, n );
            }

            if( jni && g_pActivity && isXperiaPlay) {
//                (*jni)->CallVoidMethod( jni, g_pActivity, javaOnNDKTouch, device, nSourceId, nRawAction, touchstate[nPointerId].x, touchstate[nPointerId].y, newTouch);
                (*jni)->CallVoidMethod( jni, g_pActivity, javaOnNDKTouch, device, nSourceId, nRawAction, touchstate[nPointerId].x, touchstate[nPointerId].y);
            }
            newTouch = JNI_FALSE;
        }
/*
 * Handle Touch Inputs
 */
static int32_t handle_touch_input(AInputEvent *event) {

    pthread_t thisthread = pthread_self();
    LOG_EVENTS_DEBUG("handle_touch_input(%X), pthread_self() = %X", event, thisthread);

    switch(AMotionEvent_getAction(event) &
           AMOTION_EVENT_ACTION_MASK) {

    case AMOTION_EVENT_ACTION_DOWN:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_DOWN");
            int pointerId = AMotionEvent_getPointerId(event, 0);
            float xP = AMotionEvent_getX(event,0);
            float yP = AMotionEvent_getY(event,0);

            LOG_EVENTS_DEBUG("Event: Action DOWN x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerId);
            int pId = pointerId;
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &pId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_POINTER_DOWN:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_POINTER_DOWN");
            int pointerIndex = AMotionEvent_getAction(event) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
            int pointerId = AMotionEvent_getPointerId(event, pointerIndex);
            float xP = AMotionEvent_getX(event,pointerIndex);
            float yP = AMotionEvent_getY(event,pointerIndex);

            LOG_EVENTS_DEBUG("Event: Action POINTER DOWN x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerId);
            int pId = pointerId;
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesBegin(1, &pId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_MOVE:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_MOVE");
            int pointerCount = AMotionEvent_getPointerCount(event);
            int ids[pointerCount];
            float xs[pointerCount], ys[pointerCount];
            getTouchPos(event, ids, xs, ys);
            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesMove(pointerCount, ids, xs, ys);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_UP:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_UP");
            int pointerId = AMotionEvent_getPointerId(event, 0);
            float xP = AMotionEvent_getX(event,0);
            float yP = AMotionEvent_getY(event,0);
            LOG_EVENTS_DEBUG("Event: Action UP x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerId);
            int pId = pointerId;
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, &pId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_POINTER_UP:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_POINTER_UP");
            int pointerIndex = AMotionEvent_getAction(event) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
            int pointerId = AMotionEvent_getPointerId(event, pointerIndex);
            float xP = AMotionEvent_getX(event,pointerIndex);
            float yP = AMotionEvent_getY(event,pointerIndex);
            LOG_EVENTS_DEBUG("Event: Action POINTER UP x=%f y=%f pointerID=%d\n",
                 xP, yP, pointerIndex);
            int pId = pointerId;
            float x = xP;
            float y = yP;

            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesEnd(1, &pId, &x, &y);
            return 1;
        }
        break;

    case AMOTION_EVENT_ACTION_CANCEL:
        {
            LOG_EVENTS_DEBUG("AMOTION_EVENT_ACTION_CANCEL");
            int pointerCount = AMotionEvent_getPointerCount(event);
            int ids[pointerCount];
            float xs[pointerCount], ys[pointerCount];
            getTouchPos(event, ids, xs, ys);
            cocos2d::Director::getInstance()->getOpenGLView()->handleTouchesCancel(pointerCount, ids, xs, ys);
            return 1;
        }
        break;

    default:
        LOG_EVENTS_DEBUG("handle_touch_input() default case.... NOT HANDLE");
        return 0;
        break;
    }
}
예제 #10
0
int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, ActivityStates* states)
{
    int32_t device = AInputEvent_getSource(_event);
    int32_t action = AMotionEvent_getAction(_event);

    int index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
    int id = AMotionEvent_getPointerId(_event, index);

    float x = AMotionEvent_getX(_event, index);
    float y = AMotionEvent_getY(_event, index);

    Event event;

    if (isDown)
    {
        if (device == AINPUT_SOURCE_MOUSE)
        {
            event.type = Event::MouseButtonPressed;
            event.mouseButton.button = static_cast<Mouse::Button>(id);
            event.mouseButton.x = x;
            event.mouseButton.y = y;

            if (id >= 0 && id < Mouse::ButtonCount)
                states->isButtonPressed[id] = true;
        }
        else if (device & AINPUT_SOURCE_TOUCHSCREEN)
        {
            event.type = Event::TouchBegan;
            event.touch.finger = id;
            event.touch.x = x;
            event.touch.y = y;

            states->touchEvents[id] = Vector2i(event.touch.x, event.touch.y);
        }
    }
    else
    {
        if (device == AINPUT_SOURCE_MOUSE)
        {
            event.type = Event::MouseButtonReleased;
            event.mouseButton.button = static_cast<Mouse::Button>(id);
            event.mouseButton.x = x;
            event.mouseButton.y = y;

            if (id >= 0 && id < Mouse::ButtonCount)
                states->isButtonPressed[id] = false;
        }
        else if (device & AINPUT_SOURCE_TOUCHSCREEN)
        {
            event.type = Event::TouchEnded;
            event.touch.finger = id;
            event.touch.x = x;
            event.touch.y = y;

            states->touchEvents.erase(id);
        }
    }

    forwardEvent(event);
    return 1;
}
예제 #11
0
    int32_t motion(AInputEvent* event)
    {
        auto& windowRef = Engine::getMainWindow();

        const int32_t device = AInputEvent_getSource(event);

        const int pointerCount = AMotionEvent_getPointerCount(event);

        for (int p = 0; p < pointerCount; ++p)
        {
            const int id = AMotionEvent_getPointerId(event, p);

            if (id < 10)
            {
                float x = AMotionEvent_getX(event, p);
                const float y = AMotionEvent_getY(event, p);

                auto state = ActivityState::get();

                if (device & AINPUT_SOURCE_TOUCHSCREEN)
                {
                    windowRef.getEventHandler()->touchMoved(id, x - state->lastTouchPosition[id].x, y - state->lastTouchPosition[id].y);
                    windowRef.getEventHandler()->touchMovedAbsolute(id, x, y);

                    for (int info = 0; info < 4; ++info)
                    {
                        const float i = AMotionEvent_getAxisValue(event, ns_touchAxes[info], p);

                        if (i > JOP_AXIS_TOLERANCE)
                            windowRef.getEventHandler()->touchInfo(id, Input::getJopTouchInfo(ns_touchAxes[info]), i);
                    }
                }
                else if (device & AINPUT_SOURCE_MOUSE)
                {
                    windowRef.getEventHandler()->mouseMoved(x - state->lastTouchPosition[id].x, y - state->lastTouchPosition[id].y);
                    windowRef.getEventHandler()->mouseMovedAbsolute(x, y);
                }
                else if (device & AINPUT_SOURCE_JOYSTICK)
                {
                    for (int axis = 0; axis < 15; ++axis)
                    {
                        x = AMotionEvent_getAxisValue(event, ns_joystickAxes[axis], p);

                        if (x > JOP_AXIS_TOLERANCE || x < -JOP_AXIS_TOLERANCE)
                        {
                            if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_HAT_Y || ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_HAT_X)
                            {
                                if (x > 0)
                                    x = 1;
                                else
                                    x = -1;

                                const int jopKey = Input::getJopControllerButton(x * ns_joystickAxes[axis]);
                                state->activeKey = jopKey;

                                windowRef.getEventHandler()->controllerButtonPressed(id, jopKey);
                            }
                            else if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_Y || ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_RZ)
                            {
                                x = -x;

                                if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_Y)
                                    state->activeAxes[1] = x;
                                else
                                    state->activeAxes[3] = x;

                                windowRef.getEventHandler()->controllerAxisShifted(id, Input::getJopControllerAxis(ns_joystickAxes[axis]), x);
                            }
                            else
                            {
                                if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_X)
                                    state->activeAxes[0] = x;

                                else if(ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_Z)
                                    state->activeAxes[2] = x;

                                else if(ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_LTRIGGER)
                                    state->activeAxes[4] = x;

                                else if(ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_RTRIGGER)
                                    state->activeAxes[5] = x;

                                windowRef.getEventHandler()->controllerAxisShifted(id, Input::getJopControllerAxis(ns_joystickAxes[axis]), x);
                            }
                        }
                        else if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_X)
                            state->activeAxes[0] = 0.f;

                        else if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_Y)
                            state->activeAxes[1] = 0.f;

                        else if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_Z)
                            state->activeAxes[2] = 0.f;

                        else if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_RZ)
                            state->activeAxes[3] = 0.f;

                        else if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_LTRIGGER)
                            state->activeAxes[4] = 0.f;

                        else if (ns_joystickAxes[axis] == AMOTION_EVENT_AXIS_RTRIGGER)
                            state->activeAxes[5] = 0.f;

                        if (!state->controllerPresent)
                        {
                            windowRef.getEventHandler()->controllerConnected(0, "Android_Controller");
                            state->controllerPresent = true;
                        }
                    }
                }
                else
                    return 0;

                state->lastTouchPosition[id] = glm::vec2(x,y);
            }

            return 1;
        }

        return 0;
    }
예제 #12
0
GESTURE_STATE PinchDetector::Detect(const AInputEvent* event) {
  GESTURE_STATE ret = GESTURE_STATE_NONE;
  int32_t action = AMotionEvent_getAction(event);
  uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
  event_ = event;

  int32_t count = AMotionEvent_getPointerCount(event);
  switch (flags) {
    case AMOTION_EVENT_ACTION_DOWN:
      vec_pointers_.push_back(AMotionEvent_getPointerId(event, 0));
      break;
    case AMOTION_EVENT_ACTION_POINTER_DOWN: {
      int32_t iIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
                       AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
      vec_pointers_.push_back(AMotionEvent_getPointerId(event, iIndex));
      if (count == 2) {
        // Start new pinch
        ret = GESTURE_STATE_START;
      }
    } break;
    case AMOTION_EVENT_ACTION_UP:
      vec_pointers_.pop_back();
      break;
    case AMOTION_EVENT_ACTION_POINTER_UP: {
      int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >>
                      AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
      int32_t released_pointer_id = AMotionEvent_getPointerId(event, index);

      std::vector<int32_t>::iterator it = vec_pointers_.begin();
      std::vector<int32_t>::iterator it_end = vec_pointers_.end();
      int32_t i = 0;
      for (; it != it_end; ++it, ++i) {
        if (*it == released_pointer_id) {
          vec_pointers_.erase(it);
          break;
        }
      }

      if (i <= 1) {
        // Reset pinch or drag
        if (count != 2) {
          // Start new pinch
          ret = GESTURE_STATE_START | GESTURE_STATE_END;
        }
      }
    } break;
    case AMOTION_EVENT_ACTION_MOVE:
      switch (count) {
        case 1:
          break;
        default:
          // Multi touch
          ret = GESTURE_STATE_MOVE;
          break;
      }
      break;
    case AMOTION_EVENT_ACTION_CANCEL:
      break;
  }

  return ret;
}
예제 #13
0
// Process the next input event.
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
{
    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
    {
        int32_t action = AMotionEvent_getAction(event);
        size_t pointerIndex;
        size_t pointerId;
        size_t pointerCount;
        int x;
        int y;
        
        switch (action & AMOTION_EVENT_ACTION_MASK)
        {
            case AMOTION_EVENT_ACTION_DOWN:
                {
                    pointerId = AMotionEvent_getPointerId(event, 0);
                    x = AMotionEvent_getX(event, 0);
                    y = AMotionEvent_getY(event, 0);

                    // Gesture handling
                    if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
                         __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
                    {
                        __pointer0.pressed = true;
                        __pointer0.time = Game::getInstance()->getAbsoluteTime();
                        __pointer0.pointerId = pointerId;
                        __pointer0.x = x;
                        __pointer0.y = y;
                    }

                    // Primary pointer down.
                    gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, x, y, pointerId);
                    __primaryTouchId = pointerId;
                }
                break;

            case AMOTION_EVENT_ACTION_UP:
                {
                    pointerId = AMotionEvent_getPointerId(event, 0);
                    x = AMotionEvent_getX(event, 0);
                    y = AMotionEvent_getY(event, 0);
                    
                    // Gestures
                    bool gestureDetected = false;
                    if ( __pointer0.pressed &&  __pointer0.pointerId == pointerId)
                    {
                        int deltaX = x - __pointer0.x;
                        int deltaY = y - __pointer0.y;

                        // Test for swipe
                        if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
                            gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_SWIPE_DURATION_MAX && 
                            (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
                        {
                            int direction = 0;
                            if ( abs(deltaX) > abs(deltaY) )
                            {
                                if (deltaX > 0)
                                    direction = gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
                                else if (deltaX < 0)
                                    direction = gameplay::Gesture::SWIPE_DIRECTION_LEFT;
                            }
                            else
                            {
                                if (deltaY > 0)
                                    direction = gameplay::Gesture::SWIPE_DIRECTION_DOWN;
                                else if (deltaY < 0)
                                    direction = gameplay::Gesture::SWIPE_DIRECTION_UP;
                            }
                            gameplay::Game::getInstance()->gestureSwipeEvent(x, y, direction);
                            __pointer0.pressed = false;
                            gestureDetected = true;
                        }
                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer0.time < GESTURE_TAP_DURATION_MAX)
                        {
                            gameplay::Game::getInstance()->gestureTapEvent(x, y);
                            __pointer0.pressed = false;
                            gestureDetected = true;
                        }
                    }

                    if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
                    {
                        gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, x, y, pointerId);
                    }
                    __primaryTouchId = -1;
                }
                break;

            case AMOTION_EVENT_ACTION_POINTER_DOWN:
                {
                    pointerId = AMotionEvent_getPointerId(event, 0);
                    x = AMotionEvent_getX(event, 0);
                    y = AMotionEvent_getY(event, 0);

                    // Gesture handling
                    if ( __gestureEventsProcessed.test(Gesture::GESTURE_TAP) ||
                         __gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) )
                    {
                        __pointer1.pressed = true;
                        __pointer1.time = Game::getInstance()->getAbsoluteTime();
                        __pointer1.pointerId = pointerId;
                        __pointer1.x = x;
                        __pointer1.y = y;
                    }

                    // Non-primary pointer down.
                    if (__multiTouch)
                    {
                        pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
                        pointerId = AMotionEvent_getPointerId(event, pointerIndex);
                        gameplay::Platform::touchEventInternal(Touch::TOUCH_PRESS, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
                    }
                }
                break;

            case AMOTION_EVENT_ACTION_POINTER_UP:
                {
                    pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
                    pointerId = AMotionEvent_getPointerId(event, pointerIndex);
                    x = AMotionEvent_getX(event, 0);
                    y = AMotionEvent_getY(event, 0);

                    bool gestureDetected = false;
                    if ( __pointer1.pressed &&  __pointer1.pointerId == pointerId)
                    {
                        int deltaX = x - __pointer1.x;
                        int deltaY = y - __pointer1.y;

                        // Test for swipe
                        if (__gestureEventsProcessed.test(Gesture::GESTURE_SWIPE) &&
                            gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_SWIPE_DURATION_MAX && 
                            (abs(deltaX) > GESTURE_SWIPE_DISTANCE_MIN || abs(deltaY) > GESTURE_SWIPE_DISTANCE_MIN) )
                        {
                            int direction;
                            if (deltaX > 0)
                                direction |= gameplay::Gesture::SWIPE_DIRECTION_RIGHT;
                            else if (deltaX < 0)
                                direction |= gameplay::Gesture::SWIPE_DIRECTION_LEFT;
                            
                            if (deltaY > 0)
                                direction |= gameplay::Gesture::SWIPE_DIRECTION_DOWN;
                            else if (deltaY < 0)
                                direction |= gameplay::Gesture::SWIPE_DIRECTION_UP;

                            gameplay::Game::getInstance()->gestureSwipeEvent(x, y, direction);
                            __pointer1.pressed = false;
                            gestureDetected = true;
                        }
                        else if(__gestureEventsProcessed.test(Gesture::GESTURE_TAP) &&
                               gameplay::Game::getInstance()->getAbsoluteTime() - __pointer1.time < GESTURE_TAP_DURATION_MAX)
                        {
                            gameplay::Game::getInstance()->gestureTapEvent(x, y);
                            __pointer1.pressed = false;
                            gestureDetected = true;
                        }
                    }

                    if (!gestureDetected && (__multiTouch || __primaryTouchId == pointerId) )
                    {
                        gameplay::Platform::touchEventInternal(Touch::TOUCH_RELEASE, AMotionEvent_getX(event, pointerIndex), AMotionEvent_getY(event, pointerIndex), pointerId);
                    }
                    if (__primaryTouchId == pointerId)
                        __primaryTouchId = -1;
                }
                break;

            case AMOTION_EVENT_ACTION_MOVE:
                {
                    // ACTION_MOVE events are batched, unlike the other events.
                    pointerCount = AMotionEvent_getPointerCount(event);
                    for (size_t i = 0; i < pointerCount; ++i)
                    {
                        pointerId = AMotionEvent_getPointerId(event, i);
                        if (__multiTouch || __primaryTouchId == pointerId)
                        {
                            gameplay::Platform::touchEventInternal(Touch::TOUCH_MOVE, AMotionEvent_getX(event, i), AMotionEvent_getY(event, i), pointerId);
                        }
                    }
                }
                break;
        }
        return 1;
    } 
예제 #14
0
s32 CIrrDeviceAndroid::handleInput(android_app* app, AInputEvent* androidEvent)
{
	CIrrDeviceAndroid* device = (CIrrDeviceAndroid*)app->userData;
	s32 status = 0;

	switch ( AInputEvent_getType(androidEvent) )
	{
		case AINPUT_EVENT_TYPE_MOTION:
		{
			SEvent event;
			event.EventType = EET_TOUCH_INPUT_EVENT;

			s32 eventAction = AMotionEvent_getAction(androidEvent);
			s32 eventType =  eventAction & AMOTION_EVENT_ACTION_MASK;

			bool touchReceived = true;

			switch (eventType)
			{
			case AMOTION_EVENT_ACTION_DOWN:
			case AMOTION_EVENT_ACTION_POINTER_DOWN:
				event.TouchInput.Event = ETIE_PRESSED_DOWN;
				break;
			case AMOTION_EVENT_ACTION_MOVE:
				event.TouchInput.Event = ETIE_MOVED;
				break;
			case AMOTION_EVENT_ACTION_UP:
			case AMOTION_EVENT_ACTION_POINTER_UP:
			case AMOTION_EVENT_ACTION_CANCEL:
				event.TouchInput.Event = ETIE_LEFT_UP;
				break;
			default:
				touchReceived = false;
				break;
			}

			if (touchReceived)
			{
				// Process all touches for move action.
				if (event.TouchInput.Event == ETIE_MOVED)
				{
					s32 pointerCount = AMotionEvent_getPointerCount(androidEvent);

					for (s32 i = 0; i < pointerCount; ++i)
					{
						event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, i);
						event.TouchInput.X = AMotionEvent_getX(androidEvent, i);
						event.TouchInput.Y = AMotionEvent_getY(androidEvent, i);

						device->postEventFromUser(event);
					}
				}
				else // Process one touch for other actions.
				{
					s32 pointerIndex = (eventAction & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;

					event.TouchInput.ID = AMotionEvent_getPointerId(androidEvent, pointerIndex);
					event.TouchInput.X = AMotionEvent_getX(androidEvent, pointerIndex);
					event.TouchInput.Y = AMotionEvent_getY(androidEvent, pointerIndex);

					device->postEventFromUser(event);
				}

				status = 1;
			}
		}
		break;
		case AINPUT_EVENT_TYPE_KEY:
		{
			SEvent event;
			event.EventType = EET_KEY_INPUT_EVENT;

			int32_t keyCode = AKeyEvent_getKeyCode(androidEvent);
			int32_t keyAction = AKeyEvent_getAction(androidEvent);
			int32_t keyMetaState = AKeyEvent_getMetaState(androidEvent);

			if ( keyCode >= 0 && (u32)keyCode < device->KeyMap.size() )
				event.KeyInput.Key = device->KeyMap[keyCode];
			else
				event.KeyInput.Key = KEY_UNKNOWN;
			event.KeyInput.SystemKeyCode = (u32)keyCode;
			if ( keyAction == AKEY_EVENT_ACTION_DOWN )
				event.KeyInput.PressedDown = true;
			else if ( keyAction == AKEY_EVENT_ACTION_UP )
				event.KeyInput.PressedDown = false;
			else if ( keyAction == AKEY_EVENT_ACTION_MULTIPLE )
			{
				// TODO: Multiple duplicate key events have occurred in a row,
				// or a complex string is being delivered. The repeat_count
				// property of the key event contains the number of times the
				// given key code should be executed.
				// I guess this might necessary for more complicated i18n key input,
				// but don't see yet how to handle this correctly.
			}

			/* no use for meta keys so far.
			if (   keyMetaState & AMETA_ALT_ON
				|| keyMetaState & AMETA_ALT_LEFT_ON
				|| keyMetaState & AMETA_ALT_RIGHT_ON )
				;
			// what is a sym?
			if (   keyMetaState & AMETA_SYM_ON )
				;
			*/
			if (   keyMetaState & AMETA_SHIFT_ON
				|| keyMetaState & AMETA_SHIFT_LEFT_ON
				|| keyMetaState & AMETA_SHIFT_RIGHT_ON )
				event.KeyInput.Shift = true;
			else
				event.KeyInput.Shift = false;
			event.KeyInput.Control = false;

			// Having memory allocations + going through JNI for each key-press is pretty bad (slow). 
			// So we do it only for those keys which are likely text-characters and avoid it for all other keys.
			// So it's fast for keys like game controller input and special keys. And text keys are typically 
			// only used or entering text and not for gaming on Android, so speed likely doesn't matter there too much.
			if ( event.KeyInput.Key > 0 )
			{
				// TODO:
				// Not sure why we have to attach a JNIEnv here, but it won't work when doing that in the constructor or 
				// trying to use the activity->env. My best guess is that the event-handling happens in an own thread.
				// It means JNIEnvAttachedToVM will never get detached as I don't know a safe way where to do that 
				// (we could attach & detach each time, but that would probably be slow)
				// Also - it has to be each time as it get's invalid when the application mode changes.
				if ( device->Initialized && device->Android && device->Android->activity && device->Android->activity->vm )
				{
					JavaVMAttachArgs attachArgs;
					attachArgs.version = JNI_VERSION_1_6;
					attachArgs.name = 0;
					attachArgs.group = NULL;

					// Not a big problem calling it each time - it's a no-op when the thread already is attached.
					// And we have to do that as someone else can have detached the thread in the meantime.
					jint result = device->Android->activity->vm->AttachCurrentThread(&device->JNIEnvAttachedToVM, &attachArgs);
					if(result == JNI_ERR)
					{
						os::Printer::log("AttachCurrentThread for the JNI environment failed.", ELL_WARNING);
						device->JNIEnvAttachedToVM = 0;
					}
				
					if ( device->JNIEnvAttachedToVM )
					{
						jni::CKeyEventWrapper * keyEventWrapper = new jni::CKeyEventWrapper(device->JNIEnvAttachedToVM, keyAction, keyCode);
						event.KeyInput.Char = keyEventWrapper->getUnicodeChar(keyMetaState);
						delete keyEventWrapper;
					}
				}
			}
			else
			{
				// os::Printer::log("keyCode: ", core::stringc(keyCode).c_str(), ELL_DEBUG);
				event.KeyInput.Char = 0;
			}
		
			device->postEventFromUser(event);
		}
		break;
		default:
		break;
	}

	return status;
}
예제 #15
0
//Called from the event process thread
static int32_t HandleInputCB(struct android_app* app, AInputEvent* event)
{
//	FPlatformMisc::LowLevelOutputDebugStringf(L"INPUT - type: %x, action: %x, source: %x, keycode: %x, buttons: %x", AInputEvent_getType(event), 
//		AMotionEvent_getAction(event), AInputEvent_getSource(event), AKeyEvent_getKeyCode(event), AMotionEvent_getButtonState(event));

	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
	{
		int action = AMotionEvent_getAction(event);
		int actionType = action & AMOTION_EVENT_ACTION_MASK;
		size_t actionPointer = (size_t)((action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
		bool isActionTargeted = (actionType == AMOTION_EVENT_ACTION_POINTER_DOWN || actionType == AMOTION_EVENT_ACTION_POINTER_UP);

		// trap Joystick events first, with fallthrough if there is no joystick support
		if (((AInputEvent_getSource(event) & AINPUT_SOURCE_CLASS_JOYSTICK) != 0) &&
				(GetAxes != NULL) &&
				(actionType == AMOTION_EVENT_ACTION_MOVE))
		{
			const int axisCount = sizeof(AxisList)/sizeof(int32_t);
			int device = AInputEvent_getDeviceId(event);

			for (int axis = 0; axis < axisCount; axis++)
			{
				float val = GetAxes( event, AxisList[axis], 0);
				FAndroidInputInterface::JoystickAxisEvent( device, AxisList[axis], val);
			}
		}
		else
		{
			TArray<TouchInput> TouchesArray;
			
			TouchType type = TouchEnded;

			switch (actionType)
			{
			case AMOTION_EVENT_ACTION_DOWN:
			case AMOTION_EVENT_ACTION_POINTER_DOWN:
				type = TouchBegan;
				break;
			case AMOTION_EVENT_ACTION_MOVE:
				type = TouchMoved;
				break;
			case AMOTION_EVENT_ACTION_UP:
			case AMOTION_EVENT_ACTION_POINTER_UP:
			case AMOTION_EVENT_ACTION_CANCEL:
			case AMOTION_EVENT_ACTION_OUTSIDE:
				type = TouchEnded;
				break;
			}

			size_t pointerCount = AMotionEvent_getPointerCount(event);

			if (pointerCount == 0)
			{
				return 1;
			}

			ANativeWindow* Window = (ANativeWindow*)FPlatformMisc::GetHardwareWindow();
			if (!Window)
			{
				return 0;
			}

			int32_t Width = 0 ;
			int32_t Height = 0 ;

			if(Window)
			{
				FAndroidWindow::CalculateSurfaceSize(Window, Width, Height);
			}

			// make sure OpenGL context created before accepting touch events.. FAndroidWindow::GetScreenRect() may try to create it early from wrong thread if this is the first call
			if (!GAndroidGPUInfoReady)
			{
				return 1;
			}
			FPlatformRect ScreenRect = FAndroidWindow::GetScreenRect();

			if(isActionTargeted)
			{
				if(actionPointer < 0 || pointerCount < (int)actionPointer)
				{
					return 1;
				}

				int pointerId = AMotionEvent_getPointerId(event, actionPointer);
				float x = FMath::Min<float>(AMotionEvent_getX(event, actionPointer) / Width, 1.f);
				x *= (ScreenRect.Right - 1);
				float y = FMath::Min<float>(AMotionEvent_getY(event, actionPointer) / Height, 1.f);
				y *= (ScreenRect.Bottom - 1);

				UE_LOG(LogAndroid, Verbose, TEXT("Received targeted motion event from pointer %u (id %d) action %d: (%.2f, %.2f)"), actionPointer, pointerId, action, x, y);

				TouchInput TouchMessage;
				TouchMessage.Handle = pointerId;
				TouchMessage.Type = type;
				TouchMessage.Position = FVector2D(x, y);
				TouchMessage.LastPosition = FVector2D(x, y);		//@todo android: AMotionEvent_getHistoricalRawX
				TouchesArray.Add(TouchMessage);
			}
			else
			{
				for (size_t i = 0; i < pointerCount; ++i)
				{
					int pointerId = AMotionEvent_getPointerId(event, i);

					float x = FMath::Min<float>(AMotionEvent_getX(event, i) / Width, 1.f);
					x *= (ScreenRect.Right - 1);
					float y = FMath::Min<float>(AMotionEvent_getY(event, i) / Height, 1.f);
					y *= (ScreenRect.Bottom - 1);

					UE_LOG(LogAndroid, Verbose, TEXT("Received motion event from pointer %u (id %d) action %d: (%.2f, %.2f)"), i, action, AMotionEvent_getPointerId(event,i), x, y);

					TouchInput TouchMessage;
					TouchMessage.Handle = AMotionEvent_getPointerId(event, i);
					TouchMessage.Type = type;
					TouchMessage.Position = FVector2D(x, y);
					TouchMessage.LastPosition = FVector2D(x, y);		//@todo android: AMotionEvent_getHistoricalRawX
					TouchesArray.Add(TouchMessage);
				}
			}

			FAndroidInputInterface::QueueTouchInput(TouchesArray);

#if !UE_BUILD_SHIPPING
			if ((pointerCount >= 4) && (type == TouchBegan))
			{
				bool bShowConsole = true;
				GConfig->GetBool(TEXT("/Script/Engine.InputSettings"), TEXT("bShowConsoleOnFourFingerTap"), bShowConsole, GInputIni);

				if (bShowConsole)
				{
					GShowConsoleWindowNextTick = true;
				}
			}
#endif
		}

		return 1;
	}
	bool OuyaInputView::dispatchGenericMotionEvent(AInputEvent* motionEvent)
	{
		int64_t downTime = AMotionEvent_getDownTime(motionEvent);
		int64_t eventTime = AMotionEvent_getEventTime(motionEvent);
		int32_t action = AMotionEvent_getAction(motionEvent);
		int32_t metaState = AMotionEvent_getMetaState(motionEvent);
		int32_t pointerCount = AMotionEvent_getPointerCount(motionEvent);
		int32_t buttonState = AMotionEvent_getButtonState(motionEvent);
		float xPrecision = AMotionEvent_getXPrecision(motionEvent);
		float yPrecision = AMotionEvent_getYPrecision(motionEvent);
		int32_t deviceId = AInputEvent_getDeviceId(motionEvent);
		int32_t edgeFlags = AMotionEvent_getEdgeFlags(motionEvent);
		int32_t flags = AMotionEvent_getFlags(motionEvent);
		int32_t source = AInputEvent_getSource(motionEvent);

		int* pointerPropertiesId = new int[pointerCount];
		int* pointerPropertiesToolType = new int[pointerCount];
		float* pointerCoordsOrientation = new float[pointerCount];
		float* pointerCoordsPressure = new float[pointerCount];
		float* pointerCoordsSize = new float[pointerCount];
		float* pointerCoordsToolMajor = new float[pointerCount];
		float* pointerCoordsToolMinor = new float[pointerCount];
		float* pointerCoordsTouchMajor = new float[pointerCount];
		float* pointerCoordsTouchMinor = new float[pointerCount];
		float* pointerCoordsX = new float[pointerCount];
		float* pointerCoordsY = new float[pointerCount];

		std::vector<int> listAxisIndices;
		std::vector<float> listAxisValues;

		if (pointerCount > 0)
		{
#if ENABLE_VERBOSE_LOGGING
			__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "pointerCount=%d deviceId=%d source=%d",
				pointerCount, deviceId, source);
#endif

			// MotionEvent.PointerProperties
			long long pointerId = AMotionEvent_getPointerId(motionEvent, 0);
			int32_t toolType = AMotionEvent_getToolType(motionEvent, 0);

#if ENABLE_VERBOSE_LOGGING
			__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "PointerProperties pointerId=%lld toolType-%d",
				pointerId, toolType);
#endif

			pointerPropertiesId[0] = pointerId;
			pointerPropertiesToolType[0] = toolType;

			// MotionEvent.PointerCoords
			float orientation = AMotionEvent_getOrientation(motionEvent, pointerId);
			float pressure = AMotionEvent_getPressure(motionEvent, pointerId);
			float size = AMotionEvent_getSize(motionEvent, pointerId);
			float toolMajor = AMotionEvent_getTouchMajor(motionEvent, pointerId);
			float toolMinor = AMotionEvent_getToolMinor(motionEvent, pointerId);
			float touchMajor = AMotionEvent_getTouchMajor(motionEvent, pointerId);
			float touchMinor = AMotionEvent_getTouchMinor(motionEvent, pointerId);
			float x = AMotionEvent_getX(motionEvent, pointerId);
			float y = AMotionEvent_getY(motionEvent, pointerId);

#if ENABLE_VERBOSE_LOGGING
			__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "PointerCoords orientation=%f pressure=%f size=%f toolMajor=%f toolMinor=%f touchMajor=%f touchMinor=%f x=%f y=%f",
				orientation, pressure, size,
				toolMajor, toolMinor, touchMajor, touchMinor,
				x, y);
#endif

			pointerCoordsOrientation[0] = orientation;
			pointerCoordsPressure[0] = pressure;
			pointerCoordsSize[0] = size;
			pointerCoordsToolMajor[0] = toolMajor;
			pointerCoordsToolMinor[0] = toolMinor;
			pointerCoordsTouchMajor[0] = touchMajor;
			pointerCoordsTouchMinor[0] = touchMinor;
			pointerCoordsX[0] = x;
			pointerCoordsY[0] = y;

			for (int32_t axis = 0; axis < 50; ++axis) // 50 is based on the AXIS_value range I saw in the documentation
			{
				float val = AMotionEvent_getAxisValue(motionEvent, axis, pointerId);
				if (val != 0.0f)
				{
#if ENABLE_VERBOSE_LOGGING
					__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "axis=%d val=%f", axis, val);
#endif
					listAxisIndices.push_back(axis);
					listAxisValues.push_back(val);
				}
			}
		}

		int axisCount = listAxisIndices.size();
		int* axisIndexes = new int[axisCount];
		float* axisValues = new float[axisCount];
		for (int index = 0; index < axisCount; ++index)
		{
			axisIndexes[index] = listAxisIndices[index];
			axisValues[index] = listAxisValues[index];
		}
		listAxisIndices.clear();
		listAxisValues.clear();

		bool handled = javaDispatchGenericMotionEvent(
			downTime,
			eventTime,
			action,
			pointerCount,
			metaState,
			buttonState,
			xPrecision,
			yPrecision,
			deviceId,
			edgeFlags,
			source,
			flags,
			pointerPropertiesId,
			pointerPropertiesToolType,
			pointerCoordsOrientation,
			pointerCoordsPressure,
			pointerCoordsSize,
			pointerCoordsToolMajor,
			pointerCoordsToolMinor,
			pointerCoordsTouchMajor,
			pointerCoordsTouchMinor,
			pointerCoordsX,
			pointerCoordsY,
			axisCount,
			axisIndexes,
			axisValues);

		delete pointerPropertiesId;
		delete pointerPropertiesToolType;
		delete pointerCoordsOrientation;
		delete pointerCoordsPressure;
		delete pointerCoordsSize;
		delete pointerCoordsToolMajor;
		delete pointerCoordsToolMinor;
		delete pointerCoordsTouchMajor;
		delete pointerCoordsTouchMinor;
		delete pointerCoordsX;
		delete pointerCoordsY;
		delete axisIndexes;
		delete axisValues;
		return handled;
	}
예제 #17
0
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
{
	struct engine* engine = (struct engine*)app->userData;
	if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
	{
		// touch event

		int action = AMotionEvent_getAction( event ) & 0xff;
		int pointer = (AMotionEvent_getAction( event ) >> 8) & 0xff;
		int flags = AMotionEvent_getFlags( event );
		int pointers = AMotionEvent_getPointerCount( event );
		int id = AMotionEvent_getPointerId( event, pointer );

		float x = AMotionEvent_getX( event, pointer );
		float y = AMotionEvent_getY( event, pointer );
		//if ( action != 2 ) LOGW("Action: %d, pointer: %d, count: %d, id: %d", action, pointer, pointers, id);
		//__android_log_print(ANDROID_LOG_VERBOSE, "test", "Action: %d, pointer: %d, count: %d, id: %d, lx: %f, ly: %f, rx: %f, ry: %f", action, pointer, pointers, id, lx, ly, rx, ry);
		switch ( action )
		{
			case 0:
			case 5: touchdown( id, x, y ); break;
			case 1:
			case 3:
			case 6: touchup( id, x, y ); break;
			case 2:
				{
				float lx = AMotionEvent_getAxisValue(event, AXIS_X, pointer);
				float ly = AMotionEvent_getAxisValue(event, AXIS_Y, pointer);
				float rx = AMotionEvent_getAxisValue(event, AXIS_Z, pointer);
				float ry = AMotionEvent_getAxisValue(event, AXIS_RZ, pointer);
				
				if((lx > joystick_treshold || lx < -joystick_treshold) || (ly > joystick_treshold || ly < -joystick_treshold)) 
				{
					touchdown( 0, lx*1000.0f, ly*1000.0f );
//					touchmoved( 0, x*100.0f, y*100.0f );
				}
				else
					touchup( 0, lx*1000.0f, ly*1000.0f );

				if((rx > joystick_treshold || rx < -joystick_treshold) || (ry > joystick_treshold || ry < -joystick_treshold))
				{
					touchdown( 1, rx*1000.0f, ry*1000.0f );
//					touchmoved( -1, x*255.0f, y*255.0f );
//					__android_log_print(ANDROID_LOG_VERBOSE, "test", "right joystick moved");
				}			
				else
					touchup( 1, rx*1000.0f, ry*1000.0f );
					// only the primary pointer sends move messages so get the other pointer positions while we are here
					if ( pointers > 1 )
					{
						int i = 1;
						for ( i = 1; i < pointers; i++ )
						{
							int id = AMotionEvent_getPointerId( event, i );
							x = AMotionEvent_getX( event, i );
							y = AMotionEvent_getY( event, i );
							touchmoved( id, x, y );
						}
					}
					break;
				}
			default: break;
		}

		return 1;
	}