Qt: Hook up gamepad to scripting

This commit is contained in:
Vicki Pfau 2023-01-26 04:06:57 -08:00
parent dfe2f62f16
commit 0dd7cfd44a
5 changed files with 86 additions and 1 deletions

View File

@ -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() {

View File

@ -56,6 +56,8 @@ public:
void addInputDriver(std::shared_ptr<InputDriver>);
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);

View File

@ -627,6 +627,7 @@ void Window::consoleOpen() {
void Window::scriptingOpen() {
if (!m_scripting) {
m_scripting = std::make_unique<ScriptingController>();
m_scripting->setInputController(&m_inputController);
m_shortcutController->setScriptingController(m_scripting.get());
if (m_controller) {
m_scripting->setController(m_controller);

View File

@ -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<CoreController> controller) {
@ -70,6 +75,14 @@ void ScriptingController::setController(std::shared_ptr<CoreController> 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<GamepadHatEvent*>(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<bool> 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<int16_t> 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<GamepadHatEvent::Direction> 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);

View File

@ -9,6 +9,7 @@
#include <QObject>
#include <mgba/script/context.h>
#include <mgba/script/input.h>
#include <mgba/core/scripting.h>
#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<CoreController> 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<QString, mScriptEngineContext*> m_engines;
ScriptingTextBufferModel* m_bufferModel;
mScriptGamepad m_gamepad;
std::shared_ptr<CoreController> m_controller;
InputController* m_inputController = nullptr;
};
}