bool CAndroidJoyStick::ProcessHat(AInputEvent *event, size_t pointer_index, APP_InputDeviceAxis &hat, int device, int android_axis) { bool rtn = false; // Dpad (quantized to -1.0, 0.0 and 1.0) float value = AMotionEvent_getAxisValue(event, android_axis, pointer_index); if (value != hat.value) { u_int8_t hatvalue = XBMC_HAT_CENTERED; if (value != 0) switch (android_axis) { case AMOTION_EVENT_AXIS_HAT_X: if (value < 0) hatvalue |= XBMC_HAT_LEFT; else hatvalue |= XBMC_HAT_RIGHT; break; case AMOTION_EVENT_AXIS_HAT_Y: if (value < 0) hatvalue |= XBMC_HAT_UP; else hatvalue |= XBMC_HAT_DOWN; break; } XBMC_JoyHat(device, hatvalue); rtn = true; } hat.value = value; return rtn; }
bool CAndroidMouse::onMouseEvent(AInputEvent* event) { if (event == NULL) return false; int32_t eventAction = AMotionEvent_getAction(event); int8_t mouseAction = eventAction & AMOTION_EVENT_ACTION_MASK; size_t mousePointerIdx = eventAction >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; int32_t mousePointerId = AMotionEvent_getPointerId(event, mousePointerIdx); #ifdef DEBUG_VERBOSE CXBMCApp::android_printf("%s idx:%i, id:%i", __PRETTY_FUNCTION__, mousePointerIdx, mousePointerId); #endif CPoint in(AMotionEvent_getX(event, mousePointerIdx), AMotionEvent_getY(event, mousePointerIdx)); CPoint out = in * m_droid2guiRatio; switch (mouseAction) { case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_DOWN: MouseButton(out.x, out.y, mouseAction, AMotionEvent_getButtonState(event)); return true; case AMOTION_EVENT_ACTION_SCROLL: MouseWheel(out.x, out.y, AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_VSCROLL, mousePointerIdx)); return true; default: MouseMove(out.x, out.y); return true; } return false; }
static float MapAxis(AInputEvent* event, int32_t axis) { const float deadZone = 0.1f; float value = AMotionEvent_getAxisValue(event, axis, 0); if (value > deadZone) return (value - deadZone) / (1.0f - deadZone); else return 0.0f; }
// overly-simple dead-zoning for now. static float MapCenteredAxis(AInputEvent* event, int32_t axis) { const float deadZone = (8689.0f / 32768.0f); float value = AMotionEvent_getAxisValue(event, axis, 0); if (value > deadZone) return (value - deadZone) / (1.0f - deadZone); else if (value < -deadZone) return (value + deadZone) / (1.0f - deadZone); else return 0.0f; }
void NvGamepadAndroid::ProcessDPAD(AInputEvent* event, State& state) { const float deadZone = 0.5f; float h = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0); float v = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_Y, 0); if (h < -deadZone) state.mButtons = (state.mButtons & (~BUTTON_DPAD_RIGHT)) | BUTTON_DPAD_LEFT; else if (h > deadZone) state.mButtons = (state.mButtons & (~BUTTON_DPAD_LEFT)) | BUTTON_DPAD_RIGHT; else state.mButtons &= ~(BUTTON_DPAD_LEFT | BUTTON_DPAD_RIGHT); if (v < -deadZone) state.mButtons = (state.mButtons & (~BUTTON_DPAD_DOWN)) | BUTTON_DPAD_UP; else if (v > deadZone) state.mButtons = (state.mButtons & (~BUTTON_DPAD_UP)) | BUTTON_DPAD_DOWN; else state.mButtons &= ~(BUTTON_DPAD_DOWN | BUTTON_DPAD_UP); }
int32_t VulkanExampleBase::handleAppInput(struct android_app* app, AInputEvent* event) { VulkanExampleBase* vulkanExample = (VulkanExampleBase*)app->userData; if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { if (AInputEvent_getSource(event) == AINPUT_SOURCE_JOYSTICK) { vulkanExample->gamePadState.axes.x = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_X, 0); vulkanExample->gamePadState.axes.y = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Y, 0); vulkanExample->gamePadState.axes.z = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Z, 0); vulkanExample->gamePadState.axes.rz = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_RZ, 0); } else { // todo : touch input } return 1; } return 0; }
bool CAndroidJoyStick::ProcessAxis(AInputEvent *event, size_t pointer_index, APP_InputDeviceAxis &axis, int device, int keymap_axis, int android_axis) { bool rtn = false; float value = AMotionEvent_getAxisValue(event, android_axis, pointer_index); //CLog::Log(LOGDEBUG, "ProcessAxis: keymap_axis(%d), value(%f)", keymap_axis, value); value = AxisClampAsButton(axis, value); if (value != axis.value) { XBMC_JoyAxis(device, keymap_axis, value); rtn = true; } axis.value = value; return rtn; }
int32_t touch(bool down, int32_t action, AInputEvent* event) { auto& windowRef = Engine::getMainWindow(); const int32_t device = AInputEvent_getSource(event); if (device & AINPUT_SOURCE_TOUCHSCREEN) { const int index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; const int id = AMotionEvent_getPointerId(event, index); if (id < 10) { const float x = AMotionEvent_getX(event, index); const float y = AMotionEvent_getY(event, index); auto state = ActivityState::get(); if (down) { state->lastTouchPosition[id] = glm::vec2(x, y); windowRef.getEventHandler()->touchPressed(id, x, y); } else { state->lastTouchPosition[id] = glm::vec2(-1.f, -1.f); windowRef.getEventHandler()->touchReleased(id, x, y); } for (int info = 0; info < 4; ++info) { const float i = AMotionEvent_getAxisValue(event, ns_touchAxes[info], index); if (i > JOP_AXIS_TOLERANCE) windowRef.getEventHandler()->touchInfo(id, Input::getJopTouchInfo(ns_touchAxes[info]), i); } return 1; } } return 0; }
static int32_t _onInputEvent(struct android_app* app, AInputEvent* event) { if (!event || !::g_defaultWindow.get()) { return 1; } int32_t source = AInputEvent_getSource(event); if (source == AINPUT_SOURCE_MOUSE) { int32_t x = (int32_t)AMotionEvent_getX(event, 0); int32_t y = (int32_t)AMotionEvent_getY(event, 0); g_defaultWindow->getMouseInput().setLocation(glm::ivec2(x, y)); int32_t buttonState = AMotionEvent_getButtonState(event); g_defaultWindow->getMouseInput().setButton(VKTS_MOUSE_BUTTON_LEFT, buttonState & AMOTION_EVENT_BUTTON_PRIMARY); g_defaultWindow->getMouseInput().setButton(VKTS_MOUSE_BUTTON_RIGHT, buttonState & AMOTION_EVENT_BUTTON_SECONDARY); g_defaultWindow->getMouseInput().setButton(VKTS_MOUSE_BUTTON_MIDDLE, buttonState & AMOTION_EVENT_BUTTON_TERTIARY); int32_t vscroll = (int32_t)AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_VSCROLL, 0); g_defaultWindow->getMouseInput().setMouseWheel(vscroll); return 1; } else if (source == AINPUT_SOURCE_KEYBOARD) { VkBool32 pressed = (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN); int32_t scanCode = AKeyEvent_getScanCode(event); int32_t key = vkts::_visualTranslateKey(scanCode); if (pressed && key == VKTS_KEY_ESCAPE) { g_app->destroyRequested = 1; } else if (key != VKTS_KEY_UNKNOWN) { g_defaultWindow->getKeyInput().setKey(key, pressed); } return 1; } else if (source == AINPUT_SOURCE_JOYSTICK) { int32_t pointerIndex = (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT; if (pointerIndex >= 0 && pointerIndex < VKTS_MAX_GAMEPADS) { for (int32_t axis = AMOTION_EVENT_AXIS_X; axis <= AMOTION_EVENT_AXIS_RTRIGGER; axis++) { int32_t axisIndex = -1; float axisValue = AMotionEvent_getAxisValue(event, axis, pointerIndex); switch (axis) { case AMOTION_EVENT_AXIS_X: axisIndex = VKTS_GAMEPAD_LEFT_STICK_X; break; case AMOTION_EVENT_AXIS_Y: axisIndex = VKTS_GAMEPAD_LEFT_STICK_Y; axisValue = -axisValue; break; case AMOTION_EVENT_AXIS_Z: axisIndex = VKTS_GAMEPAD_RIGHT_STICK_X; break; case AMOTION_EVENT_AXIS_RZ: axisIndex = VKTS_GAMEPAD_RIGHT_STICK_Y; axisValue = -axisValue; break; case AMOTION_EVENT_AXIS_LTRIGGER: axisIndex = VKTS_GAMEPAD_LEFT_TRIGGER; break; case AMOTION_EVENT_AXIS_RTRIGGER: axisIndex = VKTS_GAMEPAD_RIGHT_TRIGGER; break; case AMOTION_EVENT_AXIS_HAT_X: { VkBool32 buttonPressed = axisValue < 0.0f ? VK_TRUE : VK_FALSE; g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_LEFT, buttonPressed); buttonPressed = axisValue > 0.0f ? VK_TRUE : VK_FALSE; g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_RIGHT, buttonPressed); } break; case AMOTION_EVENT_AXIS_HAT_Y: { VkBool32 buttonPressed = axisValue > 0.0f ? VK_TRUE : VK_FALSE; g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_DOWN, buttonPressed); buttonPressed = axisValue < 0.0f ? VK_TRUE : VK_FALSE; g_defaultWindow->getGamepadInput(pointerIndex).setButton(VKTS_GAMEPAD_DPAD_UP, buttonPressed); } break; } if (axisIndex == -1) { continue; } g_defaultWindow->getGamepadInput(pointerIndex).setAxis(axisIndex, axisValue); } } return 1; }
/* * 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 & AMOTION_EVENT_ACTION_MASK ) { case AMOTION_EVENT_ACTION_DOWN: case AMOTION_EVENT_ACTION_UP: { static int32_t oldButtonState = 0; int32_t buttonState = AMotionEvent_getButtonState( event ); int32_t buttonsDown = buttonState & ~oldButtonState, buttonsUp = oldButtonState & ~buttonState; int32_t buttonsChanged = buttonsDown | buttonsUp; int button; oldButtonState = buttonState; for( button = 0; buttonsChanged >> button; button++ ) { if( buttonsChanged & ( 1 << button ) ) Key_MouseEvent( K_MOUSE1 + button, ( buttonsDown & ( 1 << button ) ) ? true : 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; case AMOTION_EVENT_ACTION_SCROLL: { float scroll = AMotionEvent_getAxisValue( event, AMOTION_EVENT_AXIS_VSCROLL, 0 ); if( scroll > 0.0f ) { Key_Event( K_MWHEELUP, true, time ); Key_Event( K_MWHEELUP, false, time ); } else if( scroll < 0.0f ) { Key_Event( K_MWHEELDOWN, true, time ); Key_Event( K_MWHEELDOWN, false, time ); } } break; } } break; } return 1; }
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { struct engineState* engine = (struct engineState*)app->userData; if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { int source = AInputEvent_getSource(event); if (source == AINPUT_SOURCE_TOUCHSCREEN) { float x = AMotionEvent_getX(event, 0); float y = AMotionEvent_getY(event, 0); engine->instance->getAndroidInputSystem()->handleTouchInput(x, y); return 1; } if (source == AINPUT_SOURCE_JOYSTICK) { float x = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_X, 0); float y = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_Y, 0); int devId = AInputEvent_getDeviceId(event); LOG_INFO("dev: " << devId << " pos: " << x << ":" << y); } return 0; } if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY) { int32_t source = AInputEvent_getSource(event); int32_t code = AKeyEvent_getKeyCode(event); int32_t action = AKeyEvent_getAction(event); LOG_INFO("Code: " << code << " Action: " << action); engine::input::KeyCode keycode = engine::input::KEY_VOID; switch (code) { case 96: keycode = engine::input::BUTTON_A; break; case 99: keycode = engine::input::BUTTON_X; break; case 100: keycode = engine::input::BUTTON_Y; break; case 97: keycode = engine::input::BUTTON_B; break; } if (action == 1) engine->instance->getInputSystem()->keyUp(keycode); else engine->instance->getInputSystem()->keyDown(keycode); return 1; } return 0; }
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; }
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; }
/** * Process the next input event. */ static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { // these values correspond to the queriable axes indicated enum { AXIS_X = 0, // left joystick, left to right AXIS_Y = 1, // left joystick, up to down AXIS_Z = 11, // right joystick, left to right AXIS_RZ = 14, // right joystick, up to down AXIS_HAT_X = 15, // DPAD left to right AXIS_HAT_Y = 16, // DPAD up to down AXIS_LTRIGGER = 17, // left trigger AXIS_RTRIGGER = 18 // right trigger }; struct engine* engine = (struct engine*)app->userData; if (AInputEvent_getSource(event) & AINPUT_SOURCE_CLASS_POINTER) return 0; // ignore touch events int type = AInputEvent_getType(event); if (type == AINPUT_EVENT_TYPE_KEY) { int key = AKeyEvent_getKeyCode(event); switch (key) { case AKEYCODE_BUTTON_L1: LOGI("Pressed L1"); engine->state.x = -0.5; break; case AKEYCODE_BUTTON_R1: LOGI("Pressed R1"); engine->state.x = 0.5; break; case AKEYCODE_DPAD_LEFT: LOGI("Pressed DPADL"); engine->state.x = -0.5; break; case AKEYCODE_DPAD_RIGHT: LOGI("Pressed DPADR"); engine->state.x = 0.5; break; case AKEYCODE_BUTTON_THUMBL: LOGI("Pressed LAS"); engine->state.x = -0.5; break; case AKEYCODE_BUTTON_THUMBR: LOGI("Pressed RAS"); engine->state.x = 0.5; break; default: break; } return 1; } else if (type == AINPUT_EVENT_TYPE_MOTION) { float las_l2r = AMotionEvent_getAxisValue(event, AXIS_X, 0); if (las_l2r == -1.0) engine->state.x = -0.5; else if (las_l2r == 1.0) engine->state.x = 0.5; float ras_l2r = AMotionEvent_getAxisValue(event, AXIS_Z, 0); if (ras_l2r == -1.0) engine->state.x = -0.5; else if (ras_l2r == 1.0) engine->state.x = 0.5; float dpad_l2r = AMotionEvent_getAxisValue(event, AXIS_HAT_X, 0); if (dpad_l2r == -1.0) engine->state.x = -0.5; else if (dpad_l2r == 1.0) engine->state.x = 0.5; float ltrigger = AMotionEvent_getAxisValue(event, AXIS_LTRIGGER, 0); if (ltrigger == 1.0) engine->state.x = -0.5; float rtrigger = AMotionEvent_getAxisValue(event, AXIS_RTRIGGER, 0); if (rtrigger == 1.0) engine->state.x = 0.5; LOGI("Motion event LAS:%f RAS:%f DPAD:%f LTRIG:%f RTRIG:%f", las_l2r, ras_l2r, dpad_l2r, ltrigger, rtrigger); return 1; } return 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; }