mirror of https://github.com/mgba-emu/mgba.git
Qt: Refactor to make non-SDL gamepad input possible
This commit is contained in:
parent
6ebef8dc16
commit
711c7e9903
|
@ -96,10 +96,8 @@ GameController::GameController(QObject* parent)
|
||||||
controller->m_audioProcessor->setInput(context);
|
controller->m_audioProcessor->setInput(context);
|
||||||
context->gba->luminanceSource = &controller->m_lux;
|
context->gba->luminanceSource = &controller->m_lux;
|
||||||
context->gba->rtcSource = &controller->m_rtc;
|
context->gba->rtcSource = &controller->m_rtc;
|
||||||
#ifdef BUILD_SDL
|
|
||||||
context->gba->rumble = controller->m_inputController->rumble();
|
context->gba->rumble = controller->m_inputController->rumble();
|
||||||
context->gba->rotationSource = controller->m_inputController->rotationSource();
|
context->gba->rotationSource = controller->m_inputController->rotationSource();
|
||||||
#endif
|
|
||||||
controller->gameStarted(context);
|
controller->gameStarted(context);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -154,10 +152,7 @@ GameController::GameController(QObject* parent)
|
||||||
connect(this, SIGNAL(gameStopped(GBAThread*)), m_audioProcessor, SLOT(pause()));
|
connect(this, SIGNAL(gameStopped(GBAThread*)), m_audioProcessor, SLOT(pause()));
|
||||||
connect(this, SIGNAL(gamePaused(GBAThread*)), m_audioProcessor, SLOT(pause()));
|
connect(this, SIGNAL(gamePaused(GBAThread*)), m_audioProcessor, SLOT(pause()));
|
||||||
connect(this, SIGNAL(gameUnpaused(GBAThread*)), m_audioProcessor, SLOT(start()));
|
connect(this, SIGNAL(gameUnpaused(GBAThread*)), m_audioProcessor, SLOT(start()));
|
||||||
|
connect(this, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(pollEvents()));
|
||||||
#ifdef BUILD_SDL
|
|
||||||
connect(this, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(testSDLEvents()));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GameController::~GameController() {
|
GameController::~GameController() {
|
||||||
|
@ -283,9 +278,7 @@ void GameController::openGame() {
|
||||||
m_threadContext.patch = VFileOpen(m_patch.toLocal8Bit().constData(), O_RDONLY);
|
m_threadContext.patch = VFileOpen(m_patch.toLocal8Bit().constData(), O_RDONLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
|
||||||
m_inputController->recalibrateAxes();
|
m_inputController->recalibrateAxes();
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!GBAThreadStart(&m_threadContext)) {
|
if (!GBAThreadStart(&m_threadContext)) {
|
||||||
m_gameOpen = false;
|
m_gameOpen = false;
|
||||||
|
@ -663,9 +656,7 @@ void GameController::setFakeEpoch(const QDateTime& time) {
|
||||||
|
|
||||||
void GameController::updateKeys() {
|
void GameController::updateKeys() {
|
||||||
int activeKeys = m_activeKeys;
|
int activeKeys = m_activeKeys;
|
||||||
#ifdef BUILD_SDL
|
|
||||||
activeKeys |= m_activeButtons;
|
activeKeys |= m_activeButtons;
|
||||||
#endif
|
|
||||||
activeKeys &= ~m_inactiveKeys;
|
activeKeys &= ~m_inactiveKeys;
|
||||||
m_threadContext.activeKeys = activeKeys;
|
m_threadContext.activeKeys = activeKeys;
|
||||||
}
|
}
|
||||||
|
@ -705,13 +696,11 @@ void GameController::disableLogLevel(int levels) {
|
||||||
threadContinue();
|
threadContinue();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
void GameController::pollEvents() {
|
||||||
void GameController::testSDLEvents() {
|
|
||||||
if (!m_inputController) {
|
if (!m_inputController) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_activeButtons = m_inputController->testSDLEvents();
|
m_activeButtons = m_inputController->pollEvents();
|
||||||
updateKeys();
|
updateKeys();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -146,13 +146,7 @@ public slots:
|
||||||
private slots:
|
private slots:
|
||||||
void crashGame(const QString& crashMessage);
|
void crashGame(const QString& crashMessage);
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
void pollEvents();
|
||||||
void testSDLEvents();
|
|
||||||
|
|
||||||
private:
|
|
||||||
GBASDLEvents m_sdlEvents;
|
|
||||||
int m_activeButtons;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateKeys();
|
void updateKeys();
|
||||||
|
@ -163,6 +157,7 @@ private:
|
||||||
GBAVideoSoftwareRenderer* m_renderer;
|
GBAVideoSoftwareRenderer* m_renderer;
|
||||||
GBACheatDevice m_cheatDevice;
|
GBACheatDevice m_cheatDevice;
|
||||||
int m_activeKeys;
|
int m_activeKeys;
|
||||||
|
int m_activeButtons;
|
||||||
int m_inactiveKeys;
|
int m_inactiveKeys;
|
||||||
int m_logLevels;
|
int m_logLevels;
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ using namespace QGBA;
|
||||||
|
|
||||||
QEvent::Type GamepadAxisEvent::s_type = QEvent::None;
|
QEvent::Type GamepadAxisEvent::s_type = QEvent::None;
|
||||||
|
|
||||||
GamepadAxisEvent::GamepadAxisEvent(int axis, Direction direction, bool isNew, InputController* controller)
|
GamepadAxisEvent::GamepadAxisEvent(int axis, Direction direction, bool isNew, int type, InputController* controller)
|
||||||
: QEvent(Type())
|
: QEvent(Type())
|
||||||
, m_axis(axis)
|
, m_axis(axis)
|
||||||
, m_direction(direction)
|
, m_direction(direction)
|
||||||
|
@ -20,11 +20,9 @@ GamepadAxisEvent::GamepadAxisEvent(int axis, Direction direction, bool isNew, In
|
||||||
, m_key(GBA_KEY_NONE)
|
, m_key(GBA_KEY_NONE)
|
||||||
{
|
{
|
||||||
ignore();
|
ignore();
|
||||||
#ifdef BUILD_SDL
|
|
||||||
if (controller) {
|
if (controller) {
|
||||||
m_key = GBAInputMapAxis(controller->map(), SDL_BINDING_BUTTON, axis, direction * INT_MAX);
|
m_key = GBAInputMapAxis(controller->map(), type, axis, direction * INT_MAX);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEvent::Type GamepadAxisEvent::Type() {
|
QEvent::Type GamepadAxisEvent::Type() {
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
NEGATIVE = -1
|
NEGATIVE = -1
|
||||||
};
|
};
|
||||||
|
|
||||||
GamepadAxisEvent(int axis, Direction direction, bool isNew, InputController* controller = nullptr);
|
GamepadAxisEvent(int axis, Direction direction, bool isNew, int type, InputController* controller = nullptr);
|
||||||
|
|
||||||
int axis() const { return m_axis; }
|
int axis() const { return m_axis; }
|
||||||
Direction direction() const { return m_direction; }
|
Direction direction() const { return m_direction; }
|
||||||
|
|
|
@ -12,18 +12,16 @@ using namespace QGBA;
|
||||||
QEvent::Type GamepadButtonEvent::s_downType = QEvent::None;
|
QEvent::Type GamepadButtonEvent::s_downType = QEvent::None;
|
||||||
QEvent::Type GamepadButtonEvent::s_upType = QEvent::None;
|
QEvent::Type GamepadButtonEvent::s_upType = QEvent::None;
|
||||||
|
|
||||||
GamepadButtonEvent::GamepadButtonEvent(QEvent::Type type, int button, InputController* controller)
|
GamepadButtonEvent::GamepadButtonEvent(QEvent::Type pressType, int button, int type, InputController* controller)
|
||||||
: QEvent(type)
|
: QEvent(pressType)
|
||||||
, m_button(button)
|
, m_button(button)
|
||||||
, m_controller(controller)
|
, m_controller(controller)
|
||||||
, m_key(GBA_KEY_NONE)
|
, m_key(GBA_KEY_NONE)
|
||||||
{
|
{
|
||||||
ignore();
|
ignore();
|
||||||
#ifdef BUILD_SDL
|
|
||||||
if (controller) {
|
if (controller) {
|
||||||
m_key = GBAInputMapKey(controller->map(), SDL_BINDING_BUTTON, button);
|
m_key = GBAInputMapKey(controller->map(), type, button);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QEvent::Type GamepadButtonEvent::Down() {
|
QEvent::Type GamepadButtonEvent::Down() {
|
||||||
|
|
|
@ -18,7 +18,7 @@ class InputController;
|
||||||
|
|
||||||
class GamepadButtonEvent : public QEvent {
|
class GamepadButtonEvent : public QEvent {
|
||||||
public:
|
public:
|
||||||
GamepadButtonEvent(Type type, int button, InputController* controller = nullptr);
|
GamepadButtonEvent(Type pressType, int button, int type, InputController* controller = nullptr);
|
||||||
|
|
||||||
int value() const { return m_button; }
|
int value() const { return m_button; }
|
||||||
GBAKey gbaKey() const { return m_key; }
|
GBAKey gbaKey() const { return m_key; }
|
||||||
|
|
|
@ -43,12 +43,16 @@ InputController::InputController(int playerId, QObject* parent)
|
||||||
++s_sdlInited;
|
++s_sdlInited;
|
||||||
m_sdlPlayer.bindings = &m_inputMap;
|
m_sdlPlayer.bindings = &m_inputMap;
|
||||||
GBASDLInitBindings(&m_inputMap);
|
GBASDLInitBindings(&m_inputMap);
|
||||||
|
#endif
|
||||||
|
|
||||||
m_gamepadTimer = new QTimer(this);
|
m_gamepadTimer = new QTimer(this);
|
||||||
connect(m_gamepadTimer, SIGNAL(timeout()), this, SLOT(testGamepad()));
|
#ifdef BUILD_SDL
|
||||||
|
connect(m_gamepadTimer, &QTimer::timeout, [this]() {
|
||||||
|
testGamepad(SDL_BINDING_BUTTON);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
m_gamepadTimer->setInterval(50);
|
m_gamepadTimer->setInterval(50);
|
||||||
m_gamepadTimer->start();
|
m_gamepadTimer->start();
|
||||||
#endif
|
|
||||||
|
|
||||||
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A);
|
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_X, GBA_KEY_A);
|
||||||
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B);
|
GBAInputBindKey(&m_inputMap, KEYBOARD, Qt::Key_Z, GBA_KEY_B);
|
||||||
|
@ -103,9 +107,7 @@ void InputController::loadConfiguration(uint32_t type) {
|
||||||
|
|
||||||
void InputController::loadProfile(uint32_t type, const QString& profile) {
|
void InputController::loadProfile(uint32_t type, const QString& profile) {
|
||||||
GBAInputProfileLoad(&m_inputMap, type, m_config->input(), profile.toLocal8Bit().constData());
|
GBAInputProfileLoad(&m_inputMap, type, m_config->input(), profile.toLocal8Bit().constData());
|
||||||
#ifdef BUILD_SDL
|
|
||||||
recalibrateAxes();
|
recalibrateAxes();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::saveConfiguration() {
|
void InputController::saveConfiguration() {
|
||||||
|
@ -144,74 +146,122 @@ const char* InputController::profileForType(uint32_t type) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
|
||||||
QStringList InputController::connectedGamepads(uint32_t type) const {
|
QStringList InputController::connectedGamepads(uint32_t type) const {
|
||||||
UNUSED(type);
|
UNUSED(type);
|
||||||
if (type != SDL_BINDING_BUTTON) {
|
|
||||||
return QStringList();
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList pads;
|
#ifdef BUILD_SDL
|
||||||
for (size_t i = 0; i < s_sdlEvents.nJoysticks; ++i) {
|
if (type == SDL_BINDING_BUTTON) {
|
||||||
const char* name;
|
QStringList pads;
|
||||||
|
for (size_t i = 0; i < s_sdlEvents.nJoysticks; ++i) {
|
||||||
|
const char* name;
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
name = SDL_JoystickName(s_sdlEvents.joysticks[i]);
|
name = SDL_JoystickName(s_sdlEvents.joysticks[i]);
|
||||||
#else
|
#else
|
||||||
name = SDL_JoystickName(SDL_JoystickIndex(s_sdlEvents.joysticks[i]));
|
name = SDL_JoystickName(SDL_JoystickIndex(s_sdlEvents.joysticks[i]));
|
||||||
#endif
|
#endif
|
||||||
if (name) {
|
if (name) {
|
||||||
pads.append(QString(name));
|
pads.append(QString(name));
|
||||||
} else {
|
} else {
|
||||||
pads.append(QString());
|
pads.append(QString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return pads;
|
||||||
}
|
}
|
||||||
return pads;
|
#endif
|
||||||
|
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
|
int InputController::gamepad(uint32_t type) const {
|
||||||
|
#ifdef BUILD_SDL
|
||||||
|
if (type == SDL_BINDING_BUTTON) {
|
||||||
|
return m_sdlPlayer.joystickIndex;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InputController::setGamepad(uint32_t type, int index) {
|
||||||
|
#ifdef BUILD_SDL
|
||||||
|
if (type == SDL_BINDING_BUTTON) {
|
||||||
|
GBASDLPlayerChangeJoystick(&s_sdlEvents, &m_sdlPlayer, index);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::setPreferredGamepad(uint32_t type, const QString& device) {
|
void InputController::setPreferredGamepad(uint32_t type, const QString& device) {
|
||||||
if (!m_config) {
|
if (!m_config) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GBAInputSetPreferredDevice(m_config->input(), type, m_sdlPlayer.playerId, device.toLocal8Bit().constData());
|
GBAInputSetPreferredDevice(m_config->input(), type, m_playerId, device.toLocal8Bit().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
GBARumble* InputController::rumble() {
|
GBARumble* InputController::rumble() {
|
||||||
return &m_sdlPlayer.rumble.d;
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
return &m_sdlPlayer.rumble.d;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GBARotationSource* InputController::rotationSource() {
|
GBARotationSource* InputController::rotationSource() {
|
||||||
return &m_sdlPlayer.rotation.d;
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
return &m_sdlPlayer.rotation.d;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::registerTiltAxisX(int axis) {
|
void InputController::registerTiltAxisX(int axis) {
|
||||||
m_sdlPlayer.rotation.axisX = axis;
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
m_sdlPlayer.rotation.axisX = axis;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::registerTiltAxisY(int axis) {
|
void InputController::registerTiltAxisY(int axis) {
|
||||||
m_sdlPlayer.rotation.axisY = axis;
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
m_sdlPlayer.rotation.axisY = axis;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::registerGyroAxisX(int axis) {
|
void InputController::registerGyroAxisX(int axis) {
|
||||||
m_sdlPlayer.rotation.gyroX = axis;
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
m_sdlPlayer.rotation.gyroX = axis;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::registerGyroAxisY(int axis) {
|
void InputController::registerGyroAxisY(int axis) {
|
||||||
m_sdlPlayer.rotation.gyroY = axis;
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
m_sdlPlayer.rotation.gyroY = axis;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float InputController::gyroSensitivity() const {
|
float InputController::gyroSensitivity() const {
|
||||||
return m_sdlPlayer.rotation.gyroSensitivity;
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached) {
|
||||||
|
return m_sdlPlayer.rotation.gyroSensitivity;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::setGyroSensitivity(float sensitivity) {
|
void InputController::setGyroSensitivity(float sensitivity) {
|
||||||
m_sdlPlayer.rotation.gyroSensitivity = sensitivity;
|
#ifdef BUILD_SDL
|
||||||
}
|
if (m_playerAttached) {
|
||||||
#else
|
m_sdlPlayer.rotation.gyroSensitivity = sensitivity;
|
||||||
GBARumble* InputController::rumble() {
|
}
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GBARotationSource* InputController::rotationSource() {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
GBAKey InputController::mapKeyboard(int key) const {
|
GBAKey InputController::mapKeyboard(int key) const {
|
||||||
return GBAInputMapKey(&m_inputMap, KEYBOARD, key);
|
return GBAInputMapKey(&m_inputMap, KEYBOARD, key);
|
||||||
|
@ -221,104 +271,119 @@ void InputController::bindKey(uint32_t type, int key, GBAKey gbaKey) {
|
||||||
return GBAInputBindKey(&m_inputMap, type, key, gbaKey);
|
return GBAInputBindKey(&m_inputMap, type, key, gbaKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
int InputController::pollEvents() {
|
||||||
int InputController::testSDLEvents() {
|
|
||||||
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
|
||||||
SDL_JoystickUpdate();
|
|
||||||
int numButtons = SDL_JoystickNumButtons(joystick);
|
|
||||||
int activeButtons = 0;
|
int activeButtons = 0;
|
||||||
int i;
|
#ifdef BUILD_SDL
|
||||||
for (i = 0; i < numButtons; ++i) {
|
if (m_playerAttached) {
|
||||||
GBAKey key = GBAInputMapKey(&m_inputMap, SDL_BINDING_BUTTON, i);
|
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
||||||
if (key == GBA_KEY_NONE) {
|
SDL_JoystickUpdate();
|
||||||
continue;
|
int numButtons = SDL_JoystickNumButtons(joystick);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < numButtons; ++i) {
|
||||||
|
GBAKey key = GBAInputMapKey(&m_inputMap, SDL_BINDING_BUTTON, i);
|
||||||
|
if (key == GBA_KEY_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (hasPendingEvent(key)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (SDL_JoystickGetButton(joystick, i)) {
|
||||||
|
activeButtons |= 1 << key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (hasPendingEvent(key)) {
|
int numHats = SDL_JoystickNumHats(joystick);
|
||||||
continue;
|
for (i = 0; i < numHats; ++i) {
|
||||||
|
int hat = SDL_JoystickGetHat(joystick, i);
|
||||||
|
if (hat & SDL_HAT_UP) {
|
||||||
|
activeButtons |= 1 << GBA_KEY_UP;
|
||||||
|
}
|
||||||
|
if (hat & SDL_HAT_LEFT) {
|
||||||
|
activeButtons |= 1 << GBA_KEY_LEFT;
|
||||||
|
}
|
||||||
|
if (hat & SDL_HAT_DOWN) {
|
||||||
|
activeButtons |= 1 << GBA_KEY_DOWN;
|
||||||
|
}
|
||||||
|
if (hat & SDL_HAT_RIGHT) {
|
||||||
|
activeButtons |= 1 << GBA_KEY_RIGHT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (SDL_JoystickGetButton(joystick, i)) {
|
|
||||||
activeButtons |= 1 << key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int numHats = SDL_JoystickNumHats(joystick);
|
|
||||||
for (i = 0; i < numHats; ++i) {
|
|
||||||
int hat = SDL_JoystickGetHat(joystick, i);
|
|
||||||
if (hat & SDL_HAT_UP) {
|
|
||||||
activeButtons |= 1 << GBA_KEY_UP;
|
|
||||||
}
|
|
||||||
if (hat & SDL_HAT_LEFT) {
|
|
||||||
activeButtons |= 1 << GBA_KEY_LEFT;
|
|
||||||
}
|
|
||||||
if (hat & SDL_HAT_DOWN) {
|
|
||||||
activeButtons |= 1 << GBA_KEY_DOWN;
|
|
||||||
}
|
|
||||||
if (hat & SDL_HAT_RIGHT) {
|
|
||||||
activeButtons |= 1 << GBA_KEY_RIGHT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int numAxes = SDL_JoystickNumAxes(joystick);
|
int numAxes = SDL_JoystickNumAxes(joystick);
|
||||||
for (i = 0; i < numAxes; ++i) {
|
for (i = 0; i < numAxes; ++i) {
|
||||||
int value = SDL_JoystickGetAxis(joystick, i);
|
int value = SDL_JoystickGetAxis(joystick, i);
|
||||||
|
|
||||||
enum GBAKey key = GBAInputMapAxis(&m_inputMap, SDL_BINDING_BUTTON, i, value);
|
enum GBAKey key = GBAInputMapAxis(&m_inputMap, SDL_BINDING_BUTTON, i, value);
|
||||||
if (key != GBA_KEY_NONE) {
|
if (key != GBA_KEY_NONE) {
|
||||||
activeButtons |= 1 << key;
|
activeButtons |= 1 << key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return activeButtons;
|
return activeButtons;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<int> InputController::activeGamepadButtons() {
|
QSet<int> InputController::activeGamepadButtons(int type) {
|
||||||
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
|
||||||
SDL_JoystickUpdate();
|
|
||||||
int numButtons = SDL_JoystickNumButtons(joystick);
|
|
||||||
QSet<int> activeButtons;
|
QSet<int> activeButtons;
|
||||||
int i;
|
#ifdef BUILD_SDL
|
||||||
for (i = 0; i < numButtons; ++i) {
|
if (m_playerAttached && type == SDL_BINDING_BUTTON) {
|
||||||
if (SDL_JoystickGetButton(joystick, i)) {
|
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
||||||
activeButtons.insert(i);
|
SDL_JoystickUpdate();
|
||||||
|
int numButtons = SDL_JoystickNumButtons(joystick);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < numButtons; ++i) {
|
||||||
|
if (SDL_JoystickGetButton(joystick, i)) {
|
||||||
|
activeButtons.insert(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return activeButtons;
|
return activeButtons;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::recalibrateAxes() {
|
void InputController::recalibrateAxes() {
|
||||||
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
#ifdef BUILD_SDL
|
||||||
SDL_JoystickUpdate();
|
if (m_playerAttached) {
|
||||||
int numAxes = SDL_JoystickNumAxes(joystick);
|
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
||||||
if (numAxes < 1) {
|
SDL_JoystickUpdate();
|
||||||
return;
|
int numAxes = SDL_JoystickNumAxes(joystick);
|
||||||
}
|
if (numAxes < 1) {
|
||||||
m_deadzones.resize(numAxes);
|
return;
|
||||||
int i;
|
}
|
||||||
for (i = 0; i < numAxes; ++i) {
|
m_deadzones.resize(numAxes);
|
||||||
m_deadzones[i] = SDL_JoystickGetAxis(joystick, i);
|
int i;
|
||||||
}
|
for (i = 0; i < numAxes; ++i) {
|
||||||
}
|
m_deadzones[i] = SDL_JoystickGetAxis(joystick, i);
|
||||||
|
|
||||||
QSet<QPair<int, GamepadAxisEvent::Direction>> InputController::activeGamepadAxes() {
|
|
||||||
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
|
||||||
SDL_JoystickUpdate();
|
|
||||||
int numAxes = SDL_JoystickNumAxes(joystick);
|
|
||||||
QSet<QPair<int, GamepadAxisEvent::Direction>> activeAxes;
|
|
||||||
if (numAxes < 1) {
|
|
||||||
return activeAxes;
|
|
||||||
}
|
|
||||||
m_deadzones.resize(numAxes);
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < numAxes; ++i) {
|
|
||||||
int32_t axis = SDL_JoystickGetAxis(joystick, i);
|
|
||||||
axis -= m_deadzones[i];
|
|
||||||
if (axis >= AXIS_THRESHOLD || axis <= -AXIS_THRESHOLD) {
|
|
||||||
activeAxes.insert(qMakePair(i, axis > 0 ? GamepadAxisEvent::POSITIVE : GamepadAxisEvent::NEGATIVE));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QPair<int, GamepadAxisEvent::Direction>> InputController::activeGamepadAxes(int type) {
|
||||||
|
QSet<QPair<int, GamepadAxisEvent::Direction>> activeAxes;
|
||||||
|
#ifdef BUILD_SDL
|
||||||
|
if (m_playerAttached && type == SDL_BINDING_BUTTON) {
|
||||||
|
SDL_Joystick* joystick = m_sdlPlayer.joystick;
|
||||||
|
SDL_JoystickUpdate();
|
||||||
|
int numAxes = SDL_JoystickNumAxes(joystick);
|
||||||
|
if (numAxes < 1) {
|
||||||
|
return activeAxes;
|
||||||
|
}
|
||||||
|
m_deadzones.resize(numAxes);
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < numAxes; ++i) {
|
||||||
|
int32_t axis = SDL_JoystickGetAxis(joystick, i);
|
||||||
|
axis -= m_deadzones[i];
|
||||||
|
if (axis >= AXIS_THRESHOLD || axis <= -AXIS_THRESHOLD) {
|
||||||
|
activeAxes.insert(qMakePair(i, axis > 0 ? GamepadAxisEvent::POSITIVE : GamepadAxisEvent::NEGATIVE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return activeAxes;
|
return activeAxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction direction, GBAKey key) {
|
void InputController::bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction direction, GBAKey key) {
|
||||||
const GBAAxis* old = GBAInputQueryAxis(&m_inputMap, SDL_BINDING_BUTTON, axis);
|
const GBAAxis* old = GBAInputQueryAxis(&m_inputMap, type, axis);
|
||||||
GBAAxis description = { GBA_KEY_NONE, GBA_KEY_NONE, -AXIS_THRESHOLD, AXIS_THRESHOLD };
|
GBAAxis description = { GBA_KEY_NONE, GBA_KEY_NONE, -AXIS_THRESHOLD, AXIS_THRESHOLD };
|
||||||
if (old) {
|
if (old) {
|
||||||
description = *old;
|
description = *old;
|
||||||
|
@ -335,17 +400,15 @@ void InputController::bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direct
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GBAInputBindAxis(&m_inputMap, SDL_BINDING_BUTTON, axis, &description);
|
GBAInputBindAxis(&m_inputMap, type, axis, &description);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void InputController::testGamepad() {
|
void InputController::testGamepad(int type) {
|
||||||
#ifdef BUILD_SDL
|
auto activeAxes = activeGamepadAxes(type);
|
||||||
auto activeAxes = activeGamepadAxes();
|
|
||||||
auto oldAxes = m_activeAxes;
|
auto oldAxes = m_activeAxes;
|
||||||
m_activeAxes = activeAxes;
|
m_activeAxes = activeAxes;
|
||||||
|
|
||||||
auto activeButtons = activeGamepadButtons();
|
auto activeButtons = activeGamepadButtons(type);
|
||||||
auto oldButtons = m_activeButtons;
|
auto oldButtons = m_activeButtons;
|
||||||
m_activeButtons = activeButtons;
|
m_activeButtons = activeButtons;
|
||||||
|
|
||||||
|
@ -359,7 +422,7 @@ void InputController::testGamepad() {
|
||||||
for (auto& axis : m_activeAxes) {
|
for (auto& axis : m_activeAxes) {
|
||||||
bool newlyAboveThreshold = activeAxes.contains(axis);
|
bool newlyAboveThreshold = activeAxes.contains(axis);
|
||||||
if (newlyAboveThreshold) {
|
if (newlyAboveThreshold) {
|
||||||
GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, newlyAboveThreshold, this);
|
GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, newlyAboveThreshold, type, this);
|
||||||
postPendingEvent(event->gbaKey());
|
postPendingEvent(event->gbaKey());
|
||||||
QApplication::sendEvent(QApplication::focusWidget(), event);
|
QApplication::sendEvent(QApplication::focusWidget(), event);
|
||||||
if (!event->isAccepted()) {
|
if (!event->isAccepted()) {
|
||||||
|
@ -368,7 +431,7 @@ void InputController::testGamepad() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto axis : oldAxes) {
|
for (auto axis : oldAxes) {
|
||||||
GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, false, this);
|
GamepadAxisEvent* event = new GamepadAxisEvent(axis.first, axis.second, false, type, this);
|
||||||
clearPendingEvent(event->gbaKey());
|
clearPendingEvent(event->gbaKey());
|
||||||
QApplication::sendEvent(QApplication::focusWidget(), event);
|
QApplication::sendEvent(QApplication::focusWidget(), event);
|
||||||
}
|
}
|
||||||
|
@ -381,7 +444,7 @@ void InputController::testGamepad() {
|
||||||
oldButtons.subtract(m_activeButtons);
|
oldButtons.subtract(m_activeButtons);
|
||||||
|
|
||||||
for (int button : activeButtons) {
|
for (int button : activeButtons) {
|
||||||
GamepadButtonEvent* event = new GamepadButtonEvent(GamepadButtonEvent::Down(), button, this);
|
GamepadButtonEvent* event = new GamepadButtonEvent(GamepadButtonEvent::Down(), button, type, this);
|
||||||
postPendingEvent(event->gbaKey());
|
postPendingEvent(event->gbaKey());
|
||||||
QApplication::sendEvent(QApplication::focusWidget(), event);
|
QApplication::sendEvent(QApplication::focusWidget(), event);
|
||||||
if (!event->isAccepted()) {
|
if (!event->isAccepted()) {
|
||||||
|
@ -389,11 +452,10 @@ void InputController::testGamepad() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int button : oldButtons) {
|
for (int button : oldButtons) {
|
||||||
GamepadButtonEvent* event = new GamepadButtonEvent(GamepadButtonEvent::Up(), button, this);
|
GamepadButtonEvent* event = new GamepadButtonEvent(GamepadButtonEvent::Up(), button, type, this);
|
||||||
clearPendingEvent(event->gbaKey());
|
clearPendingEvent(event->gbaKey());
|
||||||
QApplication::sendEvent(QApplication::focusWidget(), event);
|
QApplication::sendEvent(QApplication::focusWidget(), event);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputController::postPendingEvent(GBAKey key) {
|
void InputController::postPendingEvent(GBAKey key) {
|
||||||
|
|
|
@ -52,19 +52,18 @@ public:
|
||||||
|
|
||||||
const GBAInputMap* map() const { return &m_inputMap; }
|
const GBAInputMap* map() const { return &m_inputMap; }
|
||||||
|
|
||||||
#ifdef BUILD_SDL
|
int pollEvents();
|
||||||
static const int32_t AXIS_THRESHOLD = 0x3000;
|
|
||||||
|
|
||||||
int testSDLEvents();
|
static const int32_t AXIS_THRESHOLD = 0x3000;
|
||||||
QSet<int> activeGamepadButtons();
|
QSet<int> activeGamepadButtons(int type);
|
||||||
QSet<QPair<int, GamepadAxisEvent::Direction>> activeGamepadAxes();
|
QSet<QPair<int, GamepadAxisEvent::Direction>> activeGamepadAxes(int type);
|
||||||
void recalibrateAxes();
|
void recalibrateAxes();
|
||||||
|
|
||||||
void bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, GBAKey);
|
void bindAxis(uint32_t type, int axis, GamepadAxisEvent::Direction, GBAKey);
|
||||||
|
|
||||||
QStringList connectedGamepads(uint32_t type) const;
|
QStringList connectedGamepads(uint32_t type) const;
|
||||||
int gamepad(uint32_t type) const { return m_sdlPlayer.joystickIndex; }
|
int gamepad(uint32_t type) const;
|
||||||
void setGamepad(uint32_t type, int index) { GBASDLPlayerChangeJoystick(&s_sdlEvents, &m_sdlPlayer, index); }
|
void setGamepad(uint32_t type, int index);
|
||||||
void setPreferredGamepad(uint32_t type, const QString& device);
|
void setPreferredGamepad(uint32_t type, const QString& device);
|
||||||
|
|
||||||
void registerTiltAxisX(int axis);
|
void registerTiltAxisX(int axis);
|
||||||
|
@ -74,13 +73,12 @@ public:
|
||||||
|
|
||||||
float gyroSensitivity() const;
|
float gyroSensitivity() const;
|
||||||
void setGyroSensitivity(float sensitivity);
|
void setGyroSensitivity(float sensitivity);
|
||||||
#endif
|
|
||||||
|
|
||||||
GBARumble* rumble();
|
GBARumble* rumble();
|
||||||
GBARotationSource* rotationSource();
|
GBARotationSource* rotationSource();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void testGamepad();
|
void testGamepad(int type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void postPendingEvent(GBAKey);
|
void postPendingEvent(GBAKey);
|
||||||
|
@ -97,9 +95,10 @@ private:
|
||||||
static GBASDLEvents s_sdlEvents;
|
static GBASDLEvents s_sdlEvents;
|
||||||
GBASDLPlayer m_sdlPlayer;
|
GBASDLPlayer m_sdlPlayer;
|
||||||
bool m_playerAttached;
|
bool m_playerAttached;
|
||||||
QVector<int> m_deadzones;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QVector<int> m_deadzones;
|
||||||
|
|
||||||
QSet<int> m_activeButtons;
|
QSet<int> m_activeButtons;
|
||||||
QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
|
QSet<QPair<int, GamepadAxisEvent::Direction>> m_activeAxes;
|
||||||
QTimer* m_gamepadTimer;
|
QTimer* m_gamepadTimer;
|
||||||
|
|
Loading…
Reference in New Issue