mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-23 00:40:58 +01:00
input_common: Eliminate most global state
Abstracts most of the input mechanisms under an InputSubsystem class that is managed by the frontends, eliminating any static constructors and destructors. This gets rid of global accessor functions and also allows the frontends to have a more fine-grained control over the lifecycle of the input subsystem. This also makes it explicit which interfaces rely on the input subsystem instead of making it opaque in the interface functions. All that remains to migrate over is the factories, which can be done in a separate change.
This commit is contained in:
parent
3db9a25977
commit
9e1b0af259
25 changed files with 397 additions and 243 deletions
|
@ -18,66 +18,166 @@
|
|||
|
||||
namespace InputCommon {
|
||||
|
||||
static std::shared_ptr<Keyboard> keyboard;
|
||||
static std::shared_ptr<MotionEmu> motion_emu;
|
||||
#ifdef HAVE_SDL2
|
||||
static std::unique_ptr<SDL::State> sdl;
|
||||
#endif
|
||||
static std::unique_ptr<CemuhookUDP::State> udp;
|
||||
static std::shared_ptr<GCButtonFactory> gcbuttons;
|
||||
static std::shared_ptr<GCAnalogFactory> gcanalog;
|
||||
struct InputSubsystem::Impl {
|
||||
void Initialize() {
|
||||
auto gcadapter = std::make_shared<GCAdapter::Adapter>();
|
||||
gcbuttons = std::make_shared<GCButtonFactory>(gcadapter);
|
||||
Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
|
||||
gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
|
||||
Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog);
|
||||
|
||||
void Init() {
|
||||
auto gcadapter = std::make_shared<GCAdapter::Adapter>();
|
||||
gcbuttons = std::make_shared<GCButtonFactory>(gcadapter);
|
||||
Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
|
||||
gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
|
||||
Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog);
|
||||
|
||||
keyboard = std::make_shared<Keyboard>();
|
||||
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
|
||||
Input::RegisterFactory<Input::AnalogDevice>("analog_from_button",
|
||||
std::make_shared<AnalogFromButton>());
|
||||
motion_emu = std::make_shared<MotionEmu>();
|
||||
Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
|
||||
keyboard = std::make_shared<Keyboard>();
|
||||
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
|
||||
Input::RegisterFactory<Input::AnalogDevice>("analog_from_button",
|
||||
std::make_shared<AnalogFromButton>());
|
||||
motion_emu = std::make_shared<MotionEmu>();
|
||||
Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
sdl = SDL::Init();
|
||||
sdl = SDL::Init();
|
||||
#endif
|
||||
udp = CemuhookUDP::Init();
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
|
||||
keyboard.reset();
|
||||
Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
|
||||
Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
|
||||
motion_emu.reset();
|
||||
udp = CemuhookUDP::Init();
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
|
||||
keyboard.reset();
|
||||
Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
|
||||
Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
|
||||
motion_emu.reset();
|
||||
#ifdef HAVE_SDL2
|
||||
sdl.reset();
|
||||
sdl.reset();
|
||||
#endif
|
||||
udp.reset();
|
||||
Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
|
||||
Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
|
||||
udp.reset();
|
||||
Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
|
||||
Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
|
||||
|
||||
gcbuttons.reset();
|
||||
gcanalog.reset();
|
||||
gcbuttons.reset();
|
||||
gcanalog.reset();
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
|
||||
std::vector<Common::ParamPackage> devices = {
|
||||
Common::ParamPackage{{"display", "Any"}, {"class", "any"}},
|
||||
Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}},
|
||||
};
|
||||
#ifdef HAVE_SDL2
|
||||
auto sdl_devices = sdl->GetInputDevices();
|
||||
devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end());
|
||||
#endif
|
||||
auto udp_devices = udp->GetInputDevices();
|
||||
devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
|
||||
return devices;
|
||||
}
|
||||
|
||||
[[nodiscard]] AnalogMapping GetAnalogMappingForDevice(
|
||||
const Common::ParamPackage& params) const {
|
||||
if (!params.Has("class") || params.Get("class", "") == "any") {
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "key") {
|
||||
// TODO consider returning the SDL key codes for the default keybindings
|
||||
return {};
|
||||
}
|
||||
#ifdef HAVE_SDL2
|
||||
if (params.Get("class", "") == "sdl") {
|
||||
return sdl->GetAnalogMappingForDevice(params);
|
||||
}
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]] ButtonMapping GetButtonMappingForDevice(
|
||||
const Common::ParamPackage& params) const {
|
||||
if (!params.Has("class") || params.Get("class", "") == "any") {
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "key") {
|
||||
// TODO consider returning the SDL key codes for the default keybindings
|
||||
return {};
|
||||
}
|
||||
#ifdef HAVE_SDL2
|
||||
if (params.Get("class", "") == "sdl") {
|
||||
return sdl->GetButtonMappingForDevice(params);
|
||||
}
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<Keyboard> keyboard;
|
||||
std::shared_ptr<MotionEmu> motion_emu;
|
||||
#ifdef HAVE_SDL2
|
||||
std::unique_ptr<SDL::State> sdl;
|
||||
#endif
|
||||
std::unique_ptr<CemuhookUDP::State> udp;
|
||||
std::shared_ptr<GCButtonFactory> gcbuttons;
|
||||
std::shared_ptr<GCAnalogFactory> gcanalog;
|
||||
};
|
||||
|
||||
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
|
||||
|
||||
InputSubsystem::~InputSubsystem() = default;
|
||||
|
||||
void InputSubsystem::Initialize() {
|
||||
impl->Initialize();
|
||||
}
|
||||
|
||||
Keyboard* GetKeyboard() {
|
||||
return keyboard.get();
|
||||
void InputSubsystem::Shutdown() {
|
||||
impl->Shutdown();
|
||||
}
|
||||
|
||||
MotionEmu* GetMotionEmu() {
|
||||
return motion_emu.get();
|
||||
Keyboard* InputSubsystem::GetKeyboard() {
|
||||
return impl->keyboard.get();
|
||||
}
|
||||
|
||||
GCButtonFactory* GetGCButtons() {
|
||||
return gcbuttons.get();
|
||||
const Keyboard* InputSubsystem::GetKeyboard() const {
|
||||
return impl->keyboard.get();
|
||||
}
|
||||
|
||||
GCAnalogFactory* GetGCAnalogs() {
|
||||
return gcanalog.get();
|
||||
MotionEmu* InputSubsystem::GetMotionEmu() {
|
||||
return impl->motion_emu.get();
|
||||
}
|
||||
|
||||
const MotionEmu* InputSubsystem::GetMotionEmu() const {
|
||||
return impl->motion_emu.get();
|
||||
}
|
||||
|
||||
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
|
||||
return impl->GetInputDevices();
|
||||
}
|
||||
|
||||
AnalogMapping InputSubsystem::GetAnalogMappingForDevice(const Common::ParamPackage& device) const {
|
||||
return impl->GetAnalogMappingForDevice(device);
|
||||
}
|
||||
|
||||
ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPackage& device) const {
|
||||
return impl->GetButtonMappingForDevice(device);
|
||||
}
|
||||
|
||||
GCAnalogFactory* InputSubsystem::GetGCAnalogs() {
|
||||
return impl->gcanalog.get();
|
||||
}
|
||||
|
||||
const GCAnalogFactory* InputSubsystem::GetGCAnalogs() const {
|
||||
return impl->gcanalog.get();
|
||||
}
|
||||
|
||||
GCButtonFactory* InputSubsystem::GetGCButtons() {
|
||||
return impl->gcbuttons.get();
|
||||
}
|
||||
|
||||
const GCButtonFactory* InputSubsystem::GetGCButtons() const {
|
||||
return impl->gcbuttons.get();
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Polling::DevicePoller>> InputSubsystem::GetPollers(
|
||||
Polling::DeviceType type) const {
|
||||
#ifdef HAVE_SDL2
|
||||
return impl->sdl->GetPollers(type);
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string GenerateKeyboardParam(int key_code) {
|
||||
|
@ -101,68 +201,4 @@ std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left,
|
|||
};
|
||||
return circle_pad_param.Serialize();
|
||||
}
|
||||
|
||||
std::vector<Common::ParamPackage> GetInputDevices() {
|
||||
std::vector<Common::ParamPackage> devices = {
|
||||
Common::ParamPackage{{"display", "Any"}, {"class", "any"}},
|
||||
Common::ParamPackage{{"display", "Keyboard/Mouse"}, {"class", "key"}},
|
||||
};
|
||||
#ifdef HAVE_SDL2
|
||||
auto sdl_devices = sdl->GetInputDevices();
|
||||
devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end());
|
||||
#endif
|
||||
auto udp_devices = udp->GetInputDevices();
|
||||
devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
|
||||
return devices;
|
||||
}
|
||||
|
||||
std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> GetButtonMappingForDevice(
|
||||
const Common::ParamPackage& params) {
|
||||
std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage> mappings;
|
||||
if (!params.Has("class") || params.Get("class", "") == "any") {
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "key") {
|
||||
// TODO consider returning the SDL key codes for the default keybindings
|
||||
return {};
|
||||
}
|
||||
#ifdef HAVE_SDL2
|
||||
if (params.Get("class", "") == "sdl") {
|
||||
return sdl->GetButtonMappingForDevice(params);
|
||||
}
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> GetAnalogMappingForDevice(
|
||||
const Common::ParamPackage& params) {
|
||||
std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage> mappings;
|
||||
if (!params.Has("class") || params.Get("class", "") == "any") {
|
||||
return {};
|
||||
}
|
||||
if (params.Get("class", "") == "key") {
|
||||
// TODO consider returning the SDL key codes for the default keybindings
|
||||
return {};
|
||||
}
|
||||
#ifdef HAVE_SDL2
|
||||
if (params.Get("class", "") == "sdl") {
|
||||
return sdl->GetAnalogMappingForDevice(params);
|
||||
}
|
||||
#endif
|
||||
return {};
|
||||
}
|
||||
|
||||
namespace Polling {
|
||||
|
||||
std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type) {
|
||||
std::vector<std::unique_ptr<DevicePoller>> pollers;
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
pollers = sdl->GetPollers(type);
|
||||
#endif
|
||||
|
||||
return pollers;
|
||||
}
|
||||
|
||||
} // namespace Polling
|
||||
} // namespace InputCommon
|
||||
|
|
|
@ -16,52 +16,6 @@ class ParamPackage;
|
|||
}
|
||||
|
||||
namespace InputCommon {
|
||||
|
||||
/// Initializes and registers all built-in input device factories.
|
||||
void Init();
|
||||
|
||||
/// Deregisters all built-in input device factories and shuts them down.
|
||||
void Shutdown();
|
||||
|
||||
class Keyboard;
|
||||
|
||||
/// Gets the keyboard button device factory.
|
||||
Keyboard* GetKeyboard();
|
||||
|
||||
class MotionEmu;
|
||||
|
||||
/// Gets the motion emulation factory.
|
||||
MotionEmu* GetMotionEmu();
|
||||
|
||||
GCButtonFactory* GetGCButtons();
|
||||
|
||||
GCAnalogFactory* GetGCAnalogs();
|
||||
|
||||
/// Generates a serialized param package for creating a keyboard button device
|
||||
std::string GenerateKeyboardParam(int key_code);
|
||||
|
||||
/// Generates a serialized param package for creating an analog device taking input from keyboard
|
||||
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
|
||||
int key_modifier, float modifier_scale);
|
||||
|
||||
/**
|
||||
* Return a list of available input devices that this Factory can create a new device with.
|
||||
* Each returned Parampackage should have a `display` field used for display, a class field for
|
||||
* backends to determine if this backend is meant to service the request and any other information
|
||||
* needed to identify this in the backend later.
|
||||
*/
|
||||
std::vector<Common::ParamPackage> GetInputDevices();
|
||||
|
||||
/**
|
||||
* Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default
|
||||
* mapping for the device. This is currently only implemented for the sdl backend devices.
|
||||
*/
|
||||
using ButtonMapping = std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage>;
|
||||
using AnalogMapping = std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage>;
|
||||
|
||||
ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage&);
|
||||
AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage&);
|
||||
|
||||
namespace Polling {
|
||||
|
||||
enum class DeviceType { Button, AnalogPreferred };
|
||||
|
@ -90,4 +44,88 @@ public:
|
|||
// Get all DevicePoller from all backends for a specific device type
|
||||
std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type);
|
||||
} // namespace Polling
|
||||
|
||||
class GCAnalogFactory;
|
||||
class GCButtonFactory;
|
||||
class Keyboard;
|
||||
class MotionEmu;
|
||||
|
||||
/**
|
||||
* Given a ParamPackage for a Device returned from `GetInputDevices`, attempt to get the default
|
||||
* mapping for the device. This is currently only implemented for the SDL backend devices.
|
||||
*/
|
||||
using AnalogMapping = std::unordered_map<Settings::NativeAnalog::Values, Common::ParamPackage>;
|
||||
using ButtonMapping = std::unordered_map<Settings::NativeButton::Values, Common::ParamPackage>;
|
||||
|
||||
class InputSubsystem {
|
||||
public:
|
||||
explicit InputSubsystem();
|
||||
~InputSubsystem();
|
||||
|
||||
InputSubsystem(const InputSubsystem&) = delete;
|
||||
InputSubsystem& operator=(const InputSubsystem&) = delete;
|
||||
|
||||
InputSubsystem(InputSubsystem&&) = delete;
|
||||
InputSubsystem& operator=(InputSubsystem&&) = delete;
|
||||
|
||||
/// Initializes and registers all built-in input device factories.
|
||||
void Initialize();
|
||||
|
||||
/// Unregisters all built-in input device factories and shuts them down.
|
||||
void Shutdown();
|
||||
|
||||
/// Retrieves the underlying keyboard device.
|
||||
[[nodiscard]] Keyboard* GetKeyboard();
|
||||
|
||||
/// Retrieves the underlying keyboard device.
|
||||
[[nodiscard]] const Keyboard* GetKeyboard() const;
|
||||
|
||||
/// Retrieves the underlying motion emulation factory.
|
||||
[[nodiscard]] MotionEmu* GetMotionEmu();
|
||||
|
||||
/// Retrieves the underlying motion emulation factory.
|
||||
[[nodiscard]] const MotionEmu* GetMotionEmu() const;
|
||||
|
||||
/**
|
||||
* Returns all available input devices that this Factory can create a new device with.
|
||||
* Each returned ParamPackage should have a `display` field used for display, a class field for
|
||||
* backends to determine if this backend is meant to service the request and any other
|
||||
* information needed to identify this in the backend later.
|
||||
*/
|
||||
[[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const;
|
||||
|
||||
/// Retrieves the analog mappings for the given device.
|
||||
[[nodiscard]] AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& device) const;
|
||||
|
||||
/// Retrieves the button mappings for the given device.
|
||||
[[nodiscard]] ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& device) const;
|
||||
|
||||
/// Retrieves the underlying GameCube analog handler.
|
||||
[[nodiscard]] GCAnalogFactory* GetGCAnalogs();
|
||||
|
||||
/// Retrieves the underlying GameCube analog handler.
|
||||
[[nodiscard]] const GCAnalogFactory* GetGCAnalogs() const;
|
||||
|
||||
/// Retrieves the underlying GameCube button handler.
|
||||
[[nodiscard]] GCButtonFactory* GetGCButtons();
|
||||
|
||||
/// Retrieves the underlying GameCube button handler.
|
||||
[[nodiscard]] const GCButtonFactory* GetGCButtons() const;
|
||||
|
||||
/// Get all DevicePoller from all backends for a specific device type
|
||||
[[nodiscard]] std::vector<std::unique_ptr<Polling::DevicePoller>> GetPollers(
|
||||
Polling::DeviceType type) const;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
/// Generates a serialized param package for creating a keyboard button device
|
||||
std::string GenerateKeyboardParam(int key_code);
|
||||
|
||||
/// Generates a serialized param package for creating an analog device taking input from keyboard
|
||||
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
|
||||
int key_modifier, float modifier_scale);
|
||||
|
||||
} // namespace InputCommon
|
||||
|
|
|
@ -304,8 +304,9 @@ static Core::Frontend::EmuWindow::WindowSystemInfo GetWindowSystemInfo(QWindow*
|
|||
return wsi;
|
||||
}
|
||||
|
||||
GRenderWindow::GRenderWindow(GMainWindow* parent_, EmuThread* emu_thread_)
|
||||
: QWidget(parent_), emu_thread(emu_thread_) {
|
||||
GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
||||
InputCommon::InputSubsystem* input_subsystem_)
|
||||
: QWidget(parent), emu_thread(emu_thread_), input_subsystem{input_subsystem_} {
|
||||
setWindowTitle(QStringLiteral("yuzu %1 | %2-%3")
|
||||
.arg(QString::fromUtf8(Common::g_build_name),
|
||||
QString::fromUtf8(Common::g_scm_branch),
|
||||
|
@ -314,15 +315,15 @@ GRenderWindow::GRenderWindow(GMainWindow* parent_, EmuThread* emu_thread_)
|
|||
auto layout = new QHBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
setLayout(layout);
|
||||
InputCommon::Init();
|
||||
input_subsystem->Initialize();
|
||||
|
||||
this->setMouseTracking(true);
|
||||
|
||||
connect(this, &GRenderWindow::FirstFrameDisplayed, parent_, &GMainWindow::OnLoadComplete);
|
||||
connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete);
|
||||
}
|
||||
|
||||
GRenderWindow::~GRenderWindow() {
|
||||
InputCommon::Shutdown();
|
||||
input_subsystem->Shutdown();
|
||||
}
|
||||
|
||||
void GRenderWindow::PollEvents() {
|
||||
|
@ -391,11 +392,11 @@ void GRenderWindow::closeEvent(QCloseEvent* event) {
|
|||
}
|
||||
|
||||
void GRenderWindow::keyPressEvent(QKeyEvent* event) {
|
||||
InputCommon::GetKeyboard()->PressKey(event->key());
|
||||
input_subsystem->GetKeyboard()->PressKey(event->key());
|
||||
}
|
||||
|
||||
void GRenderWindow::keyReleaseEvent(QKeyEvent* event) {
|
||||
InputCommon::GetKeyboard()->ReleaseKey(event->key());
|
||||
input_subsystem->GetKeyboard()->ReleaseKey(event->key());
|
||||
}
|
||||
|
||||
void GRenderWindow::mousePressEvent(QMouseEvent* event) {
|
||||
|
@ -409,7 +410,7 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
|
|||
const auto [x, y] = ScaleTouch(pos);
|
||||
this->TouchPressed(x, y);
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
InputCommon::GetMotionEmu()->BeginTilt(pos.x(), pos.y());
|
||||
input_subsystem->GetMotionEmu()->BeginTilt(pos.x(), pos.y());
|
||||
}
|
||||
QWidget::mousePressEvent(event);
|
||||
}
|
||||
|
@ -423,7 +424,7 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
|
|||
auto pos = event->pos();
|
||||
const auto [x, y] = ScaleTouch(pos);
|
||||
this->TouchMoved(x, y);
|
||||
InputCommon::GetMotionEmu()->Tilt(pos.x(), pos.y());
|
||||
input_subsystem->GetMotionEmu()->Tilt(pos.x(), pos.y());
|
||||
QWidget::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
|
@ -436,7 +437,7 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent* event) {
|
|||
if (event->button() == Qt::LeftButton) {
|
||||
this->TouchReleased();
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
InputCommon::GetMotionEmu()->EndTilt();
|
||||
input_subsystem->GetMotionEmu()->EndTilt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,7 +486,7 @@ bool GRenderWindow::event(QEvent* event) {
|
|||
|
||||
void GRenderWindow::focusOutEvent(QFocusEvent* event) {
|
||||
QWidget::focusOutEvent(event);
|
||||
InputCommon::GetKeyboard()->ReleaseAllKeys();
|
||||
input_subsystem->GetKeyboard()->ReleaseAllKeys();
|
||||
}
|
||||
|
||||
void GRenderWindow::resizeEvent(QResizeEvent* event) {
|
||||
|
|
|
@ -23,6 +23,10 @@ class QKeyEvent;
|
|||
class QTouchEvent;
|
||||
class QStringList;
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
namespace VideoCore {
|
||||
enum class LoadCallbackStage;
|
||||
}
|
||||
|
@ -121,7 +125,8 @@ class GRenderWindow : public QWidget, public Core::Frontend::EmuWindow {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GRenderWindow(GMainWindow* parent, EmuThread* emu_thread);
|
||||
explicit GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_,
|
||||
InputCommon::InputSubsystem* input_subsystem_);
|
||||
~GRenderWindow() override;
|
||||
|
||||
// EmuWindow implementation.
|
||||
|
@ -183,6 +188,7 @@ private:
|
|||
QStringList GetUnsupportedGLExtensions() const;
|
||||
|
||||
EmuThread* emu_thread;
|
||||
InputCommon::InputSubsystem* input_subsystem;
|
||||
|
||||
// Main context that will be shared with all other contexts that are requested.
|
||||
// If this is used in a shared context setting, then this should not be used directly, but
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
#include "ui_configure_debug_controller.h"
|
||||
#include "yuzu/configuration/configure_debug_controller.h"
|
||||
|
||||
ConfigureDebugController::ConfigureDebugController(QWidget* parent)
|
||||
ConfigureDebugController::ConfigureDebugController(QWidget* parent,
|
||||
InputCommon::InputSubsystem* input_subsystem)
|
||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDebugController>()),
|
||||
debug_controller(new ConfigureInputPlayer(this, 9, nullptr, true)) {
|
||||
debug_controller(new ConfigureInputPlayer(this, 9, nullptr, input_subsystem, true)) {
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->controllerLayout->addWidget(debug_controller);
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
class QPushButton;
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureDebugController;
|
||||
}
|
||||
|
@ -18,7 +22,8 @@ class ConfigureDebugController : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigureDebugController(QWidget* parent);
|
||||
explicit ConfigureDebugController(QWidget* parent,
|
||||
InputCommon::InputSubsystem* input_subsystem);
|
||||
~ConfigureDebugController() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
#include "yuzu/configuration/configure_input_player.h"
|
||||
#include "yuzu/hotkeys.h"
|
||||
|
||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry)
|
||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry,
|
||||
InputCommon::InputSubsystem* input_subsystem)
|
||||
: QDialog(parent), ui(new Ui::ConfigureDialog), registry(registry) {
|
||||
Settings::configuring_global = true;
|
||||
|
||||
|
@ -20,6 +21,8 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry)
|
|||
ui->hotkeysTab->Populate(registry);
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
ui->inputTab->Initialize(input_subsystem);
|
||||
|
||||
SetConfiguration();
|
||||
PopulateSelectionList();
|
||||
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
class HotkeyRegistry;
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureDialog;
|
||||
}
|
||||
|
@ -17,7 +21,8 @@ class ConfigureDialog : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry);
|
||||
explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry,
|
||||
InputCommon::InputSubsystem* input_subsystem);
|
||||
~ConfigureDialog() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
|
|
|
@ -65,16 +65,20 @@ void OnDockedModeChanged(bool last_state, bool new_state) {
|
|||
ConfigureInput::ConfigureInput(QWidget* parent)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInput>()) {
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
ConfigureInput::~ConfigureInput() = default;
|
||||
|
||||
void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem) {
|
||||
player_controllers = {
|
||||
new ConfigureInputPlayer(this, 0, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 1, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 2, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 3, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 4, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 5, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 6, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 7, ui->consoleInputSettings),
|
||||
new ConfigureInputPlayer(this, 0, ui->consoleInputSettings, input_subsystem),
|
||||
new ConfigureInputPlayer(this, 1, ui->consoleInputSettings, input_subsystem),
|
||||
new ConfigureInputPlayer(this, 2, ui->consoleInputSettings, input_subsystem),
|
||||
new ConfigureInputPlayer(this, 3, ui->consoleInputSettings, input_subsystem),
|
||||
new ConfigureInputPlayer(this, 4, ui->consoleInputSettings, input_subsystem),
|
||||
new ConfigureInputPlayer(this, 5, ui->consoleInputSettings, input_subsystem),
|
||||
new ConfigureInputPlayer(this, 6, ui->consoleInputSettings, input_subsystem),
|
||||
new ConfigureInputPlayer(this, 7, ui->consoleInputSettings, input_subsystem),
|
||||
};
|
||||
|
||||
player_tabs = {
|
||||
|
@ -115,10 +119,12 @@ ConfigureInput::ConfigureInput(QWidget* parent)
|
|||
advanced = new ConfigureInputAdvanced(this);
|
||||
ui->tabAdvanced->setLayout(new QHBoxLayout(ui->tabAdvanced));
|
||||
ui->tabAdvanced->layout()->addWidget(advanced);
|
||||
connect(advanced, &ConfigureInputAdvanced::CallDebugControllerDialog,
|
||||
[this] { CallConfigureDialog<ConfigureDebugController>(*this); });
|
||||
connect(advanced, &ConfigureInputAdvanced::CallMouseConfigDialog,
|
||||
[this] { CallConfigureDialog<ConfigureMouseAdvanced>(*this); });
|
||||
connect(advanced, &ConfigureInputAdvanced::CallDebugControllerDialog, [this, input_subsystem] {
|
||||
CallConfigureDialog<ConfigureDebugController>(*this, input_subsystem);
|
||||
});
|
||||
connect(advanced, &ConfigureInputAdvanced::CallMouseConfigDialog, [this, input_subsystem] {
|
||||
CallConfigureDialog<ConfigureMouseAdvanced>(*this, input_subsystem);
|
||||
});
|
||||
connect(advanced, &ConfigureInputAdvanced::CallTouchscreenConfigDialog,
|
||||
[this] { CallConfigureDialog<ConfigureTouchscreenAdvanced>(*this); });
|
||||
|
||||
|
@ -129,8 +135,6 @@ ConfigureInput::ConfigureInput(QWidget* parent)
|
|||
LoadConfiguration();
|
||||
}
|
||||
|
||||
ConfigureInput::~ConfigureInput() = default;
|
||||
|
||||
QList<QWidget*> ConfigureInput::GetSubTabs() const {
|
||||
return {
|
||||
ui->tabPlayer1, ui->tabPlayer2, ui->tabPlayer3, ui->tabPlayer4, ui->tabPlayer5,
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QWidget>
|
||||
|
||||
#include "yuzu/configuration/configure_input_advanced.h"
|
||||
#include "yuzu/configuration/configure_input_player.h"
|
||||
|
@ -19,6 +19,10 @@ class QCheckBox;
|
|||
class QString;
|
||||
class QTimer;
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureInput;
|
||||
}
|
||||
|
@ -32,6 +36,9 @@ public:
|
|||
explicit ConfigureInput(QWidget* parent = nullptr);
|
||||
~ConfigureInput() override;
|
||||
|
||||
/// Initializes the input dialog with the given input subsystem.
|
||||
void Initialize(InputCommon::InputSubsystem* input_subsystem_);
|
||||
|
||||
/// Save all button configurations to settings file.
|
||||
void ApplyConfiguration();
|
||||
|
||||
|
|
|
@ -11,12 +11,12 @@
|
|||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
#include "common/assert.h"
|
||||
#include "common/param_package.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "input_common/gcadapter/gc_poller.h"
|
||||
#include "input_common/main.h"
|
||||
#include "ui_configure_input_player.h"
|
||||
#include "yuzu/configuration/config.h"
|
||||
|
@ -229,9 +229,11 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)
|
|||
} // namespace
|
||||
|
||||
ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index,
|
||||
QWidget* bottom_row, bool debug)
|
||||
QWidget* bottom_row,
|
||||
InputCommon::InputSubsystem* input_subsystem_,
|
||||
bool debug)
|
||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index),
|
||||
debug(debug), timeout_timer(std::make_unique<QTimer>()),
|
||||
debug(debug), input_subsystem{input_subsystem_}, timeout_timer(std::make_unique<QTimer>()),
|
||||
poll_timer(std::make_unique<QTimer>()), bottom_row(bottom_row) {
|
||||
ui->setupUi(this);
|
||||
|
||||
|
@ -287,7 +289,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
|||
params.Set("direction", "+");
|
||||
params.Set("threshold", "0.5");
|
||||
}
|
||||
(*param) = std::move(params);
|
||||
*param = std::move(params);
|
||||
},
|
||||
InputCommon::Polling::DeviceType::Button);
|
||||
});
|
||||
|
@ -401,15 +403,15 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
|||
|
||||
connect(poll_timer.get(), &QTimer::timeout, [this] {
|
||||
Common::ParamPackage params;
|
||||
if (InputCommon::GetGCButtons()->IsPolling()) {
|
||||
params = InputCommon::GetGCButtons()->GetNextInput();
|
||||
if (input_subsystem->GetGCButtons()->IsPolling()) {
|
||||
params = input_subsystem->GetGCButtons()->GetNextInput();
|
||||
if (params.Has("engine")) {
|
||||
SetPollingResult(params, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (InputCommon::GetGCAnalogs()->IsPolling()) {
|
||||
params = InputCommon::GetGCAnalogs()->GetNextInput();
|
||||
if (input_subsystem->GetGCAnalogs()->IsPolling()) {
|
||||
params = input_subsystem->GetGCAnalogs()->GetNextInput();
|
||||
if (params.Has("engine")) {
|
||||
SetPollingResult(params, false);
|
||||
return;
|
||||
|
@ -514,7 +516,7 @@ void ConfigureInputPlayer::LoadConfiguration() {
|
|||
}
|
||||
|
||||
void ConfigureInputPlayer::UpdateInputDevices() {
|
||||
input_devices = InputCommon::GetInputDevices();
|
||||
input_devices = input_subsystem->GetInputDevices();
|
||||
ui->comboDevices->clear();
|
||||
for (auto device : input_devices) {
|
||||
ui->comboDevices->addItem(QString::fromStdString(device.Get("display", "Unknown")), {});
|
||||
|
@ -642,8 +644,8 @@ void ConfigureInputPlayer::UpdateMappingWithDefaults() {
|
|||
return;
|
||||
}
|
||||
const auto& device = input_devices[ui->comboDevices->currentIndex()];
|
||||
auto button_mapping = InputCommon::GetButtonMappingForDevice(device);
|
||||
auto analog_mapping = InputCommon::GetAnalogMappingForDevice(device);
|
||||
auto button_mapping = input_subsystem->GetButtonMappingForDevice(device);
|
||||
auto analog_mapping = input_subsystem->GetAnalogMappingForDevice(device);
|
||||
for (int i = 0; i < buttons_param.size(); ++i) {
|
||||
buttons_param[i] = button_mapping[static_cast<Settings::NativeButton::Values>(i)];
|
||||
}
|
||||
|
@ -666,7 +668,7 @@ void ConfigureInputPlayer::HandleClick(
|
|||
|
||||
input_setter = new_input_setter;
|
||||
|
||||
device_pollers = InputCommon::Polling::GetPollers(type);
|
||||
device_pollers = input_subsystem->GetPollers(type);
|
||||
|
||||
for (auto& poller : device_pollers) {
|
||||
poller->Start();
|
||||
|
@ -676,9 +678,9 @@ void ConfigureInputPlayer::HandleClick(
|
|||
QWidget::grabKeyboard();
|
||||
|
||||
if (type == InputCommon::Polling::DeviceType::Button) {
|
||||
InputCommon::GetGCButtons()->BeginConfiguration();
|
||||
input_subsystem->GetGCButtons()->BeginConfiguration();
|
||||
} else {
|
||||
InputCommon::GetGCAnalogs()->BeginConfiguration();
|
||||
input_subsystem->GetGCAnalogs()->BeginConfiguration();
|
||||
}
|
||||
|
||||
timeout_timer->start(2500); // Cancel after 2.5 seconds
|
||||
|
@ -695,8 +697,8 @@ void ConfigureInputPlayer::SetPollingResult(const Common::ParamPackage& params,
|
|||
QWidget::releaseMouse();
|
||||
QWidget::releaseKeyboard();
|
||||
|
||||
InputCommon::GetGCButtons()->EndConfiguration();
|
||||
InputCommon::GetGCAnalogs()->EndConfiguration();
|
||||
input_subsystem->GetGCButtons()->EndConfiguration();
|
||||
input_subsystem->GetGCAnalogs()->EndConfiguration();
|
||||
|
||||
if (!abort) {
|
||||
(*input_setter)(params);
|
||||
|
|
|
@ -10,12 +10,11 @@
|
|||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QWidget>
|
||||
|
||||
#include "common/param_package.h"
|
||||
#include "core/settings.h"
|
||||
#include "ui_configure_input.h"
|
||||
#include "yuzu/uisettings.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QKeyEvent;
|
||||
|
@ -27,6 +26,10 @@ class QString;
|
|||
class QTimer;
|
||||
class QWidget;
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
namespace InputCommon::Polling {
|
||||
class DevicePoller;
|
||||
enum class DeviceType;
|
||||
|
@ -41,6 +44,7 @@ class ConfigureInputPlayer : public QWidget {
|
|||
|
||||
public:
|
||||
explicit ConfigureInputPlayer(QWidget* parent, std::size_t player_index, QWidget* bottom_row,
|
||||
InputCommon::InputSubsystem* input_subsystem_,
|
||||
bool debug = false);
|
||||
~ConfigureInputPlayer() override;
|
||||
|
||||
|
@ -111,6 +115,8 @@ private:
|
|||
std::size_t player_index;
|
||||
bool debug;
|
||||
|
||||
InputCommon::InputSubsystem* input_subsystem;
|
||||
|
||||
std::unique_ptr<QTimer> timeout_timer;
|
||||
std::unique_ptr<QTimer> poll_timer;
|
||||
|
||||
|
|
|
@ -76,8 +76,10 @@ static QString ButtonToText(const Common::ParamPackage& param) {
|
|||
return QObject::tr("[unknown]");
|
||||
}
|
||||
|
||||
ConfigureMouseAdvanced::ConfigureMouseAdvanced(QWidget* parent)
|
||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureMouseAdvanced>()),
|
||||
ConfigureMouseAdvanced::ConfigureMouseAdvanced(QWidget* parent,
|
||||
InputCommon::InputSubsystem* input_subsystem_)
|
||||
: QDialog(parent),
|
||||
ui(std::make_unique<Ui::ConfigureMouseAdvanced>()), input_subsystem{input_subsystem_},
|
||||
timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) {
|
||||
ui->setupUi(this);
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
|
@ -209,7 +211,7 @@ void ConfigureMouseAdvanced::HandleClick(
|
|||
|
||||
input_setter = new_input_setter;
|
||||
|
||||
device_pollers = InputCommon::Polling::GetPollers(type);
|
||||
device_pollers = input_subsystem->GetPollers(type);
|
||||
|
||||
for (auto& poller : device_pollers) {
|
||||
poller->Start();
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
#include <optional>
|
||||
#include <QDialog>
|
||||
|
||||
#include "core/settings.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QPushButton;
|
||||
class QTimer;
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
namespace Ui {
|
||||
class ConfigureMouseAdvanced;
|
||||
}
|
||||
|
@ -22,7 +24,7 @@ class ConfigureMouseAdvanced : public QDialog {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConfigureMouseAdvanced(QWidget* parent);
|
||||
explicit ConfigureMouseAdvanced(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_);
|
||||
~ConfigureMouseAdvanced() override;
|
||||
|
||||
void ApplyConfiguration();
|
||||
|
@ -57,6 +59,8 @@ private:
|
|||
|
||||
std::unique_ptr<Ui::ConfigureMouseAdvanced> ui;
|
||||
|
||||
InputCommon::InputSubsystem* input_subsystem;
|
||||
|
||||
/// This will be the the setting function when an input is awaiting configuration.
|
||||
std::optional<std::function<void(const Common::ParamPackage&)>> input_setter;
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
|||
#include "core/perf_stats.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/telemetry_session.h"
|
||||
#include "input_common/main.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/shader_notify.h"
|
||||
#include "yuzu/about_dialog.h"
|
||||
|
@ -186,9 +187,9 @@ static void InitializeLogging() {
|
|||
}
|
||||
|
||||
GMainWindow::GMainWindow()
|
||||
: config(new Config()), emu_thread(nullptr),
|
||||
vfs(std::make_shared<FileSys::RealVfsFilesystem>()),
|
||||
provider(std::make_unique<FileSys::ManualContentProvider>()) {
|
||||
: input_subsystem{std::make_unique<InputCommon::InputSubsystem>()},
|
||||
config{std::make_unique<Config>()}, vfs{std::make_shared<FileSys::RealVfsFilesystem>()},
|
||||
provider{std::make_unique<FileSys::ManualContentProvider>()} {
|
||||
InitializeLogging();
|
||||
|
||||
LoadTranslation();
|
||||
|
@ -473,7 +474,7 @@ void GMainWindow::InitializeWidgets() {
|
|||
#ifdef YUZU_ENABLE_COMPATIBILITY_REPORTING
|
||||
ui.action_Report_Compatibility->setVisible(true);
|
||||
#endif
|
||||
render_window = new GRenderWindow(this, emu_thread.get());
|
||||
render_window = new GRenderWindow(this, emu_thread.get(), input_subsystem.get());
|
||||
render_window->hide();
|
||||
|
||||
game_list = new GameList(vfs, provider.get(), this);
|
||||
|
@ -2213,7 +2214,7 @@ void GMainWindow::OnConfigure() {
|
|||
const auto old_theme = UISettings::values.theme;
|
||||
const bool old_discord_presence = UISettings::values.enable_discord_presence;
|
||||
|
||||
ConfigureDialog configure_dialog(this, hotkey_registry);
|
||||
ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get());
|
||||
connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this,
|
||||
&GMainWindow::OnLanguageChanged);
|
||||
|
||||
|
|
|
@ -40,12 +40,20 @@ namespace Core::Frontend {
|
|||
struct SoftwareKeyboardParameters;
|
||||
} // namespace Core::Frontend
|
||||
|
||||
namespace DiscordRPC {
|
||||
class DiscordInterface;
|
||||
}
|
||||
|
||||
namespace FileSys {
|
||||
class ContentProvider;
|
||||
class ManualContentProvider;
|
||||
class VfsFilesystem;
|
||||
} // namespace FileSys
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
enum class EmulatedDirectoryTarget {
|
||||
NAND,
|
||||
SDMC,
|
||||
|
@ -62,10 +70,6 @@ enum class ReinitializeKeyBehavior {
|
|||
Warning,
|
||||
};
|
||||
|
||||
namespace DiscordRPC {
|
||||
class DiscordInterface;
|
||||
}
|
||||
|
||||
class GMainWindow : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -86,8 +90,6 @@ public:
|
|||
GMainWindow();
|
||||
~GMainWindow() override;
|
||||
|
||||
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
||||
|
||||
bool DropAction(QDropEvent* event);
|
||||
void AcceptDropEvent(QDropEvent* event);
|
||||
|
||||
|
@ -255,6 +257,9 @@ private:
|
|||
|
||||
Ui::MainWindow ui;
|
||||
|
||||
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
||||
std::unique_ptr<InputCommon::InputSubsystem> input_subsystem;
|
||||
|
||||
GRenderWindow* render_window;
|
||||
GameList* game_list;
|
||||
LoadingScreen* loading_screen;
|
||||
|
|
|
@ -13,23 +13,25 @@
|
|||
#include "input_common/sdl/sdl.h"
|
||||
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
|
||||
|
||||
EmuWindow_SDL2::EmuWindow_SDL2(Core::System& system, bool fullscreen) : system{system} {
|
||||
EmuWindow_SDL2::EmuWindow_SDL2(Core::System& system, bool fullscreen,
|
||||
InputCommon::InputSubsystem* input_subsystem_)
|
||||
: system{system}, input_subsystem{input_subsystem_} {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) {
|
||||
LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting...");
|
||||
exit(1);
|
||||
}
|
||||
InputCommon::Init();
|
||||
input_subsystem->Initialize();
|
||||
SDL_SetMainReady();
|
||||
}
|
||||
|
||||
EmuWindow_SDL2::~EmuWindow_SDL2() {
|
||||
InputCommon::Shutdown();
|
||||
input_subsystem->Shutdown();
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
|
||||
TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
|
||||
InputCommon::GetMotionEmu()->Tilt(x, y);
|
||||
input_subsystem->GetMotionEmu()->Tilt(x, y);
|
||||
}
|
||||
|
||||
void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
||||
|
@ -41,9 +43,9 @@ void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
|||
}
|
||||
} else if (button == SDL_BUTTON_RIGHT) {
|
||||
if (state == SDL_PRESSED) {
|
||||
InputCommon::GetMotionEmu()->BeginTilt(x, y);
|
||||
input_subsystem->GetMotionEmu()->BeginTilt(x, y);
|
||||
} else {
|
||||
InputCommon::GetMotionEmu()->EndTilt();
|
||||
input_subsystem->GetMotionEmu()->EndTilt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,9 +81,9 @@ void EmuWindow_SDL2::OnFingerUp() {
|
|||
|
||||
void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
|
||||
if (state == SDL_PRESSED) {
|
||||
InputCommon::GetKeyboard()->PressKey(key);
|
||||
input_subsystem->GetKeyboard()->PressKey(key);
|
||||
} else if (state == SDL_RELEASED) {
|
||||
InputCommon::GetKeyboard()->ReleaseKey(key);
|
||||
input_subsystem->GetKeyboard()->ReleaseKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,14 @@ namespace Core {
|
|||
class System;
|
||||
}
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
class EmuWindow_SDL2 : public Core::Frontend::EmuWindow {
|
||||
public:
|
||||
explicit EmuWindow_SDL2(Core::System& system, bool fullscreen);
|
||||
explicit EmuWindow_SDL2(Core::System& system, bool fullscreen,
|
||||
InputCommon::InputSubsystem* input_subsystem);
|
||||
~EmuWindow_SDL2();
|
||||
|
||||
/// Polls window events
|
||||
|
@ -76,4 +81,7 @@ protected:
|
|||
|
||||
/// Keeps track of how often to update the title bar during gameplay
|
||||
u32 last_time = 0;
|
||||
|
||||
/// Input subsystem to use with this window.
|
||||
InputCommon::InputSubsystem* input_subsystem;
|
||||
};
|
||||
|
|
|
@ -87,8 +87,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() {
|
|||
return unsupported_ext.empty();
|
||||
}
|
||||
|
||||
EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(Core::System& system, bool fullscreen)
|
||||
: EmuWindow_SDL2{system, fullscreen} {
|
||||
EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(Core::System& system, bool fullscreen,
|
||||
InputCommon::InputSubsystem* input_subsystem)
|
||||
: EmuWindow_SDL2{system, fullscreen, input_subsystem} {
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
|
||||
|
|
|
@ -8,9 +8,14 @@
|
|||
#include "core/frontend/emu_window.h"
|
||||
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 {
|
||||
public:
|
||||
explicit EmuWindow_SDL2_GL(Core::System& system, bool fullscreen);
|
||||
explicit EmuWindow_SDL2_GL(Core::System& system, bool fullscreen,
|
||||
InputCommon::InputSubsystem* input_subsystem);
|
||||
~EmuWindow_SDL2_GL();
|
||||
|
||||
void Present() override;
|
||||
|
|
|
@ -19,8 +19,9 @@
|
|||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
|
||||
EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(Core::System& system, bool fullscreen)
|
||||
: EmuWindow_SDL2{system, fullscreen} {
|
||||
EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(Core::System& system, bool fullscreen,
|
||||
InputCommon::InputSubsystem* input_subsystem)
|
||||
: EmuWindow_SDL2{system, fullscreen, input_subsystem} {
|
||||
const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name,
|
||||
Common::g_scm_branch, Common::g_scm_desc);
|
||||
render_window =
|
||||
|
|
|
@ -13,9 +13,14 @@ namespace Core {
|
|||
class System;
|
||||
}
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 {
|
||||
public:
|
||||
explicit EmuWindow_SDL2_VK(Core::System& system, bool fullscreen);
|
||||
explicit EmuWindow_SDL2_VK(Core::System& system, bool fullscreen,
|
||||
InputCommon::InputSubsystem* input_subsystem);
|
||||
~EmuWindow_SDL2_VK();
|
||||
|
||||
void Present() override;
|
||||
|
|
|
@ -23,12 +23,14 @@
|
|||
#include "common/telemetry.h"
|
||||
#include "core/core.h"
|
||||
#include "core/crypto/key_manager.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "core/file_sys/vfs_real.h"
|
||||
#include "core/gdbstub/gdbstub.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/telemetry_session.h"
|
||||
#include "input_common/main.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "yuzu_cmd/config.h"
|
||||
#include "yuzu_cmd/emu_window/emu_window_sdl2.h"
|
||||
|
@ -37,8 +39,6 @@
|
|||
#include "yuzu_cmd/emu_window/emu_window_sdl2_vk.h"
|
||||
#endif
|
||||
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
// windows.h needs to be included before shellapi.h
|
||||
#include <windows.h>
|
||||
|
@ -179,15 +179,16 @@ int main(int argc, char** argv) {
|
|||
Settings::Apply();
|
||||
|
||||
Core::System& system{Core::System::GetInstance()};
|
||||
InputCommon::InputSubsystem input_subsystem;
|
||||
|
||||
std::unique_ptr<EmuWindow_SDL2> emu_window;
|
||||
switch (Settings::values.renderer_backend.GetValue()) {
|
||||
case Settings::RendererBackend::OpenGL:
|
||||
emu_window = std::make_unique<EmuWindow_SDL2_GL>(system, fullscreen);
|
||||
emu_window = std::make_unique<EmuWindow_SDL2_GL>(system, fullscreen, &input_subsystem);
|
||||
break;
|
||||
case Settings::RendererBackend::Vulkan:
|
||||
#ifdef HAS_VULKAN
|
||||
emu_window = std::make_unique<EmuWindow_SDL2_VK>(system, fullscreen);
|
||||
emu_window = std::make_unique<EmuWindow_SDL2_VK>(system, fullscreen, &input_subsystem);
|
||||
break;
|
||||
#else
|
||||
LOG_CRITICAL(Frontend, "Vulkan backend has not been compiled!");
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "core/settings.h"
|
||||
|
@ -53,7 +52,7 @@ EmuWindow_SDL2_Hide::EmuWindow_SDL2_Hide() {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
InputCommon::Init();
|
||||
input_subsystem->Initialize();
|
||||
|
||||
SDL_SetMainReady();
|
||||
|
||||
|
@ -105,7 +104,7 @@ EmuWindow_SDL2_Hide::EmuWindow_SDL2_Hide() {
|
|||
}
|
||||
|
||||
EmuWindow_SDL2_Hide::~EmuWindow_SDL2_Hide() {
|
||||
InputCommon::Shutdown();
|
||||
input_subsystem->Shutdown();
|
||||
SDL_GL_DeleteContext(gl_context);
|
||||
SDL_Quit();
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
|
||||
struct SDL_Window;
|
||||
|
||||
namespace InputCommon {
|
||||
class InputSubsystem;
|
||||
}
|
||||
|
||||
class EmuWindow_SDL2_Hide : public Core::Frontend::EmuWindow {
|
||||
public:
|
||||
explicit EmuWindow_SDL2_Hide();
|
||||
|
@ -25,6 +29,8 @@ private:
|
|||
/// Whether the GPU and driver supports the OpenGL extension required
|
||||
bool SupportsRequiredGLExtensions();
|
||||
|
||||
std::unique_ptr<InputCommon::InputSubsystem> input_subsystem;
|
||||
|
||||
/// Internal SDL2 render window
|
||||
SDL_Window* render_window;
|
||||
|
||||
|
|
Loading…
Reference in a new issue