From 0dd7cfd44aa8f71983d1870c738df7aeba328b28 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Thu, 26 Jan 2023 04:06:57 -0800 Subject: [PATCH] Qt: Hook up gamepad to scripting --- src/platform/qt/InputController.cpp | 3 +- src/platform/qt/InputController.h | 3 + src/platform/qt/Window.cpp | 1 + .../qt/scripting/ScriptingController.cpp | 68 +++++++++++++++++++ .../qt/scripting/ScriptingController.h | 12 ++++ 5 files changed, 86 insertions(+), 1 deletion(-) diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index f036d6f52..d8b5dd783 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -44,7 +44,7 @@ InputController::InputController(int playerId, QWidget* topLevel, QObject* paren } }); - m_gamepadTimer.setInterval(50); + m_gamepadTimer.setInterval(15); m_gamepadTimer.start(); #ifdef BUILD_QT_MULTIMEDIA @@ -336,6 +336,7 @@ void InputController::update() { loadProfile(driver->type(), newProfile); } } + emit updated(); } int InputController::pollEvents() { diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index d74cd3148..12f4e8915 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -56,6 +56,8 @@ public: void addInputDriver(std::shared_ptr); + int playerId() const { return m_playerId; } + void setConfiguration(ConfigController* config); void saveConfiguration(); bool loadConfiguration(uint32_t type); @@ -103,6 +105,7 @@ public: GBALuminanceSource* luminance() { return &m_lux; } signals: + void updated(); void profileLoaded(const QString& profile); void luminanceValueChanged(int value); diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index ae80b8454..6626d7204 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -627,6 +627,7 @@ void Window::consoleOpen() { void Window::scriptingOpen() { if (!m_scripting) { m_scripting = std::make_unique(); + m_scripting->setInputController(&m_inputController); m_shortcutController->setScriptingController(m_scripting.get()); if (m_controller) { m_scripting->setController(m_controller); diff --git a/src/platform/qt/scripting/ScriptingController.cpp b/src/platform/qt/scripting/ScriptingController.cpp index b6932d602..47cd08674 100644 --- a/src/platform/qt/scripting/ScriptingController.cpp +++ b/src/platform/qt/scripting/ScriptingController.cpp @@ -12,8 +12,10 @@ #include "CoreController.h" #include "Display.h" +#include "input/Gamepad.h" #include "input/GamepadButtonEvent.h" #include "input/GamepadHatEvent.h" +#include "InputController.h" #include "scripting/ScriptingTextBuffer.h" #include "scripting/ScriptingTextBufferModel.h" @@ -48,12 +50,15 @@ ScriptingController::ScriptingController(QObject* parent) m_bufferModel = new ScriptingTextBufferModel(this); QObject::connect(m_bufferModel, &ScriptingTextBufferModel::textBufferCreated, this, &ScriptingController::textBufferCreated); + mScriptGamepadInit(&m_gamepad); + init(); } ScriptingController::~ScriptingController() { clearController(); mScriptContextDeinit(&m_scriptContext); + mScriptGamepadDeinit(&m_gamepad); } void ScriptingController::setController(std::shared_ptr controller) { @@ -70,6 +75,14 @@ void ScriptingController::setController(std::shared_ptr controll connect(m_controller.get(), &CoreController::stopping, this, &ScriptingController::clearController); } +void ScriptingController::setInputController(InputController* input) { + if (m_inputController) { + m_inputController->disconnect(this); + } + m_inputController = input; + connect(m_inputController, &InputController::updated, this, &ScriptingController::updateGamepad); +} + bool ScriptingController::loadFile(const QString& path) { VFileDevice vf(path, QIODevice::ReadOnly); if (!vf.isOpen()) { @@ -204,6 +217,7 @@ void ScriptingController::event(QObject* obj, QEvent* event) { } if (type == GamepadHatEvent::Type()) { struct mScriptGamepadHatEvent ev{mSCRIPT_EV_TYPE_GAMEPAD_HAT}; + updateGamepad(); auto gamepadEvent = static_cast(event); ev.pad = 0; ev.hat = gamepadEvent->hatId(); @@ -212,6 +226,60 @@ void ScriptingController::event(QObject* obj, QEvent* event) { } } +void ScriptingController::updateGamepad() { + InputDriver* driver = m_inputController->gamepadDriver(); + if (!driver) { + detachGamepad(); + return; + } + Gamepad* gamepad = driver->activeGamepad(); + if (!gamepad) { + detachGamepad(); + return; + } + attachGamepad(); + + QList buttons = gamepad->currentButtons(); + int nButtons = gamepad->buttonCount(); + mScriptGamepadSetButtonCount(&m_gamepad, nButtons); + for (int i = 0; i < nButtons; ++i) { + mScriptGamepadSetButton(&m_gamepad, i, buttons.at(i)); + } + + QList axes = gamepad->currentAxes(); + int nAxes = gamepad->axisCount(); + mScriptGamepadSetAxisCount(&m_gamepad, nAxes); + for (int i = 0; i < nAxes; ++i) { + mScriptGamepadSetAxis(&m_gamepad, i, axes.at(i)); + } + + QList hats = gamepad->currentHats(); + int nHats = gamepad->hatCount(); + mScriptGamepadSetHatCount(&m_gamepad, nHats); + for (int i = 0; i < nHats; ++i) { + mScriptGamepadSetHat(&m_gamepad, i, hats.at(i)); + } +} + +void ScriptingController::attachGamepad() { + mScriptGamepad* pad = mScriptContextGamepadLookup(&m_scriptContext, 0); + if (pad == &m_gamepad) { + return; + } + if (pad) { + mScriptContextGamepadDetach(&m_scriptContext, 0); + } + mScriptContextGamepadAttach(&m_scriptContext, &m_gamepad); +} + +void ScriptingController::detachGamepad() { + mScriptGamepad* pad = mScriptContextGamepadLookup(&m_scriptContext, 0); + if (pad != &m_gamepad) { + return; + } + mScriptContextGamepadDetach(&m_scriptContext, 0); +} + void ScriptingController::init() { mScriptContextInit(&m_scriptContext); mScriptContextAttachStdlib(&m_scriptContext); diff --git a/src/platform/qt/scripting/ScriptingController.h b/src/platform/qt/scripting/ScriptingController.h index d0fb73fbc..0e275561d 100644 --- a/src/platform/qt/scripting/ScriptingController.h +++ b/src/platform/qt/scripting/ScriptingController.h @@ -9,6 +9,7 @@ #include #include +#include #include #include "VFileDevice.h" @@ -21,6 +22,7 @@ class QTextDocument; namespace QGBA { class CoreController; +class InputController; class ScriptingTextBuffer; class ScriptingTextBufferModel; @@ -32,6 +34,7 @@ public: ~ScriptingController(); void setController(std::shared_ptr controller); + void setInputController(InputController* controller); bool loadFile(const QString& path); bool load(VFileDevice& vf, const QString& name); @@ -55,9 +58,15 @@ public slots: protected: bool eventFilter(QObject*, QEvent*) override; +private slots: + void updateGamepad(); + private: void init(); + void attachGamepad(); + void detachGamepad(); + static uint32_t qtToScriptingKey(const QKeyEvent*); static uint16_t qtToScriptingModifiers(Qt::KeyboardModifiers); @@ -71,7 +80,10 @@ private: QHash m_engines; ScriptingTextBufferModel* m_bufferModel; + mScriptGamepad m_gamepad; + std::shared_ptr m_controller; + InputController* m_inputController = nullptr; }; }