Qt: Switch SDL controller usage from Joystick to GameController

This commit is contained in:
Vicki Pfau 2024-04-03 04:41:54 -07:00
parent 68d120ec55
commit 9320588e45
10 changed files with 307 additions and 6 deletions

View File

@ -39,7 +39,7 @@ if(NOT MSVC)
# TODO: Remove this once mScript KV pairs support const correctness
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=incompatible-pointer-types")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -Woverloaded-virtual")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} -Woverloaded-virtual -Werror=reorder")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267 /Zc:preprocessor-")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146 /wd4267 /Zc:preprocessor-")

View File

@ -122,6 +122,7 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, const QString&
connect(key, &KeyEditor::valueChanged, this, &GBAKeyEditor::setNext);
connect(key, &KeyEditor::axisChanged, this, &GBAKeyEditor::setNext);
connect(key, &KeyEditor::hatChanged, this, &GBAKeyEditor::setNext);
key->setInputController(m_controller);
key->installEventFilter(this);
}

View File

@ -5,6 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "KeyEditor.h"
#include "InputController.h"
#include "input/Gamepad.h"
#include "input/GamepadAxisEvent.h"
#include "input/GamepadButtonEvent.h"
#include "ShortcutController.h"
@ -18,6 +20,7 @@ using namespace QGBA;
KeyEditor::KeyEditor(QWidget* parent)
: QLineEdit(parent)
, m_controller(nullptr)
, m_direction(GamepadAxisEvent::NEUTRAL)
, m_hatDirection(GamepadHatEvent::CENTER)
{
@ -26,6 +29,13 @@ KeyEditor::KeyEditor(QWidget* parent)
m_lastKey.setSingleShot(true);
}
void KeyEditor::setInputController(InputController* controller) {
m_controller = controller;
if (m_button) {
updateButtonText();
}
}
void KeyEditor::setValue(int key) {
m_key = key;
if (m_button) {
@ -204,10 +214,28 @@ void KeyEditor::updateButtonText() {
}
}
if (m_key >= 0) {
text.append(QString::number(m_key));
std::shared_ptr<Gamepad> gamepad;
if (m_controller && m_controller->gamepadDriver()) {
gamepad = m_controller->gamepadDriver()->activeGamepad();
}
if (!gamepad) {
text.append(QString::number(m_key));
} else {
text.append(gamepad->buttonHumanName(m_key));
}
}
if (m_direction != GamepadAxisEvent::NEUTRAL) {
text.append((m_direction == GamepadAxisEvent::NEGATIVE ? "-" : "+") + QString::number(m_axis));
QString name;
std::shared_ptr<Gamepad> gamepad;
if (m_controller && m_controller->gamepadDriver()) {
gamepad = m_controller->gamepadDriver()->activeGamepad();
}
if (!gamepad) {
name = QString::number(m_axis);
} else {
name = gamepad->axisHumanName(m_axis);
}
text.append((m_direction == GamepadAxisEvent::NEGATIVE ? "-" : "+") + name);
}
if (text.isEmpty()) {
setText(tr("---"));

View File

@ -13,12 +13,16 @@
namespace QGBA {
class InputController;
class KeyEditor : public QLineEdit {
Q_OBJECT
public:
KeyEditor(QWidget* parent = nullptr);
void setInputController(InputController* controller);
int value() const { return m_key; }
GamepadAxisEvent::Direction direction() const { return m_direction; }
@ -57,6 +61,7 @@ private:
int m_axis = -1;
int m_hat = -1;
bool m_button = false;
InputController* m_controller;
GamepadAxisEvent::Direction m_direction;
GamepadHatEvent::Direction m_hatDirection;
QTimer m_lastKey;

View File

@ -54,6 +54,7 @@ void ShortcutView::setInputController(InputController* controller) {
}
m_input = controller;
m_input->stealFocus(this);
m_ui.keyEdit->setInputController(controller);
}
void ShortcutView::load(const QModelIndex& index) {

View File

@ -22,6 +22,9 @@ public:
virtual QList<int16_t> currentAxes() = 0;
virtual QList<GamepadHatEvent::Direction> currentHats() = 0;
virtual QString buttonHumanName(int) const = 0;
virtual QString axisHumanName(int) const = 0;
virtual int buttonCount() const = 0;
virtual int axisCount() const = 0;
virtual int hatCount() const = 0;

View File

@ -257,13 +257,20 @@ QList<bool> SDLGamepad::currentButtons() {
return {};
}
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
QList<bool> buttons;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller;
for (int i = 0; i < SDL_CONTROLLER_BUTTON_MAX; ++i) {
buttons.append(SDL_GameControllerGetButton(controller, static_cast<SDL_GameControllerButton>(i)));
}
#else
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
int numButtons = SDL_JoystickNumButtons(joystick);
for (int i = 0; i < numButtons; ++i) {
buttons.append(SDL_JoystickGetButton(joystick, i));
}
#endif
return buttons;
}
@ -273,13 +280,20 @@ QList<int16_t> SDLGamepad::currentAxes() {
return {};
}
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
QList<int16_t> axes;
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller;
for (int i = 0; i < SDL_CONTROLLER_AXIS_MAX; ++i) {
axes.append(SDL_GameControllerGetAxis(controller, static_cast<SDL_GameControllerAxis>(i)));
}
#else
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
int numAxes = SDL_JoystickNumAxes(joystick);
for (int i = 0; i < numAxes; ++i) {
axes.append(SDL_JoystickGetAxis(joystick, i));
}
#endif
return axes;
}
@ -289,24 +303,52 @@ QList<GamepadHatEvent::Direction> SDLGamepad::currentHats() {
return {};
}
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
QList<GamepadHatEvent::Direction> hats;
#if !SDL_VERSION_ATLEAST(2, 0, 0)
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
int numHats = SDL_JoystickNumHats(joystick);
for (int i = 0; i < numHats; ++i) {
hats.append(static_cast<GamepadHatEvent::Direction>(SDL_JoystickGetHat(joystick, i)));
}
#endif
return hats;
}
QString SDLGamepad::buttonHumanName(int button) const {
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller;
const char* name = mSDLButtonName(controller, static_cast<SDL_GameControllerButton>(button));
if (name) {
return QString::fromUtf8(name);
}
#endif
return QString::number(button);
}
QString SDLGamepad::axisHumanName(int axis) const {
#if SDL_VERSION_ATLEAST(2, 0, 0)
SDL_GameController* controller = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->controller;
const char* name = mSDLAxisName(controller, static_cast<SDL_GameControllerAxis>(axis));
if (name) {
return QString::fromUtf8(name);
}
#endif
return QString::number(axis);
}
int SDLGamepad::buttonCount() const {
if (!verify()) {
return -1;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
return SDL_CONTROLLER_BUTTON_MAX;
#else
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
return SDL_JoystickNumButtons(joystick);
#endif
}
int SDLGamepad::axisCount() const {
@ -314,8 +356,12 @@ int SDLGamepad::axisCount() const {
return -1;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
return SDL_CONTROLLER_AXIS_MAX;
#else
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
return SDL_JoystickNumAxes(joystick);
#endif
}
int SDLGamepad::hatCount() const {
@ -323,8 +369,12 @@ int SDLGamepad::hatCount() const {
return -1;
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
return 0;
#else
SDL_Joystick* joystick = SDL_JoystickListGetPointer(&s_sdlEvents.joysticks, m_index)->joystick;
return SDL_JoystickNumHats(joystick);
#endif
}
QString SDLGamepad::name() const {

View File

@ -93,6 +93,9 @@ public:
int axisCount() const override;
int hatCount() const override;
QString buttonHumanName(int) const override;
QString axisHumanName(int) const override;
QString name() const override;
QString visibleName() const override;

View File

@ -886,4 +886,211 @@ void mSDLSetScreensaverSuspendable(struct mSDLEvents* events, bool suspendable)
SDL_EnableScreenSaver();
}
}
static const char* const buttonNamesXbox360[SDL_CONTROLLER_BUTTON_MAX] = {
[SDL_CONTROLLER_BUTTON_A] = "A",
[SDL_CONTROLLER_BUTTON_B] = "B",
[SDL_CONTROLLER_BUTTON_X] = "X",
[SDL_CONTROLLER_BUTTON_Y] = "Y",
[SDL_CONTROLLER_BUTTON_BACK] = "Back",
[SDL_CONTROLLER_BUTTON_GUIDE] = "Xbox",
[SDL_CONTROLLER_BUTTON_START] = "Start",
[SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS",
[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS",
[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB",
[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB",
[SDL_CONTROLLER_BUTTON_MISC1] = "Misc",
[SDL_CONTROLLER_BUTTON_PADDLE1] = "P1",
[SDL_CONTROLLER_BUTTON_PADDLE2] = "P2",
[SDL_CONTROLLER_BUTTON_PADDLE3] = "P3",
[SDL_CONTROLLER_BUTTON_PADDLE4] = "P4",
[SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch",
};
#if SDL_VERSION_ATLEAST(2, 0, 12)
static const char* const buttonNamesXboxOne[SDL_CONTROLLER_BUTTON_MAX] = {
[SDL_CONTROLLER_BUTTON_A] = "A",
[SDL_CONTROLLER_BUTTON_B] = "B",
[SDL_CONTROLLER_BUTTON_X] = "X",
[SDL_CONTROLLER_BUTTON_Y] = "Y",
[SDL_CONTROLLER_BUTTON_BACK] = "View",
[SDL_CONTROLLER_BUTTON_GUIDE] = "Xbox",
[SDL_CONTROLLER_BUTTON_START] = "Menu",
[SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS",
[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS",
[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB",
[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB",
[SDL_CONTROLLER_BUTTON_MISC1] = "Share",
[SDL_CONTROLLER_BUTTON_PADDLE1] = "P1",
[SDL_CONTROLLER_BUTTON_PADDLE2] = "P2",
[SDL_CONTROLLER_BUTTON_PADDLE3] = "P3",
[SDL_CONTROLLER_BUTTON_PADDLE4] = "P4",
[SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch",
};
static const char* const buttonNamesPlayStation[SDL_CONTROLLER_BUTTON_MAX] = {
[SDL_CONTROLLER_BUTTON_A] = "×",
[SDL_CONTROLLER_BUTTON_B] = "",
[SDL_CONTROLLER_BUTTON_X] = "",
[SDL_CONTROLLER_BUTTON_Y] = "",
[SDL_CONTROLLER_BUTTON_BACK] = "Share",
[SDL_CONTROLLER_BUTTON_GUIDE] = "PS",
[SDL_CONTROLLER_BUTTON_START] = "Options",
[SDL_CONTROLLER_BUTTON_LEFTSTICK] = "L3",
[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "R3",
[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L1",
[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R1",
[SDL_CONTROLLER_BUTTON_MISC1] = "Misc",
[SDL_CONTROLLER_BUTTON_PADDLE1] = "P1",
[SDL_CONTROLLER_BUTTON_PADDLE2] = "P2",
[SDL_CONTROLLER_BUTTON_PADDLE3] = "P3",
[SDL_CONTROLLER_BUTTON_PADDLE4] = "P4",
[SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch",
};
static const char* const buttonNamesNintedo[SDL_CONTROLLER_BUTTON_MAX] = {
[SDL_CONTROLLER_BUTTON_A] = "A",
[SDL_CONTROLLER_BUTTON_B] = "B",
[SDL_CONTROLLER_BUTTON_X] = "X",
[SDL_CONTROLLER_BUTTON_Y] = "Y",
[SDL_CONTROLLER_BUTTON_BACK] = "-",
[SDL_CONTROLLER_BUTTON_GUIDE] = "Home",
[SDL_CONTROLLER_BUTTON_START] = "+",
[SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS",
[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS",
[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "L",
[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "R",
[SDL_CONTROLLER_BUTTON_MISC1] = "Share",
[SDL_CONTROLLER_BUTTON_PADDLE1] = "P1",
[SDL_CONTROLLER_BUTTON_PADDLE2] = "P2",
[SDL_CONTROLLER_BUTTON_PADDLE3] = "P3",
[SDL_CONTROLLER_BUTTON_PADDLE4] = "P4",
[SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch",
};
static const char* const buttonNamesGeneric[SDL_CONTROLLER_BUTTON_MAX] = {
[SDL_CONTROLLER_BUTTON_A] = "A",
[SDL_CONTROLLER_BUTTON_B] = "B",
[SDL_CONTROLLER_BUTTON_X] = "X",
[SDL_CONTROLLER_BUTTON_Y] = "Y",
[SDL_CONTROLLER_BUTTON_BACK] = "Select",
[SDL_CONTROLLER_BUTTON_GUIDE] = "Guide",
[SDL_CONTROLLER_BUTTON_START] = "Start",
[SDL_CONTROLLER_BUTTON_LEFTSTICK] = "LS",
[SDL_CONTROLLER_BUTTON_RIGHTSTICK] = "RS",
[SDL_CONTROLLER_BUTTON_LEFTSHOULDER] = "LB",
[SDL_CONTROLLER_BUTTON_RIGHTSHOULDER] = "RB",
[SDL_CONTROLLER_BUTTON_MISC1] = "Misc",
[SDL_CONTROLLER_BUTTON_PADDLE1] = "P1",
[SDL_CONTROLLER_BUTTON_PADDLE2] = "P2",
[SDL_CONTROLLER_BUTTON_PADDLE3] = "P3",
[SDL_CONTROLLER_BUTTON_PADDLE4] = "P4",
[SDL_CONTROLLER_BUTTON_TOUCHPAD] = "Touch",
};
#endif
const char* mSDLButtonName(SDL_GameController* controller, SDL_GameControllerButton button) {
const char* const* buttonNames = buttonNamesXbox360;
#if SDL_VERSION_ATLEAST(2, 0, 12)
switch (SDL_GameControllerGetType(controller)) {
case SDL_CONTROLLER_TYPE_XBOX360:
buttonNames = buttonNamesXbox360;
break;
case SDL_CONTROLLER_TYPE_XBOXONE:
buttonNames = buttonNamesXboxOne;
break;
case SDL_CONTROLLER_TYPE_PS3:
case SDL_CONTROLLER_TYPE_PS4:
#if SDL_VERSION_ATLEAST(2, 0, 14)
case SDL_CONTROLLER_TYPE_PS5:
#endif
buttonNames = buttonNamesPlayStation;
break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
buttonNames = buttonNamesNintedo;
break;
default:
buttonNames = buttonNamesGeneric;
break;
}
#endif
switch (button) {
case SDL_CONTROLLER_BUTTON_DPAD_UP:
return "D↑";
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
return "D↓";
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
return "D←";
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
return "D→";
default:
return buttonNames[button];
case SDL_CONTROLLER_BUTTON_INVALID:
case SDL_CONTROLLER_BUTTON_MAX:
break;
}
return NULL;
}
static const char* const axisNamesXbox[SDL_CONTROLLER_AXIS_MAX] = {
[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = "LT",
[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = "RT",
};
#if SDL_VERSION_ATLEAST(2, 0, 12)
static const char* const axisNamesPlayStation[SDL_CONTROLLER_AXIS_MAX] = {
[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = "L3",
[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = "R3",
};
static const char* const axisNamesNintendo[SDL_CONTROLLER_AXIS_MAX] = {
[SDL_CONTROLLER_AXIS_TRIGGERLEFT] = "ZL",
[SDL_CONTROLLER_AXIS_TRIGGERRIGHT] = "ZR",
};
#endif
const char* mSDLAxisName(SDL_GameController* controller, SDL_GameControllerAxis axis) {
const char* const* axisNames = axisNamesXbox;
#if SDL_VERSION_ATLEAST(2, 0, 12)
switch (SDL_GameControllerGetType(controller)) {
case SDL_CONTROLLER_TYPE_XBOX360:
case SDL_CONTROLLER_TYPE_XBOXONE:
default:
axisNames = axisNamesXbox;
break;
case SDL_CONTROLLER_TYPE_PS3:
case SDL_CONTROLLER_TYPE_PS4:
#if SDL_VERSION_ATLEAST(2, 0, 14)
case SDL_CONTROLLER_TYPE_PS5:
#endif
axisNames = axisNamesPlayStation;
break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
axisNames = axisNamesNintendo;
break;
}
#endif
switch (axis) {
case SDL_CONTROLLER_AXIS_LEFTX:
return "X";
case SDL_CONTROLLER_AXIS_LEFTY:
return "Y";
case SDL_CONTROLLER_AXIS_RIGHTX:
return "RX";
case SDL_CONTROLLER_AXIS_RIGHTY:
return "RY";
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
return axisNames[axis];
case SDL_CONTROLLER_AXIS_INVALID:
case SDL_CONTROLLER_AXIS_MAX:
break;
}
return NULL;
}
#endif

View File

@ -126,6 +126,9 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext,
void mSDLSuspendScreensaver(struct mSDLEvents*);
void mSDLResumeScreensaver(struct mSDLEvents*);
void mSDLSetScreensaverSuspendable(struct mSDLEvents*, bool suspendable);
const char* mSDLButtonName(SDL_GameController*, SDL_GameControllerButton);
const char* mSDLAxisName(SDL_GameController*, SDL_GameControllerAxis);
#endif
CXX_GUARD_END