mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2024-08-21 15:43:22 +02:00
Merge pull request #4544 from lioncash/input-sub
input_common: Eliminate most global state
This commit is contained in:
commit
45b73ba840
@ -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 New Issue
Block a user