1 Commits

Author SHA1 Message Date
fb1eee561f alsdkj 2022-04-23 19:47:32 -05:00
13 changed files with 95 additions and 34 deletions

View File

@ -540,7 +540,7 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
controller.npad_button_state.raw = NpadButton::None; controller.npad_button_state.raw = NpadButton::None;
controller.debug_pad_button_state.raw = 0; controller.debug_pad_button_state.raw = 0;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Button, false); TriggerOnChange(ControllerTriggerType::Button, CallbackType::RawInput);
return; return;
} }
@ -639,7 +639,7 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
Connect(); Connect();
} }
} }
TriggerOnChange(ControllerTriggerType::Button, true); TriggerOnChange(ControllerTriggerType::Button, CallbackType::ServiceInput);
} }
void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, std::size_t index, void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback, std::size_t index,
@ -664,7 +664,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
controller.analog_stick_state.left = {}; controller.analog_stick_state.left = {};
controller.analog_stick_state.right = {}; controller.analog_stick_state.right = {};
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Stick, false); TriggerOnChange(ControllerTriggerType::Stick, CallbackType::RawInput);
return; return;
} }
@ -691,7 +691,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
} }
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Stick, true); TriggerOnChange(ControllerTriggerType::Stick, CallbackType::ServiceInput);
} }
void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callback, void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callback,
@ -716,7 +716,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
controller.gc_trigger_state.left = 0; controller.gc_trigger_state.left = 0;
controller.gc_trigger_state.right = 0; controller.gc_trigger_state.right = 0;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Trigger, false); TriggerOnChange(ControllerTriggerType::Trigger, CallbackType::RawInput);
return; return;
} }
@ -735,7 +735,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
} }
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Trigger, true); TriggerOnChange(ControllerTriggerType::Trigger, CallbackType::ServiceInput);
} }
void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback, void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback,
@ -765,7 +765,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
if (is_configuring) { if (is_configuring) {
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Motion, false); TriggerOnChange(ControllerTriggerType::Motion, CallbackType::RawInput);
return; return;
} }
@ -777,7 +777,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
motion.is_at_rest = !emulated.IsMoving(motion_sensitivity); motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Motion, true); TriggerOnChange(ControllerTriggerType::Motion, CallbackType::ServiceInput);
} }
void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback, void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callback,
@ -790,7 +790,7 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
if (is_configuring) { if (is_configuring) {
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Battery, false); TriggerOnChange(ControllerTriggerType::Battery, CallbackType::RawInput);
return; return;
} }
@ -848,7 +848,7 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
} }
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Battery, true); TriggerOnChange(ControllerTriggerType::Battery, CallbackType::ServiceInput);
} }
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
@ -1002,7 +1002,7 @@ void EmulatedController::Connect(bool use_temporary_value) {
if (is_configuring) { if (is_configuring) {
tmp_is_connected = true; tmp_is_connected = true;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Connected, false); TriggerOnChange(ControllerTriggerType::Connected, CallbackType::RawInput);
return; return;
} }
@ -1012,7 +1012,7 @@ void EmulatedController::Connect(bool use_temporary_value) {
is_connected = true; is_connected = true;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Connected, true); TriggerOnChange(ControllerTriggerType::Connected, CallbackType::ServiceInput);
} }
void EmulatedController::Disconnect() { void EmulatedController::Disconnect() {
@ -1020,7 +1020,7 @@ void EmulatedController::Disconnect() {
if (is_configuring) { if (is_configuring) {
tmp_is_connected = false; tmp_is_connected = false;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Disconnected, false); TriggerOnChange(ControllerTriggerType::Disconnected, CallbackType::RawInput);
return; return;
} }
@ -1030,7 +1030,7 @@ void EmulatedController::Disconnect() {
is_connected = false; is_connected = false;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Disconnected, true); TriggerOnChange(ControllerTriggerType::Disconnected, CallbackType::ServiceInput);
} }
bool EmulatedController::IsConnected(bool get_temporary_value) const { bool EmulatedController::IsConnected(bool get_temporary_value) const {
@ -1069,7 +1069,7 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
} }
tmp_npad_type = npad_type_; tmp_npad_type = npad_type_;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Type, false); TriggerOnChange(ControllerTriggerType::Type, CallbackType::RawInput);
return; return;
} }
@ -1083,7 +1083,7 @@ void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
npad_type = npad_type_; npad_type = npad_type_;
lock.unlock(); lock.unlock();
TriggerOnChange(ControllerTriggerType::Type, true); TriggerOnChange(ControllerTriggerType::Type, CallbackType::ServiceInput);
} }
LedPattern EmulatedController::GetLedPattern() const { LedPattern EmulatedController::GetLedPattern() const {
@ -1163,6 +1163,14 @@ NpadButtonState EmulatedController::GetNpadButtons() const {
return controller.npad_button_state; return controller.npad_button_state;
} }
NpadButtonState EmulatedController::GetSystemButtons() const {
std::scoped_lock lock{mutex};
if (is_configuring) {
return {};
}
return controller.system_button_state;
}
DebugPadButton EmulatedController::GetDebugPadButtons() const { DebugPadButton EmulatedController::GetDebugPadButtons() const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
if (is_configuring) { if (is_configuring) {
@ -1191,6 +1199,14 @@ AnalogSticks EmulatedController::GetSticks() const {
return controller.analog_stick_state; return controller.analog_stick_state;
} }
AnalogSticks EmulatedController::GetSystemSticks() const {
std::unique_lock lock{mutex};
if (is_configuring) {
return {};
}
return controller.system_analog_stick_state;
}
NpadGcTriggerState EmulatedController::GetTriggers() const { NpadGcTriggerState EmulatedController::GetTriggers() const {
std::scoped_lock lock{mutex}; std::scoped_lock lock{mutex};
if (is_configuring) { if (is_configuring) {
@ -1227,11 +1243,11 @@ BatteryLevelState EmulatedController::GetBattery() const {
return controller.battery_state; return controller.battery_state;
} }
void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { void EmulatedController::TriggerOnChange(ControllerTriggerType type, CallbackType callback_type) {
std::scoped_lock lock{callback_mutex}; std::scoped_lock lock{callback_mutex};
for (const auto& poller_pair : callback_list) { for (const auto& poller_pair : callback_list) {
const ControllerUpdateCallback& poller = poller_pair.second; const ControllerUpdateCallback& poller = poller_pair.second;
if (!is_npad_service_update && poller.is_npad_service) { if (callback_type < poller.callback_type) {
continue; continue;
} }
if (poller.on_change) { if (poller.on_change) {

View File

@ -97,9 +97,13 @@ struct ControllerStatus {
BatteryValues battery_values{}; BatteryValues battery_values{};
VibrationValues vibration_values{}; VibrationValues vibration_values{};
// Data for HID serices // Data for system
HomeButtonState home_button_state{}; HomeButtonState home_button_state{};
CaptureButtonState capture_button_state{}; CaptureButtonState capture_button_state{};
NpadButtonState system_button_state{};
AnalogSticks system_analog_stick_state{};
// Data for HID serices
NpadButtonState npad_button_state{}; NpadButtonState npad_button_state{};
DebugPadButton debug_pad_button_state{}; DebugPadButton debug_pad_button_state{};
AnalogSticks analog_stick_state{}; AnalogSticks analog_stick_state{};
@ -123,9 +127,16 @@ enum class ControllerTriggerType {
All, All,
}; };
// Type of update events
enum class CallbackType {
RawInput,
SystemInput,
ServiceInput,
};
struct ControllerUpdateCallback { struct ControllerUpdateCallback {
std::function<void(ControllerTriggerType)> on_change; std::function<void(ControllerTriggerType)> on_change;
bool is_npad_service; CallbackType callback_type;
}; };
class EmulatedController { class EmulatedController {
@ -278,16 +289,22 @@ public:
/// Returns the latest status of button input for the hid::Npad service /// Returns the latest status of button input for the hid::Npad service
NpadButtonState GetNpadButtons() const; NpadButtonState GetNpadButtons() const;
/// Returns the latest status of button input for the system
NpadButtonState GetSystemButtons() const;
/// Returns the latest status of button input for the debug pad service /// Returns the latest status of button input for the debug pad service
DebugPadButton GetDebugPadButtons() const; DebugPadButton GetDebugPadButtons() const;
/// Returns the latest status of stick input from the mouse /// Returns the latest status of stick input for the hid::Npad service
AnalogSticks GetSticks() const; AnalogSticks GetSticks() const;
/// Returns the latest status of trigger input from the mouse /// Returns the latest status of system stick input for the system
AnalogSticks GetSystemSticks() const;
/// Returns the latest status of trigger input for the hid::Npad service
NpadGcTriggerState GetTriggers() const; NpadGcTriggerState GetTriggers() const;
/// Returns the latest status of motion input from the mouse /// Returns the latest status of motion input for the hid::Npad service
MotionState GetMotions() const; MotionState GetMotions() const;
/// Returns the latest color value from the controller /// Returns the latest color value from the controller
@ -395,15 +412,16 @@ private:
/** /**
* Triggers a callback that something has changed on the controller status * Triggers a callback that something has changed on the controller status
* @param type Input type of the event to trigger * @param type Input type of the event to trigger
* @param is_service_update indicates if this event should only be sent to HID services * @param callback_type type of input that should be triggered
*/ */
void TriggerOnChange(ControllerTriggerType type, bool is_service_update); void TriggerOnChange(ControllerTriggerType type, CallbackType callback_type);
const NpadIdType npad_id_type; const NpadIdType npad_id_type;
NpadStyleIndex npad_type{NpadStyleIndex::None}; NpadStyleIndex npad_type{NpadStyleIndex::None};
NpadStyleTag supported_style_tag{NpadStyleSet::All}; NpadStyleTag supported_style_tag{NpadStyleSet::All};
bool is_connected{false}; bool is_connected{false};
bool is_configuring{false}; bool is_configuring{false};
bool is_service_disabled{false};
bool system_buttons_enabled{true}; bool system_buttons_enabled{true};
f32 motion_sensitivity{0.01f}; f32 motion_sensitivity{0.01f};
bool force_update_motion{false}; bool force_update_motion{false};

View File

@ -74,7 +74,7 @@ Controller_NPad::Controller_NPad(Core::HID::HIDCore& hid_core_,
Core::HID::ControllerUpdateCallback engine_callback{ Core::HID::ControllerUpdateCallback engine_callback{
.on_change = [this, .on_change = [this,
i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); }, i](Core::HID::ControllerTriggerType type) { ControllerUpdate(type, i); },
.is_npad_service = true, .callback_type = Core::HID::CallbackType::ServiceInput,
}; };
controller.callback_key = controller.device->SetCallback(engine_callback); controller.callback_key = controller.device->SetCallback(engine_callback);
} }

View File

@ -21,6 +21,7 @@
#include "yuzu/configuration/configure_vibration.h" #include "yuzu/configuration/configure_vibration.h"
#include "yuzu/configuration/input_profiles.h" #include "yuzu/configuration/input_profiles.h"
#include "yuzu/main.h" #include "yuzu/main.h"
#include "yuzu/util/controller_navigation.h"
namespace { namespace {
@ -197,6 +198,13 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
connect(ui->buttonBox, &QDialogButtonBox::accepted, this, connect(ui->buttonBox, &QDialogButtonBox::accepted, this,
&QtControllerSelectorDialog::ApplyConfiguration); &QtControllerSelectorDialog::ApplyConfiguration);
connect(controller_navigation, &ControllerNavigation::TriggerKeyboardEvent,
[this](Qt::Key key) {
if (!this->isActiveWindow()) {
return;
}
});
// Enhancement: Check if the parameters have already been met before disconnecting controllers. // Enhancement: Check if the parameters have already been met before disconnecting controllers.
// If all the parameters are met AND only allows a single player, // If all the parameters are met AND only allows a single player,
// stop the constructor here as we do not need to continue. // stop the constructor here as we do not need to continue.
@ -215,6 +223,7 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
} }
QtControllerSelectorDialog::~QtControllerSelectorDialog() { QtControllerSelectorDialog::~QtControllerSelectorDialog() {
controller_navigation->UnloadController();
system.HIDCore().DisableAllControllerConfiguration(); system.HIDCore().DisableAllControllerConfiguration();
} }

View File

@ -8,6 +8,7 @@
#include <QDialog> #include <QDialog>
#include "core/frontend/applets/controller.h" #include "core/frontend/applets/controller.h"
class ControllerNavigation;
class GMainWindow; class GMainWindow;
class QCheckBox; class QCheckBox;
class QComboBox; class QComboBox;
@ -147,6 +148,9 @@ private:
// Checkboxes representing the "Connected Controllers". // Checkboxes representing the "Connected Controllers".
std::array<QCheckBox*, NUM_PLAYERS> connected_controller_checkboxes; std::array<QCheckBox*, NUM_PLAYERS> connected_controller_checkboxes;
// Controller input to navigate through the UI
ControllerNavigation* controller_navigation = nullptr;
}; };
class QtControllerSelector final : public QObject, public Core::Frontend::ControllerApplet { class QtControllerSelector final : public QObject, public Core::Frontend::ControllerApplet {

View File

@ -131,7 +131,7 @@ int QtProfileSelectionDialog::exec() {
// Skip profile selection when there's only one. // Skip profile selection when there's only one.
if (profile_manager->GetUserCount() == 1) { if (profile_manager->GetUserCount() == 1) {
user_index = 0; user_index = 0;
return QDialog::Accepted; // return QDialog::Accepted;
} }
return QDialog::exec(); return QDialog::exec();
} }

View File

@ -28,7 +28,7 @@ void PlayerControlPreview::SetController(Core::HID::EmulatedController* controll
controller = controller_; controller = controller_;
Core::HID::ControllerUpdateCallback engine_callback{ Core::HID::ControllerUpdateCallback engine_callback{
.on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); }, .on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); },
.is_npad_service = false, .callback_type = Core::HID::CallbackType::RawInput,
}; };
callback_key = controller->SetCallback(engine_callback); callback_key = controller->SetCallback(engine_callback);
ControllerUpdate(Core::HID::ControllerTriggerType::All); ControllerUpdate(Core::HID::ControllerTriggerType::All);

View File

@ -31,7 +31,7 @@ ConfigureVibration::ConfigureVibration(QWidget* parent, Core::HID::HIDCore& hid_
Core::HID::ControllerUpdateCallback engine_callback{ Core::HID::ControllerUpdateCallback engine_callback{
.on_change = [this, .on_change = [this,
i](Core::HID::ControllerTriggerType type) { VibrateController(type, i); }, i](Core::HID::ControllerTriggerType type) { VibrateController(type, i); },
.is_npad_service = false, .callback_type = Core::HID::CallbackType::RawInput,
}; };
controller_callback_key[i] = controller->SetCallback(engine_callback); controller_callback_key[i] = controller->SetCallback(engine_callback);
vibration_groupboxes[i]->setChecked(players[i].vibration_enabled); vibration_groupboxes[i]->setChecked(players[i].vibration_enabled);

View File

@ -48,7 +48,7 @@ void ControllerDialog::refreshConfiguration() {
Core::HID::ControllerUpdateCallback engine_callback{ Core::HID::ControllerUpdateCallback engine_callback{
.on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); }, .on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); },
.is_npad_service = true, .callback_type = Core::HID::CallbackType::SystemInput,
}; };
callback_key = controller->SetCallback(engine_callback); callback_key = controller->SetCallback(engine_callback);
widget->SetController(controller); widget->SetController(controller);

View File

@ -88,7 +88,7 @@ ControllerShortcut::ControllerShortcut(Core::HID::EmulatedController* controller
emulated_controller = controller; emulated_controller = controller;
Core::HID::ControllerUpdateCallback engine_callback{ Core::HID::ControllerUpdateCallback engine_callback{
.on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdateEvent(type); }, .on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdateEvent(type); },
.is_npad_service = false, .callback_type = Core::HID::CallbackType::RawInput,
}; };
callback_key = emulated_controller->SetCallback(engine_callback); callback_key = emulated_controller->SetCallback(engine_callback);
is_enabled = true; is_enabled = true;

View File

@ -3312,10 +3312,13 @@ void GMainWindow::CenterMouseCursor() {
mouse_center_timer.stop(); mouse_center_timer.stop();
return; return;
} }
if (!this->isActiveWindow()) { if (!this->isActiveWindow()) {
mouse_center_timer.stop(); mouse_center_timer.stop();
return; return;
} }
LOG_ERROR(Input,"RESET");
const int center_x = render_window->width() / 2; const int center_x = render_window->width() / 2;
const int center_y = render_window->height() / 2; const int center_y = render_window->height() / 2;
@ -3615,6 +3618,17 @@ void GMainWindow::leaveEvent(QEvent* event) {
} }
} }
void GMainWindow::leaveEvent(QEvent* event) {
if (!this->isActiveWindow()) {
return;
}
if (Settings::values.mouse_panning) {
mouse_center_timer.start();
event->accept();
}
}
bool GMainWindow::ConfirmChangeGame() { bool GMainWindow::ConfirmChangeGame() {
if (emu_thread == nullptr) if (emu_thread == nullptr)
return true; return true;
@ -3803,4 +3817,4 @@ int main(int argc, char* argv[]) {
int result = app.exec(); int result = app.exec();
detached_tasks.WaitForAllTasks(); detached_tasks.WaitForAllTasks();
return result; return result;
} }

View File

@ -421,4 +421,4 @@ protected:
void dragEnterEvent(QDragEnterEvent* event) override; void dragEnterEvent(QDragEnterEvent* event) override;
void dragMoveEvent(QDragMoveEvent* event) override; void dragMoveEvent(QDragMoveEvent* event) override;
void leaveEvent(QEvent* event) override; void leaveEvent(QEvent* event) override;
}; };

View File

@ -11,7 +11,7 @@ ControllerNavigation::ControllerNavigation(Core::HID::HIDCore& hid_core, QWidget
handheld_controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); handheld_controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
Core::HID::ControllerUpdateCallback engine_callback{ Core::HID::ControllerUpdateCallback engine_callback{
.on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdateEvent(type); }, .on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdateEvent(type); },
.is_npad_service = false, .callback_type = Core::HID::CallbackType::SystemInput,
}; };
player1_callback_key = player1_controller->SetCallback(engine_callback); player1_callback_key = player1_controller->SetCallback(engine_callback);
handheld_callback_key = handheld_controller->SetCallback(engine_callback); handheld_callback_key = handheld_controller->SetCallback(engine_callback);