feat: add steel wheel delay

This commit is contained in:
Barry 2021-06-27 20:22:22 +08:00
commit 47a416801c
2 changed files with 114 additions and 21 deletions

View file

@ -2,12 +2,18 @@
#include <QCursor>
#include <QGuiApplication>
#include <QTimer>
#include <QTime>
#include <QRandomGenerator>
#include "inputconvertgame.h"
#define CURSOR_POS_CHECK 50
InputConvertGame::InputConvertGame(Controller *controller) : InputConvertNormal(controller) {}
InputConvertGame::InputConvertGame(Controller *controller) : InputConvertNormal(controller) {
m_ctrlSteerWheel.delayData.timer = new QTimer(this);
m_ctrlSteerWheel.delayData.timer->setSingleShot(true);
connect(m_ctrlSteerWheel.delayData.timer, &QTimer::timeout, this, &InputConvertGame::onSteerWheelTimer);
}
InputConvertGame::~InputConvertGame() {}
@ -138,8 +144,10 @@ void InputConvertGame::updateSize(const QSize &frameSize, const QSize &showSize)
{
if (showSize != m_showSize) {
if (m_gameMap && m_keyMap.isValidMouseMoveMap()) {
#ifdef QT_NO_DEBUG
// show size change, resize grab cursor
emit grabCursor(true);
#endif
}
}
m_frameSize = frameSize;
@ -237,6 +245,56 @@ int InputConvertGame::getTouchID(int key)
// -------- steer wheel event --------
void InputConvertGame::getDelayQueue(const QPointF& start, const QPointF& end,
const double& distanceStep, const double& posStepconst, const double& timerStep,
QQueue<QPointF>& queuePos, QQueue<double>& queueTimer) {
double timerBase = 5.0f; // ms
double x1 = start.x();
double y1 = start.y();
double x2 = end.x();
double y2 = end.y();
double dx=x2-x1;
double dy=y2-y1;
double e=(fabs(dx)>fabs(dy))?fabs(dx):fabs(dy);
e /= distanceStep;
dx/=e;
dy/=e;
QQueue<QPointF> queue;
QQueue<double> queue2;
for(int i=1;i<=e;i++) {
QPointF pos(x1+(QRandomGenerator::global()->bounded(posStepconst*2)-posStepconst), y1+(QRandomGenerator::global()->bounded(posStepconst*2)-posStepconst));
queue.enqueue(pos);
queue2.enqueue(QRandomGenerator::global()->bounded(timerStep*2)-timerStep + timerBase);
x1+=dx;
y1+=dy;
}
queuePos = queue;
queueTimer = queue2;
}
void InputConvertGame::onSteerWheelTimer() {
if(m_ctrlSteerWheel.delayData.queuePos.empty()) {
return;
}
int id = getTouchID(m_ctrlSteerWheel.touchKey);
m_ctrlSteerWheel.delayData.currentPos = m_ctrlSteerWheel.delayData.queuePos.dequeue();
sendTouchMoveEvent(id, m_ctrlSteerWheel.delayData.currentPos);
if(m_ctrlSteerWheel.delayData.queuePos.empty() && m_ctrlSteerWheel.delayData.pressedNum == 0) {
sendTouchUpEvent(id, m_ctrlSteerWheel.delayData.currentPos);
detachTouchID(m_ctrlSteerWheel.touchKey);
qDebug() << "***************** detach:" << id;
return;
}
if(!m_ctrlSteerWheel.delayData.queuePos.empty()) {
m_ctrlSteerWheel.delayData.timer->start(m_ctrlSteerWheel.delayData.queueTimer.dequeue());
}
}
void InputConvertGame::processSteerWheel(const KeyMap::KeyMapNode &node, const QKeyEvent *from)
{
int key = from->key();
@ -271,27 +329,46 @@ void InputConvertGame::processSteerWheel(const KeyMap::KeyMapNode &node, const Q
++pressedNum;
offset.rx() -= node.data.steerWheel.left.extendOffset;
}
m_ctrlSteerWheel.delayData.pressedNum = pressedNum;
// action
// last key release and timer no active, active timer to detouch
if (pressedNum == 0) {
// touch up release all
int id = getTouchID(m_ctrlSteerWheel.touchKey);
sendTouchUpEvent(id, node.data.steerWheel.centerPos + m_ctrlSteerWheel.lastOffset);
detachTouchID(m_ctrlSteerWheel.touchKey);
} else {
int id;
// first press, get key and touch down
if (pressedNum == 1 && flag) {
m_ctrlSteerWheel.touchKey = from->key();
id = attachTouchID(m_ctrlSteerWheel.touchKey);
sendTouchDownEvent(id, node.data.steerWheel.centerPos);
} else {
// jsut get touch id and move
id = getTouchID(m_ctrlSteerWheel.touchKey);
if (m_ctrlSteerWheel.delayData.timer->isActive()) {
m_ctrlSteerWheel.delayData.timer->stop();
m_ctrlSteerWheel.delayData.queueTimer.clear();
m_ctrlSteerWheel.delayData.queuePos.clear();
}
sendTouchMoveEvent(id, node.data.steerWheel.centerPos + offset);
m_ctrlSteerWheel.delayData.queueTimer.enqueue(0);
m_ctrlSteerWheel.delayData.queuePos.enqueue(m_ctrlSteerWheel.delayData.currentPos);
m_ctrlSteerWheel.delayData.timer->start();
return;
}
m_ctrlSteerWheel.lastOffset = offset;
// process steer wheel key event
m_ctrlSteerWheel.delayData.timer->stop();
m_ctrlSteerWheel.delayData.queueTimer.clear();
m_ctrlSteerWheel.delayData.queuePos.clear();
// first press, get key and touch down
if (pressedNum == 1 && flag) {
m_ctrlSteerWheel.touchKey = from->key();
int id = attachTouchID(m_ctrlSteerWheel.touchKey);
qDebug() << "***************** attach:" << id;
sendTouchDownEvent(id, node.data.steerWheel.centerPos);
getDelayQueue(node.data.steerWheel.centerPos, node.data.steerWheel.centerPos+offset,
0.01f, 0.002f, 3.0f,
m_ctrlSteerWheel.delayData.queuePos,
m_ctrlSteerWheel.delayData.queueTimer);
} else {
getDelayQueue(m_ctrlSteerWheel.delayData.currentPos, node.data.steerWheel.centerPos+offset,
0.01f, 0.002f, 3.0f,
m_ctrlSteerWheel.delayData.queuePos,
m_ctrlSteerWheel.delayData.queueTimer);
}
m_ctrlSteerWheel.delayData.timer->start();
return;
}
@ -509,9 +586,10 @@ bool InputConvertGame::switchGameMap()
if (!m_keyMap.isValidMouseMoveMap()) {
return m_gameMap;
}
#ifdef QT_NO_DEBUG
// grab cursor and set cursor only mouse move map
emit grabCursor(m_gameMap);
#endif
hideMouseCursor(m_gameMap);
if (!m_gameMap) {

View file

@ -2,6 +2,7 @@
#define INPUTCONVERTGAME_H
#include <QPointF>
#include <QQueue>
#include "inputconvertnormal.h"
#include "keymap.h"
@ -60,9 +61,16 @@ protected:
bool checkCursorPos(const QMouseEvent *from);
void hideMouseCursor(bool hide);
void getDelayQueue(const QPointF& start, const QPointF& end,
const double& distanceStep, const double& posStepconst, const double& timerStep,
QQueue<QPointF>& queuePos, QQueue<double>& queueTimer);
protected:
void timerEvent(QTimerEvent *event);
private slots:
void onSteerWheelTimer();
private:
QSize m_frameSize;
QSize m_showSize;
@ -82,8 +90,15 @@ private:
bool pressedDown = false;
bool pressedLeft = false;
bool pressedRight = false;
// for last up
QPointF lastOffset;
// for delay
struct {
QPointF currentPos;
QTimer* timer = nullptr;
QQueue<QPointF> queuePos;
QQueue<double> queueTimer;
int pressedNum = 0;
} delayData;
} m_ctrlSteerWheel;
// mouse move