///////////////////////////////////////////////////////
| 490 | |
| 491 | //////////////////////////////////////////////////////////// |
| 492 | int WindowImplAndroid::processMotionEvent(AInputEvent* inputEvent, ActivityStates& states) |
| 493 | { |
| 494 | const std::int32_t device = AInputEvent_getSource(inputEvent); |
| 495 | const std::size_t pointerCount = AMotionEvent_getPointerCount(inputEvent); |
| 496 | |
| 497 | for (std::size_t p = 0; p < pointerCount; ++p) |
| 498 | { |
| 499 | const std::int32_t id = AMotionEvent_getPointerId(inputEvent, p); |
| 500 | |
| 501 | const int x = static_cast<int>(AMotionEvent_getX(inputEvent, p)); |
| 502 | const int y = static_cast<int>(AMotionEvent_getY(inputEvent, p)); |
| 503 | |
| 504 | if (device == AINPUT_SOURCE_MOUSE) |
| 505 | { |
| 506 | const Event::MouseMoved mouseMoved{{x, y}}; |
| 507 | forwardEvent(mouseMoved); |
| 508 | |
| 509 | states.mousePosition = mouseMoved.position; |
| 510 | } |
| 511 | else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_TOUCHSCREEN) |
| 512 | { |
| 513 | if (states.touchEvents[id].x == x && states.touchEvents[id].y == y) |
| 514 | continue; |
| 515 | |
| 516 | const Event::TouchMoved touchMoved{static_cast<unsigned int>(id), {x, y}}; |
| 517 | forwardEvent(touchMoved); |
| 518 | |
| 519 | states.touchEvents[id] = touchMoved.position; |
| 520 | } |
| 521 | else if (static_cast<std::uint32_t>(device) & AINPUT_SOURCE_JOYSTICK) |
| 522 | { |
| 523 | // There seems to be no direct mapping between input event and the ID of the device that |
| 524 | // caused the event. However, as the single input event contains all axii changes, it's possible |
| 525 | // to poll values for all axii in a single loop iteration. |
| 526 | // |
| 527 | // Additionally, some controllers such as the Xbox One controller will report triggers as |
| 528 | // negative/positive values on the single axis on Windows, while Android reports them |
| 529 | // on two separate axii. |
| 530 | const auto deviceId = AInputEvent_getDeviceId(inputEvent); |
| 531 | if (states.joystickStates.find(deviceId) == states.joystickStates.end()) |
| 532 | return 1; |
| 533 | |
| 534 | const float factor = 100.f; // SFML normalizes axis to the range <-100, 100> instead of <-1, 1> |
| 535 | auto& axes = states.joystickStates[deviceId].axes; |
| 536 | |
| 537 | for (unsigned int axisIdx = 0; axisIdx < Joystick::AxisCount; ++axisIdx) |
| 538 | { |
| 539 | const auto axis = static_cast<Joystick::Axis>(axisIdx); |
| 540 | axes[axis] = AMotionEvent_getAxisValue(inputEvent, JoystickImpl::sfAxisToAndroid(axis), p) * factor; |
| 541 | } |
| 542 | } |
| 543 | } |
| 544 | |
| 545 | return 1; |
| 546 | } |
| 547 | |
| 548 | |
| 549 | //////////////////////////////////////////////////////////// |