mirror of
https://invent.kde.org/marcoa/a-la-karte.git
synced 2026-02-09 21:13:08 +00:00
233 lines
5.3 KiB
C++
233 lines
5.3 KiB
C++
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||
|
|
// SPDX-FileCopyrightText: 2024 A-La-Karte Contributors
|
||
|
|
|
||
|
|
#include "gamepadmanager.h"
|
||
|
|
|
||
|
|
#if defined(ALAKARTE_HAVE_QT_GAMEPAD)
|
||
|
|
|
||
|
|
#include <QGamepad>
|
||
|
|
#include <QGamepadManager>
|
||
|
|
|
||
|
|
GamepadManager *GamepadManager::s_instance = nullptr;
|
||
|
|
|
||
|
|
GamepadManager::GamepadManager(QObject *parent)
|
||
|
|
: QObject(parent)
|
||
|
|
{
|
||
|
|
auto *manager = QGamepadManager::instance();
|
||
|
|
|
||
|
|
connect(manager, &QGamepadManager::gamepadConnected, this, &GamepadManager::onGamepadConnected);
|
||
|
|
connect(manager, &QGamepadManager::gamepadDisconnected, this, &GamepadManager::onGamepadDisconnected);
|
||
|
|
|
||
|
|
m_repeatTimer.setInterval(150);
|
||
|
|
connect(&m_repeatTimer, &QTimer::timeout, this, &GamepadManager::processInput);
|
||
|
|
|
||
|
|
const auto gamepads = manager->connectedGamepads();
|
||
|
|
if (!gamepads.isEmpty()) {
|
||
|
|
setupGamepad(gamepads.first());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
GamepadManager *GamepadManager::instance()
|
||
|
|
{
|
||
|
|
if (!s_instance) {
|
||
|
|
s_instance = new GamepadManager();
|
||
|
|
}
|
||
|
|
return s_instance;
|
||
|
|
}
|
||
|
|
|
||
|
|
GamepadManager *GamepadManager::create(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||
|
|
{
|
||
|
|
Q_UNUSED(engine)
|
||
|
|
Q_UNUSED(scriptEngine)
|
||
|
|
return instance();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool GamepadManager::connected() const
|
||
|
|
{
|
||
|
|
return m_connected;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool GamepadManager::active() const
|
||
|
|
{
|
||
|
|
return m_active;
|
||
|
|
}
|
||
|
|
|
||
|
|
void GamepadManager::setActive(bool active)
|
||
|
|
{
|
||
|
|
if (m_active != active) {
|
||
|
|
m_active = active;
|
||
|
|
Q_EMIT activeChanged();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void GamepadManager::onGamepadConnected(int deviceId)
|
||
|
|
{
|
||
|
|
if (!m_gamepad) {
|
||
|
|
setupGamepad(deviceId);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void GamepadManager::onGamepadDisconnected(int deviceId)
|
||
|
|
{
|
||
|
|
if (m_gamepad && m_gamepad->deviceId() == deviceId) {
|
||
|
|
m_gamepad->deleteLater();
|
||
|
|
m_gamepad = nullptr;
|
||
|
|
m_connected = false;
|
||
|
|
m_repeatTimer.stop();
|
||
|
|
Q_EMIT connectedChanged();
|
||
|
|
|
||
|
|
const auto gamepads = QGamepadManager::instance()->connectedGamepads();
|
||
|
|
if (!gamepads.isEmpty()) {
|
||
|
|
setupGamepad(gamepads.first());
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
void GamepadManager::setupGamepad(int deviceId)
|
||
|
|
{
|
||
|
|
m_gamepad = new QGamepad(deviceId, this);
|
||
|
|
m_connected = true;
|
||
|
|
Q_EMIT connectedChanged();
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::axisLeftYChanged, this, [this](double value) {
|
||
|
|
if (qAbs(value) > 0.5) {
|
||
|
|
setActive(true);
|
||
|
|
if (value < -0.5) {
|
||
|
|
Q_EMIT navigateUp();
|
||
|
|
} else {
|
||
|
|
Q_EMIT navigateDown();
|
||
|
|
}
|
||
|
|
m_repeatTimer.start();
|
||
|
|
} else {
|
||
|
|
m_repeatTimer.stop();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::axisLeftXChanged, this, [this](double value) {
|
||
|
|
if (qAbs(value) > 0.5) {
|
||
|
|
setActive(true);
|
||
|
|
if (value < -0.5) {
|
||
|
|
Q_EMIT navigateLeft();
|
||
|
|
} else {
|
||
|
|
Q_EMIT navigateRight();
|
||
|
|
}
|
||
|
|
m_repeatTimer.start();
|
||
|
|
} else {
|
||
|
|
m_repeatTimer.stop();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonAChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT selectPressed();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonBChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT backPressed();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonStartChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT menuPressed();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonYChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT searchPressed();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonUpChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT navigateUp();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonDownChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT navigateDown();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonLeftChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT navigateLeft();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
connect(m_gamepad, &QGamepad::buttonRightChanged, this, [this](bool pressed) {
|
||
|
|
if (pressed) {
|
||
|
|
setActive(true);
|
||
|
|
Q_EMIT navigateRight();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
void GamepadManager::processInput()
|
||
|
|
{
|
||
|
|
if (!m_gamepad)
|
||
|
|
return;
|
||
|
|
|
||
|
|
double y = m_gamepad->axisLeftY();
|
||
|
|
double x = m_gamepad->axisLeftX();
|
||
|
|
|
||
|
|
if (y < -0.5) {
|
||
|
|
Q_EMIT navigateUp();
|
||
|
|
} else if (y > 0.5) {
|
||
|
|
Q_EMIT navigateDown();
|
||
|
|
}
|
||
|
|
|
||
|
|
if (x < -0.5) {
|
||
|
|
Q_EMIT navigateLeft();
|
||
|
|
} else if (x > 0.5) {
|
||
|
|
Q_EMIT navigateRight();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
#else
|
||
|
|
|
||
|
|
GamepadManager *GamepadManager::s_instance = nullptr;
|
||
|
|
|
||
|
|
GamepadManager::GamepadManager(QObject *parent)
|
||
|
|
: QObject(parent)
|
||
|
|
{
|
||
|
|
}
|
||
|
|
|
||
|
|
GamepadManager *GamepadManager::instance()
|
||
|
|
{
|
||
|
|
if (!s_instance) {
|
||
|
|
s_instance = new GamepadManager();
|
||
|
|
}
|
||
|
|
return s_instance;
|
||
|
|
}
|
||
|
|
|
||
|
|
GamepadManager *GamepadManager::create(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||
|
|
{
|
||
|
|
Q_UNUSED(engine)
|
||
|
|
Q_UNUSED(scriptEngine)
|
||
|
|
return instance();
|
||
|
|
}
|
||
|
|
|
||
|
|
bool GamepadManager::connected() const
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
bool GamepadManager::active() const
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
#endif
|