SDL: Start actually using SDL_GameController for its intended purpose

This commit is contained in:
Vicki Pfau 2024-04-03 02:56:29 -07:00
parent fb7ad7dbfb
commit 68d120ec55
6 changed files with 93 additions and 22 deletions

View File

@ -54,7 +54,7 @@ GBAKeyEditor::GBAKeyEditor(InputController* controller, int type, const QString&
refresh();
#ifdef BUILD_SDL
if (type == SDL_BINDING_BUTTON) {
if (type == SDL_BINDING_BUTTON || type == SDL_BINDING_CONTROLLER) {
m_profileSelect = new QComboBox(this);
connect(m_profileSelect, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &GBAKeyEditor::selectGamepad);
@ -265,7 +265,7 @@ void GBAKeyEditor::refresh() {
void GBAKeyEditor::lookupBinding(const mInputMap* map, KeyEditor* keyEditor, int key) {
#ifdef BUILD_SDL
if (m_type == SDL_BINDING_BUTTON) {
if (m_type == SDL_BINDING_BUTTON || m_type == SDL_BINDING_CONTROLLER) {
int value = mInputQueryBinding(map, m_type, key);
keyEditor->setValueButton(value);
return;
@ -329,7 +329,7 @@ void GBAKeyEditor::lookupHats(const mInputMap* map) {
void GBAKeyEditor::bindKey(const KeyEditor* keyEditor, int key) {
InputMapper mapper = m_controller->mapper(m_type);
#ifdef BUILD_SDL
if (m_type == SDL_BINDING_BUTTON && keyEditor->axis() >= 0) {
if ((m_type == SDL_BINDING_BUTTON || m_type == SDL_BINDING_CONTROLLER) && keyEditor->axis() >= 0) {
mapper.bindAxis(keyEditor->axis(), keyEditor->direction(), key);
}
if (m_type == SDL_BINDING_BUTTON && keyEditor->hat() >= 0) {

View File

@ -334,8 +334,13 @@ SettingsView::SettingsView(ConfigController* controller, InputController* inputC
GBAKeyEditor* buttonEditor = nullptr;
#ifdef BUILD_SDL
#if SDL_VERSION_ATLEAST(2, 0, 0)
QString profile = inputController->profileForType(SDL_BINDING_CONTROLLER);
buttonEditor = new GBAKeyEditor(inputController, SDL_BINDING_CONTROLLER, profile);
#else
QString profile = inputController->profileForType(SDL_BINDING_BUTTON);
buttonEditor = new GBAKeyEditor(inputController, SDL_BINDING_BUTTON, profile);
#endif
addPage(tr("Controllers"), buttonEditor, Page::CONTROLLERS);
connect(m_ui.buttonBox, &QDialogButtonBox::accepted, buttonEditor, &GBAKeyEditor::save);
#endif

View File

@ -177,8 +177,13 @@ Window::Window(CoreManager* manager, ConfigController* config, int playerId, QWi
#ifdef BUILD_SDL
m_inputController.addInputDriver(std::make_shared<SDLInputDriver>(&m_inputController));
#if SDL_VERSION_ATLEAST(2, 0, 0)
m_inputController.setGamepadDriver(SDL_BINDING_CONTROLLER);
m_inputController.setSensorDriver(SDL_BINDING_CONTROLLER);
#else
m_inputController.setGamepadDriver(SDL_BINDING_BUTTON);
m_inputController.setSensorDriver(SDL_BINDING_BUTTON);
#endif
#endif
m_shortcutController->setConfigController(m_config);

View File

@ -31,7 +31,11 @@ public:
SDLInputDriver(InputController*, QObject* parent = nullptr);
~SDLInputDriver();
#if SDL_VERSION_ATLEAST(2, 0, 0)
uint32_t type() const override { return SDL_BINDING_CONTROLLER; }
#else
uint32_t type() const override { return SDL_BINDING_BUTTON; }
#endif
QString visibleName() const override { return QLatin1String("SDL"); }
QString currentProfile() const override;

View File

@ -167,12 +167,30 @@ void mSDLInitBindingsGBA(struct mInputMap* inputMap) {
mInputBindKey(inputMap, SDL_BINDING_KEY, SDLK_RIGHT, GBA_KEY_RIGHT);
#endif
#if SDL_VERSION_ATLEAST(2, 0, 0)
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_A, GBA_KEY_A);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_B, GBA_KEY_B);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, GBA_KEY_L);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, GBA_KEY_R);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_START, GBA_KEY_START);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_BACK, GBA_KEY_SELECT);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_UP, GBA_KEY_UP);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_DOWN, GBA_KEY_DOWN);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_LEFT, GBA_KEY_LEFT);
mInputBindKey(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, GBA_KEY_RIGHT);
struct mInputAxis description = (struct mInputAxis) { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x4000, -0x4000 };
mInputBindAxis(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_AXIS_LEFTX, &description);
description = (struct mInputAxis) { GBA_KEY_DOWN, GBA_KEY_UP, 0x4000, -0x4000 };
mInputBindAxis(inputMap, SDL_BINDING_CONTROLLER, SDL_CONTROLLER_AXIS_LEFTY, &description);
#else
struct mInputAxis description = { GBA_KEY_RIGHT, GBA_KEY_LEFT, 0x4000, -0x4000 };
mInputBindAxis(inputMap, SDL_BINDING_BUTTON, 0, &description);
description = (struct mInputAxis) { GBA_KEY_DOWN, GBA_KEY_UP, 0x4000, -0x4000 };
mInputBindAxis(inputMap, SDL_BINDING_BUTTON, 1, &description);
mInputBindHat(inputMap, SDL_BINDING_BUTTON, 0, &GBAInputInfo.hat);
#endif
}
bool mSDLAttachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) {
@ -284,17 +302,19 @@ void mSDLDetachPlayer(struct mSDLEvents* events, struct mSDLPlayer* player) {
void mSDLPlayerLoadConfig(struct mSDLPlayer* context, const struct Configuration* config) {
mInputMapLoad(context->bindings, SDL_BINDING_KEY, config);
if (context->joystick) {
mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config);
#if SDL_VERSION_ATLEAST(2, 0, 0)
mInputMapLoad(context->bindings, SDL_BINDING_CONTROLLER, config);
char name[34] = {0};
SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(context->joystick->joystick), name, sizeof(name));
mInputProfileLoad(context->bindings, SDL_BINDING_CONTROLLER, config, name);
#else
mInputMapLoad(context->bindings, SDL_BINDING_BUTTON, config);
const char* name = SDL_JoystickName(SDL_JoystickIndex(context->joystick->joystick));
if (!name) {
return;
}
#endif
mInputProfileLoad(context->bindings, SDL_BINDING_BUTTON, config, name);
#endif
const char* value;
char* end;
@ -410,7 +430,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
if (events->preferredJoysticks[i] && strcmp(events->preferredJoysticks[i], joystickName) == 0) {
events->players[i]->joystick = joystick;
if (config) {
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_CONTROLLER, config, joystickName);
}
return;
}
@ -421,7 +441,7 @@ void mSDLUpdateJoysticks(struct mSDLEvents* events, const struct Configuration*
}
events->players[i]->joystick = joystick;
if (config && joystickName[0]) {
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_BUTTON, config, joystickName);
mInputProfileLoad(events->players[i]->bindings, SDL_BINDING_CONTROLLER, config, joystickName);
}
break;
}
@ -574,6 +594,45 @@ static void _mSDLHandleKeypress(struct mCoreThread* context, struct mSDLPlayer*
}
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
static void _mSDLHandleControllerButton(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const struct SDL_ControllerButtonEvent* event) {
int key = 0;
key = mInputMapKey(sdlContext->bindings, SDL_BINDING_CONTROLLER, event->button);
if (key == -1) {
return;
}
mCoreThreadInterrupt(context);
if (event->type == SDL_CONTROLLERBUTTONDOWN) {
context->core->addKeys(context->core, 1 << key);
} else {
context->core->clearKeys(context->core, 1 << key);
}
mCoreThreadContinue(context);
}
static void _mSDLHandleControllerAxis(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const struct SDL_ControllerAxisEvent* event) {
int clearKeys = ~mInputClearAxis(sdlContext->bindings, SDL_BINDING_CONTROLLER, event->axis, -1);
int newKeys = 0;
int key = mInputMapAxis(sdlContext->bindings, SDL_BINDING_CONTROLLER, event->axis, event->value);
if (key != -1) {
newKeys |= 1 << key;
}
clearKeys &= ~newKeys;
mCoreThreadInterrupt(context);
context->core->clearKeys(context->core, clearKeys);
context->core->addKeys(context->core, newKeys);
mCoreThreadContinue(context);
}
static void _mSDLHandleWindowEvent(struct mSDLPlayer* sdlContext, const struct SDL_WindowEvent* event) {
switch (event->event) {
case SDL_WINDOWEVENT_SIZE_CHANGED:
sdlContext->windowUpdated = 1;
break;
}
}
#else
static void _mSDLHandleJoyButton(struct mCoreThread* context, struct mSDLPlayer* sdlContext, const struct SDL_JoyButtonEvent* event) {
int key = 0;
key = mInputMapKey(sdlContext->bindings, SDL_BINDING_BUTTON, event->button);
@ -616,16 +675,6 @@ static void _mSDLHandleJoyAxis(struct mCoreThread* context, struct mSDLPlayer* s
context->core->clearKeys(context->core, clearKeys);
context->core->addKeys(context->core, newKeys);
mCoreThreadContinue(context);
}
#if SDL_VERSION_ATLEAST(2, 0, 0)
static void _mSDLHandleWindowEvent(struct mSDLPlayer* sdlContext, const struct SDL_WindowEvent* event) {
switch (event->event) {
case SDL_WINDOWEVENT_SIZE_CHANGED:
sdlContext->windowUpdated = 1;
break;
}
}
#endif
@ -638,17 +687,19 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext,
case SDL_WINDOWEVENT:
_mSDLHandleWindowEvent(sdlContext, &event->window);
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
_mSDLHandleControllerButton(context, sdlContext, &event->cbutton);
break;
case SDL_CONTROLLERAXISMOTION:
_mSDLHandleControllerAxis(context, sdlContext, &event->caxis);
break;
#else
case SDL_VIDEORESIZE:
sdlContext->newWidth = event->resize.w;
sdlContext->newHeight = event->resize.h;
sdlContext->windowUpdated = 1;
break;
#endif
case SDL_KEYDOWN:
case SDL_KEYUP:
_mSDLHandleKeypress(context, sdlContext, &event->key);
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
_mSDLHandleJoyButton(context, sdlContext, &event->jbutton);
@ -659,6 +710,11 @@ void mSDLHandleEvent(struct mCoreThread* context, struct mSDLPlayer* sdlContext,
case SDL_JOYAXISMOTION:
_mSDLHandleJoyAxis(context, sdlContext, &event->jaxis);
break;
#endif
case SDL_KEYDOWN:
case SDL_KEYUP:
_mSDLHandleKeypress(context, sdlContext, &event->key);
break;
}
}

View File

@ -29,6 +29,7 @@ mLOG_DECLARE_CATEGORY(SDL_EVENTS);
#define SDL_BINDING_KEY 0x53444C4BU
#define SDL_BINDING_BUTTON 0x53444C42U
#define SDL_BINDING_CONTROLLER 0x53444C43U
#define MAX_PLAYERS 4