mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 10:35:03 +00:00
Use separate class for SDL event signals so that i can work with the SDL window event loop
This commit is contained in:
parent
5430ca00fe
commit
b74eb796fe
@ -1068,6 +1068,8 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||
src/qt_gui/gui_settings.h
|
||||
src/qt_gui/settings.cpp
|
||||
src/qt_gui/settings.h
|
||||
src/qt_gui/sdl_event_wrapper.cpp
|
||||
src/qt_gui/sdl_event_wrapper.h
|
||||
${EMULATOR}
|
||||
${RESOURCE_FILES}
|
||||
${TRANSLATIONS}
|
||||
|
@ -10,17 +10,21 @@
|
||||
#include "control_settings.h"
|
||||
#include "ui_control_settings.h"
|
||||
|
||||
ControlSettings::ControlSettings(std::shared_ptr<GameInfoClass> game_info_get, QWidget* parent)
|
||||
: QDialog(parent), m_game_info(game_info_get), ui(new Ui::ControlSettings) {
|
||||
ControlSettings::ControlSettings(std::shared_ptr<GameInfoClass> game_info_get, bool isGameRunning,
|
||||
QWidget* parent)
|
||||
: QDialog(parent), m_game_info(game_info_get), GameRunning(isGameRunning),
|
||||
ui(new Ui::ControlSettings) {
|
||||
|
||||
ui->setupUi(this);
|
||||
|
||||
if (!GameRunning) {
|
||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||
SDL_InitSubSystem(SDL_INIT_EVENTS);
|
||||
} else {
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
|
||||
}
|
||||
|
||||
CheckGamePad();
|
||||
QFuture<void> future = QtConcurrent::run(&ControlSettings::pollSDLEvents, this);
|
||||
|
||||
AddBoxItems();
|
||||
SetUIValuestoMappings();
|
||||
UpdateLightbarColor();
|
||||
@ -113,6 +117,14 @@ ControlSettings::ControlSettings(std::shared_ptr<GameInfoClass> game_info_get, Q
|
||||
[this]() { CheckMapping(MappingButton); });
|
||||
connect(this, &ControlSettings::AxisChanged, this,
|
||||
[this]() { ConnectAxisInputs(MappingButton); });
|
||||
|
||||
RemapWrapper = SdlEventWrapper::Wrapper::GetInstance();
|
||||
SdlEventWrapper::Wrapper::wrapperActive = true;
|
||||
QObject::connect(RemapWrapper, &SdlEventWrapper::Wrapper::SDLEvent, this,
|
||||
&ControlSettings::processSDLEvents);
|
||||
|
||||
if (!GameRunning)
|
||||
QFuture<void> future = QtConcurrent::run(&ControlSettings::pollSDLEvents, this);
|
||||
}
|
||||
|
||||
void ControlSettings::SaveControllerConfig(bool CloseOnSave) {
|
||||
@ -621,9 +633,12 @@ void ControlSettings::UpdateLightbarColor() {
|
||||
}
|
||||
|
||||
void ControlSettings::CheckGamePad() {
|
||||
if (m_gamepad) {
|
||||
SDL_CloseGamepad(m_gamepad);
|
||||
m_gamepad = nullptr;
|
||||
if (GameRunning)
|
||||
return;
|
||||
|
||||
if (gamepad) {
|
||||
SDL_CloseGamepad(gamepad);
|
||||
gamepad = nullptr;
|
||||
}
|
||||
|
||||
int gamepad_count;
|
||||
@ -641,9 +656,9 @@ void ControlSettings::CheckGamePad() {
|
||||
}
|
||||
|
||||
LOG_INFO(Input, "Got {} gamepads. Opening the first one.", gamepad_count);
|
||||
m_gamepad = SDL_OpenGamepad(gamepads[0]);
|
||||
gamepad = SDL_OpenGamepad(gamepads[0]);
|
||||
|
||||
if (!m_gamepad) {
|
||||
if (!gamepad) {
|
||||
LOG_ERROR(Input, "Failed to open gamepad 0: {}", SDL_GetError());
|
||||
SDL_free(gamepads);
|
||||
return;
|
||||
@ -697,7 +712,6 @@ void ControlSettings::StartTimer(QPushButton*& button, bool isButton) {
|
||||
MappingTimer = 3;
|
||||
isButton ? EnableButtonMapping = true : EnableAxisMapping = true;
|
||||
MappingCompleted = false;
|
||||
triggerWasPressed = false;
|
||||
mapping = button->text();
|
||||
DisableMappingButtons();
|
||||
|
||||
@ -743,8 +757,8 @@ void ControlSettings::SetMapping(QString input) {
|
||||
mapping = input;
|
||||
MappingCompleted = true;
|
||||
if (EnableAxisMapping) {
|
||||
emit AxisChanged();
|
||||
emit PushGamepadEvent();
|
||||
emit AxisChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@ -760,27 +774,28 @@ bool ControlSettings::eventFilter(QObject* obj, QEvent* event) {
|
||||
return QDialog::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void ControlSettings::pollSDLEvents() {
|
||||
SDL_Event event;
|
||||
|
||||
while (isRunning) {
|
||||
if (!SDL_WaitEvent(&event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type == SDL_EVENT_QUIT) {
|
||||
isRunning = false;
|
||||
void ControlSettings::processSDLEvents(int Type, int Input, int Value) {
|
||||
if (Type == SDL_EVENT_QUIT) {
|
||||
SdlEventWrapper::Wrapper::wrapperActive = false;
|
||||
if (gamepad)
|
||||
SDL_CloseGamepad(gamepad);
|
||||
if (!GameRunning) {
|
||||
SDL_QuitSubSystem(SDL_INIT_GAMEPAD);
|
||||
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||
SDL_Quit();
|
||||
} else {
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "0");
|
||||
}
|
||||
}
|
||||
|
||||
if (event.type == SDL_EVENT_GAMEPAD_ADDED)
|
||||
if (Type == SDL_EVENT_GAMEPAD_ADDED) {
|
||||
if (!GameRunning)
|
||||
CheckGamePad();
|
||||
}
|
||||
|
||||
if (EnableButtonMapping) {
|
||||
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
|
||||
switch (event.gbutton.button) {
|
||||
if (Type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
|
||||
switch (Input) {
|
||||
case SDL_GAMEPAD_BUTTON_SOUTH:
|
||||
pressedButtons.insert("cross");
|
||||
break;
|
||||
@ -840,42 +855,28 @@ void ControlSettings::pollSDLEvents() {
|
||||
}
|
||||
}
|
||||
|
||||
if (event.type == SDL_EVENT_GAMEPAD_BUTTON_UP) {
|
||||
emit PushGamepadEvent();
|
||||
}
|
||||
|
||||
if (event.type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
|
||||
if (Type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
|
||||
// SDL trigger axis values range from 0 to 32000, set mapping on half movement
|
||||
// Set zone for trigger release signal arbitrarily at 5000
|
||||
switch (event.gaxis.axis) {
|
||||
if (Value > 16000) {
|
||||
switch (Input) {
|
||||
case SDL_GAMEPAD_AXIS_LEFT_TRIGGER:
|
||||
if (event.gaxis.value > 16000) {
|
||||
pressedButtons.insert("l2");
|
||||
triggerWasPressed = true;
|
||||
} else if (event.gaxis.value < 5000) {
|
||||
if (triggerWasPressed)
|
||||
emit PushGamepadEvent();
|
||||
}
|
||||
break;
|
||||
case SDL_GAMEPAD_AXIS_RIGHT_TRIGGER:
|
||||
if (event.gaxis.value > 16000) {
|
||||
pressedButtons.insert("r2");
|
||||
triggerWasPressed = true;
|
||||
} else if (event.gaxis.value < 5000) {
|
||||
if (triggerWasPressed)
|
||||
emit PushGamepadEvent();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (EnableAxisMapping) {
|
||||
if (event.type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
|
||||
if (Type == SDL_EVENT_GAMEPAD_AXIS_MOTION) {
|
||||
// SDL stick axis values range from -32000 to 32000, set mapping on half movement
|
||||
if (event.gaxis.value > 16000 || event.gaxis.value < -16000) {
|
||||
switch (event.gaxis.axis) {
|
||||
if (Value > 16000 || Value < -16000) {
|
||||
switch (Input) {
|
||||
case SDL_GAMEPAD_AXIS_LEFTX:
|
||||
SetMapping("axis_left_x");
|
||||
break;
|
||||
@ -894,6 +895,16 @@ void ControlSettings::pollSDLEvents() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ControlSettings::pollSDLEvents() {
|
||||
SDL_Event event;
|
||||
while (SdlEventWrapper::Wrapper::wrapperActive) {
|
||||
if (!SDL_WaitEvent(&event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SdlEventWrapper::Wrapper::GetInstance()->Wrapper::ProcessEvent(&event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_gamepad.h>
|
||||
#include "game_info.h"
|
||||
#include "sdl_event_wrapper.h"
|
||||
|
||||
namespace Ui {
|
||||
class ControlSettings;
|
||||
@ -14,7 +14,7 @@ class ControlSettings;
|
||||
class ControlSettings : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ControlSettings(std::shared_ptr<GameInfoClass> game_info_get,
|
||||
explicit ControlSettings(std::shared_ptr<GameInfoClass> game_info_get, bool GameRunning,
|
||||
QWidget* parent = nullptr);
|
||||
~ControlSettings();
|
||||
|
||||
@ -39,6 +39,7 @@ private:
|
||||
void SetUIValuestoMappings();
|
||||
void GetGameTitle();
|
||||
void CheckGamePad();
|
||||
void processSDLEvents(int Type, int Input, int Value);
|
||||
void pollSDLEvents();
|
||||
void SetMapping(QString input);
|
||||
void DisableMappingButtons();
|
||||
@ -48,8 +49,7 @@ private:
|
||||
QList<QPushButton*> AxisList;
|
||||
QSet<QString> pressedButtons;
|
||||
|
||||
bool isRunning = true;
|
||||
bool triggerWasPressed = false;
|
||||
bool GameRunning;
|
||||
bool EnableButtonMapping = false;
|
||||
bool EnableAxisMapping = false;
|
||||
bool MappingCompleted = false;
|
||||
@ -57,7 +57,8 @@ private:
|
||||
int MappingTimer;
|
||||
QTimer* timer;
|
||||
QPushButton* MappingButton;
|
||||
SDL_Gamepad* m_gamepad = nullptr;
|
||||
SDL_Gamepad* gamepad = nullptr;
|
||||
SdlEventWrapper::Wrapper* RemapWrapper;
|
||||
|
||||
const std::vector<std::string> ControllerInputs = {
|
||||
"cross", "circle", "square", "triangle", "l1",
|
||||
|
@ -473,13 +473,8 @@ void MainWindow::CreateConnects() {
|
||||
});
|
||||
|
||||
connect(ui->controllerButton, &QPushButton::clicked, this, [this]() {
|
||||
if (!isGameRunning) {
|
||||
auto configWindow = new ControlSettings(m_game_info, this);
|
||||
configWindow->exec();
|
||||
} else {
|
||||
QMessageBox::information(this, tr("Remapping not available"),
|
||||
tr("Cannot remap controller while game is running"));
|
||||
}
|
||||
ControlSettings* remapWindow = new ControlSettings(m_game_info, isGameRunning, this);
|
||||
remapWindow->exec();
|
||||
});
|
||||
|
||||
connect(ui->keyboardButton, &QPushButton::clicked, this, [this]() {
|
||||
|
44
src/qt_gui/sdl_event_wrapper.cpp
Normal file
44
src/qt_gui/sdl_event_wrapper.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "sdl_event_wrapper.h"
|
||||
|
||||
using namespace SdlEventWrapper;
|
||||
|
||||
Wrapper* Wrapper::WrapperInstance = nullptr;
|
||||
bool Wrapper::wrapperActive = false;
|
||||
|
||||
Wrapper::Wrapper(QObject* parent) : QObject(parent) {}
|
||||
|
||||
Wrapper* Wrapper::GetInstance() {
|
||||
if (WrapperInstance == nullptr) {
|
||||
WrapperInstance = new Wrapper();
|
||||
}
|
||||
return WrapperInstance;
|
||||
}
|
||||
|
||||
bool Wrapper::ProcessEvent(SDL_Event* event) {
|
||||
if (!wrapperActive)
|
||||
return false;
|
||||
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_QUIT:
|
||||
emit SDLEvent(SDL_EVENT_QUIT, 0, 0);
|
||||
return true;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
emit SDLEvent(SDL_EVENT_GAMEPAD_ADDED, 0, 0);
|
||||
return true;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN:
|
||||
emit SDLEvent(SDL_EVENT_GAMEPAD_BUTTON_DOWN, event->gbutton.button, 0);
|
||||
return true;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP:
|
||||
emit SDLEvent(SDL_EVENT_GAMEPAD_BUTTON_UP, event->gbutton.button, 0);
|
||||
return true;
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION:
|
||||
emit SDLEvent(SDL_EVENT_GAMEPAD_AXIS_MOTION, event->gaxis.axis, event->gaxis.value);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Wrapper::~Wrapper() {}
|
25
src/qt_gui/sdl_event_wrapper.h
Normal file
25
src/qt_gui/sdl_event_wrapper.h
Normal file
@ -0,0 +1,25 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
#include <QObject>
|
||||
#include <SDL3/SDL_events.h>
|
||||
|
||||
namespace SdlEventWrapper {
|
||||
|
||||
class Wrapper : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Wrapper(QObject* parent = nullptr);
|
||||
~Wrapper();
|
||||
bool ProcessEvent(SDL_Event* event);
|
||||
static Wrapper* GetInstance();
|
||||
static bool wrapperActive;
|
||||
static Wrapper* WrapperInstance;
|
||||
|
||||
signals:
|
||||
void SDLEvent(int Type, int Input, int Value);
|
||||
};
|
||||
|
||||
} // namespace SdlEventWrapper
|
@ -20,6 +20,10 @@
|
||||
#include "sdl_window.h"
|
||||
#include "video_core/renderdoc.h"
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
#include "qt_gui/sdl_event_wrapper.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "SDL3/SDL_metal.h"
|
||||
#endif
|
||||
@ -340,6 +344,13 @@ void WindowSDL::WaitEvent() {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
if (SdlEventWrapper::Wrapper::wrapperActive) {
|
||||
if (SdlEventWrapper::Wrapper::GetInstance()->ProcessEvent(&event))
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ImGui::Core::ProcessEvent(&event)) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user