#include #include #include #include "inputconvertgame.h" #define CURSOR_POS_CHECK 50 InputConvertGame::InputConvertGame(Controller* controller) : InputConvertNormal(controller) { } InputConvertGame::~InputConvertGame() { } void InputConvertGame::mouseEvent(const QMouseEvent *from, const QSize &frameSize, const QSize &showSize) { if (m_gameMap) { updateSize(frameSize, showSize); if (m_keyMap.enableMouseMoveMap()) { // mouse move if (processMouseMove(from)) { return; } } // mouse click if (processMouseClick(from)) { return; } } else { InputConvertNormal::mouseEvent(from, frameSize, showSize); } } void InputConvertGame::wheelEvent(const QWheelEvent *from, const QSize &frameSize, const QSize &showSize) { if (m_gameMap) { updateSize(frameSize, showSize); } else { InputConvertNormal::wheelEvent(from, frameSize, showSize); } } void InputConvertGame::keyEvent(const QKeyEvent *from, const QSize& frameSize, const QSize& showSize) { // 处理开关按键 if (m_keyMap.getSwitchKey() == from->key()) { if (QEvent::KeyPress == from->type()) { if (!switchGameMap()) { m_needSwitchGameAgain = false; } } return; } KeyMap::KeyMapNode& node = m_keyMap.getKeyMapNode(from->key()); // 处理特殊按键:可以在按键映射和普通映射间切换的按键 if (m_needSwitchGameAgain && KeyMap::KMT_CLICK == node.type && node.click.switchMap) { updateSize(frameSize, showSize); // Qt::Key_Tab Qt::Key_M processKeyClick(node.click.keyNode.pos, false, node.click.switchMap, from); return; } if (m_gameMap) { updateSize(frameSize, showSize); if (!from || from->isAutoRepeat()) { return; } // 处理方向盘 if (KeyMap::KMT_STEER_WHEEL == node.type) { processSteerWheel(node, from); return; } // 处理普通按键 switch (node.type) { case KeyMap::KMT_CLICK: processKeyClick(node.click.keyNode.pos, false, node.click.switchMap, from); return; case KeyMap::KMT_CLICK_TWICE: processKeyClick(node.clickTwice.keyNode.pos, true, false, from); return; } } else { InputConvertNormal::keyEvent(from, frameSize, showSize); } } void InputConvertGame::loadKeyMap(const QString &json) { m_keyMap.loadKeyMap(json); if (m_keyMap.enableMouseMoveMap()) { m_mouseMoveLastConverPos = m_keyMap.getMouseMoveMap().startPos; } } void InputConvertGame::updateSize(const QSize &frameSize, const QSize &showSize) { m_frameSize = frameSize; m_showSize = showSize; } void InputConvertGame::sendTouchDownEvent(int id, QPointF pos) { sendTouchEvent(id, pos, AMOTION_EVENT_ACTION_DOWN); } void InputConvertGame::sendTouchMoveEvent(int id, QPointF pos) { sendTouchEvent(id, pos, AMOTION_EVENT_ACTION_MOVE); } void InputConvertGame::sendTouchUpEvent(int id, QPointF pos) { sendTouchEvent(id, pos, AMOTION_EVENT_ACTION_UP); } void InputConvertGame::sendTouchEvent(int id, QPointF pos, AndroidMotioneventAction action) { if (0 > id || MULTI_TOUCH_MAX_NUM-1 < id) { return; } ControlMsg* controlMsg = new ControlMsg(ControlMsg::CMT_INJECT_TOUCH); if (!controlMsg) { return; } controlMsg->setInjectTouchMsgData(id, action, QRect(calcFrameAbsolutePos(pos).toPoint(), m_frameSize)); sendControlMsg(controlMsg); } QPointF InputConvertGame::calcFrameAbsolutePos(QPointF relativePos) { QPointF absolutePos; absolutePos.setX(m_frameSize.width() * relativePos.x()); absolutePos.setY(m_frameSize.height() * relativePos.y()); return absolutePos; } int InputConvertGame::attachTouchID(int key) { for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) { if (0 == multiTouchID[i]) { multiTouchID[i] = key; return i; } } return -1; } void InputConvertGame::detachTouchID(int key) { for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) { if (key == multiTouchID[i]) { multiTouchID[i] = 0; return; } } } int InputConvertGame::getTouchID(int key) { for (int i = 0; i < MULTI_TOUCH_MAX_NUM; i++) { if (key == multiTouchID[i]) { return i; } } return -1; } void InputConvertGame::processSteerWheel(KeyMap::KeyMapNode &node, const QKeyEvent *from) { int keyPress1 = Qt::Key_unknown; int keyPress2 = Qt::Key_unknown; int keysNum = updateSteerWheelKeysPress(node, from, keyPress1, keyPress2); bool needMove = false; if (QEvent::KeyPress == from->type()) { if (1 == keysNum) { node.steerWheel.firstPressKey = from->key(); int id = attachTouchID(node.steerWheel.firstPressKey); if (-1 == id) { return; } sendTouchDownEvent(id, node.steerWheel.centerPos); needMove = true; } else if (2 == keysNum) { needMove = true; } } else if (QEvent::KeyRelease == from->type()){ if (0 == keysNum) { int id = getTouchID(node.steerWheel.firstPressKey); sendTouchUpEvent(id, node.steerWheel.centerPos); detachTouchID(node.steerWheel.firstPressKey); node.steerWheel.firstPressKey = 0; } else if (1 == keysNum) { needMove = true; } } if (needMove) { steerWheelMove(node, keysNum, keyPress1, keyPress2); } } int InputConvertGame::updateSteerWheelKeysPress(KeyMap::KeyMapNode &node, const QKeyEvent *from, int& keyPress1, int& keyPress2) { bool keyPress = false; if (QEvent::KeyPress == from->type()) { keyPress = true; } else if (QEvent::KeyRelease == from->type()) { keyPress = false; } if (from->key() == node.steerWheel.upKey) { node.steerWheel.upKeyPressed = keyPress; } else if (from->key() == node.steerWheel.rightKey) { node.steerWheel.rightKeyPressed = keyPress; } else if (from->key() == node.steerWheel.downKey) { node.steerWheel.downKeyPressed = keyPress; } else if (from->key() == node.steerWheel.leftKey) { node.steerWheel.leftKeyPressed = keyPress; } int count = 0; keyPress1 = Qt::Key_unknown; keyPress2 = Qt::Key_unknown; // 上右下左的顺序统计按键数量,并记录前两个按键码 if (node.steerWheel.upKeyPressed) { count++; if (Qt::Key_unknown == keyPress1) { keyPress1 = node.steerWheel.upKey; } else if (Qt::Key_unknown == keyPress2) { keyPress2 = node.steerWheel.upKey; } } if (node.steerWheel.rightKeyPressed) { count++; if (Qt::Key_unknown == keyPress1) { keyPress1 = node.steerWheel.rightKey; } else if (Qt::Key_unknown == keyPress2) { keyPress2 = node.steerWheel.rightKey; } } if (node.steerWheel.downKeyPressed) { count++; if (Qt::Key_unknown == keyPress1) { keyPress1 = node.steerWheel.downKey; } else if (Qt::Key_unknown == keyPress2) { keyPress2 = node.steerWheel.downKey; } } if (node.steerWheel.leftKeyPressed) { count++; if (Qt::Key_unknown == keyPress1) { keyPress1 = node.steerWheel.leftKey; } else if (Qt::Key_unknown == keyPress2) { keyPress2 = node.steerWheel.leftKey; } } return count; } void InputConvertGame::steerWheelMove(KeyMap::KeyMapNode &node, int keysNum, int keyPress1, int keyPress2) { if (1 != keysNum && 2 != keysNum) { return; } QPointF movePos = node.steerWheel.centerPos; switch (keysNum) { case 2: if (keyPress2 == node.steerWheel.upKey) { movePos.setY(movePos.y() - node.steerWheel.upOffset); } else if (keyPress2 == node.steerWheel.rightKey) { movePos.setX(movePos.x() + node.steerWheel.rightOffset); } else if (keyPress2 == node.steerWheel.downKey) { movePos.setY(movePos.y() + node.steerWheel.downOffset); } else if (keyPress2 == node.steerWheel.leftKey) { movePos.setX(movePos.x() - node.steerWheel.leftOffset); } case 1: if (keyPress1 == node.steerWheel.upKey) { movePos.setY(movePos.y() - node.steerWheel.upOffset); } else if (keyPress1 == node.steerWheel.rightKey) { movePos.setX(movePos.x() + node.steerWheel.rightOffset); } else if (keyPress1 == node.steerWheel.downKey) { movePos.setY(movePos.y() + node.steerWheel.downOffset); } else if (keyPress1 == node.steerWheel.leftKey) { movePos.setX(movePos.x() - node.steerWheel.leftOffset); } break; } sendTouchMoveEvent(getTouchID(node.steerWheel.firstPressKey), movePos); } void InputConvertGame::processKeyClick(QPointF clickPos, bool clickTwice, bool switchMap, const QKeyEvent *from) { if (switchMap && QEvent::KeyRelease == from->type()) { m_needSwitchGameAgain = !m_needSwitchGameAgain; switchGameMap(); } if (QEvent::KeyPress == from->type()) { int id = attachTouchID(from->key()); sendTouchDownEvent(id, clickPos); if (clickTwice) { sendTouchUpEvent(getTouchID(from->key()), clickPos); detachTouchID(from->key()); } } else if (QEvent::KeyRelease == from->type()) { if (clickTwice) { int id = attachTouchID(from->key()); sendTouchDownEvent(id, clickPos); } sendTouchUpEvent(getTouchID(from->key()), clickPos); detachTouchID(from->key()); } } bool InputConvertGame::processMouseClick(const QMouseEvent *from) { KeyMap::KeyMapNode& node = m_keyMap.getKeyMapNode(from->button()); if (KeyMap::KMT_INVALID == node.type) { return false; } if (QEvent::MouseButtonPress == from->type() || QEvent::MouseButtonDblClick == from->type()) { int id = attachTouchID(from->button()); sendTouchDownEvent(id, node.click.keyNode.pos); } else if (QEvent::MouseButtonRelease == from->type()) { sendTouchUpEvent(getTouchID(from->button()), node.click.keyNode.pos); detachTouchID(from->button()); } else { return false; } return true; } bool InputConvertGame::processMouseMove(const QMouseEvent *from) { if (QEvent::MouseMove != from->type()) { return false; } if (checkCursorPos(from)) { m_mouseMoveLastPos = QPointF(0.0f, 0.0f); return true; } if (!m_mouseMoveLastPos.isNull()) { QPointF distance = from->localPos() - m_mouseMoveLastPos; distance /= m_keyMap.getMouseMoveMap().speedRatio; mouseMoveStartTouch(from); startMouseMoveTimer(); m_mouseMoveLastConverPos.setX(m_mouseMoveLastConverPos.x() + distance.x() / m_showSize.width()); m_mouseMoveLastConverPos.setY(m_mouseMoveLastConverPos.y() + distance.y() / m_showSize.height()); if (m_mouseMoveLastConverPos.x() < 0.1 || m_mouseMoveLastConverPos.x() > 0.8 || m_mouseMoveLastConverPos.y() < 0.1 || m_mouseMoveLastConverPos.y() > 0.8) { mouseMoveStopTouch(); mouseMoveStartTouch(from); } sendTouchMoveEvent(getTouchID(Qt::ExtraButton24), m_mouseMoveLastConverPos); } m_mouseMoveLastPos = from->localPos(); return true; } void InputConvertGame::moveCursorToStart(const QMouseEvent *from) { QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().startPos; QPoint localPos = QPoint(m_showSize.width()*mouseMoveStartPos.x(), m_showSize.height()*mouseMoveStartPos.y()); QPoint posOffset = from->localPos().toPoint() - localPos; QPoint globalPos = from->globalPos(); globalPos -= posOffset; QCursor::setPos(globalPos); } void InputConvertGame::moveCursorTo(const QMouseEvent *from, const QPoint &pos) { QPoint posOffset = from->localPos().toPoint() - pos; QPoint globalPos = from->globalPos(); globalPos -= posOffset; QCursor::setPos(globalPos); } void InputConvertGame::startMouseMoveTimer() { stopMouseMoveTimer(); m_mouseMoveTimer = startTimer(1000); } void InputConvertGame::stopMouseMoveTimer() { if (0 != m_mouseMoveTimer) { killTimer(m_mouseMoveTimer); m_mouseMoveTimer = 0; } } void InputConvertGame::mouseMoveStartTouch(const QMouseEvent* from) { Q_UNUSED(from); if (!m_mouseMovePress) { QPointF mouseMoveStartPos = m_keyMap.getMouseMoveMap().startPos; //moveCursorToStart(from); int id = attachTouchID(Qt::ExtraButton24); sendTouchDownEvent(id, mouseMoveStartPos); m_mouseMoveLastConverPos = mouseMoveStartPos; m_mouseMovePress = true; } } void InputConvertGame::mouseMoveStopTouch() { if (m_mouseMovePress) { sendTouchUpEvent(getTouchID(Qt::ExtraButton24), m_mouseMoveLastConverPos); detachTouchID(Qt::ExtraButton24); m_mouseMovePress = false; } } bool InputConvertGame::switchGameMap() { m_gameMap = !m_gameMap; emit grabCursor(m_gameMap); if (m_gameMap) { QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor)); } else { mouseMoveStopTouch(); QGuiApplication::restoreOverrideCursor(); } return m_gameMap; } bool InputConvertGame::checkCursorPos(const QMouseEvent *from) { bool moveCursor = false; QPoint pos = from->pos(); if (pos.x() < CURSOR_POS_CHECK) { pos.setX(m_showSize.width() - CURSOR_POS_CHECK); moveCursor = true; } else if (pos.x() > m_showSize.width() - CURSOR_POS_CHECK) { pos.setX(CURSOR_POS_CHECK); moveCursor = true; } else if (pos.y() < CURSOR_POS_CHECK) { pos.setY(m_showSize.height() - CURSOR_POS_CHECK); moveCursor = true; } else if (pos.y() > m_showSize.height() - CURSOR_POS_CHECK) { pos.setY(CURSOR_POS_CHECK); moveCursor = true; } if (moveCursor) { moveCursorTo(from, pos); } return moveCursor; } void InputConvertGame::timerEvent(QTimerEvent *event) { if (m_mouseMoveTimer == event->timerId()) { stopMouseMoveTimer(); mouseMoveStopTouch(); } }