mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-23 00:40:58 +01:00
configuration: Migrate controller settings to emulated controller
This commit is contained in:
parent
c3ff0a8ac0
commit
af55dd1935
12 changed files with 140 additions and 126 deletions
|
@ -91,7 +91,6 @@ void EmulatedController::ReloadFromSettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::ReloadInput() {
|
void EmulatedController::ReloadInput() {
|
||||||
// LOG_ERROR(Service_HID, "reload config {}", NpadIdTypeToIndex(npad_id_type));
|
|
||||||
// If you load any device here add the equivalent to the UnloadInput() function
|
// If you load any device here add the equivalent to the UnloadInput() function
|
||||||
const auto left_side = button_params[Settings::NativeButton::ZL];
|
const auto left_side = button_params[Settings::NativeButton::ZL];
|
||||||
const auto right_side = button_params[Settings::NativeButton::ZR];
|
const auto right_side = button_params[Settings::NativeButton::ZR];
|
||||||
|
|
|
@ -329,7 +329,7 @@ private:
|
||||||
* @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 be sended to only services
|
* @param is_service_update: indicates if this event should be sended to only services
|
||||||
*/
|
*/
|
||||||
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
|
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
|
||||||
|
|
||||||
NpadIdType npad_id_type;
|
NpadIdType npad_id_type;
|
||||||
NpadType npad_type{NpadType::None};
|
NpadType npad_type{NpadType::None};
|
||||||
|
|
|
@ -111,6 +111,27 @@ NpadStyleTag HIDCore::GetSupportedStyleTag() const {
|
||||||
return supported_style_tag;
|
return supported_style_tag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s8 HIDCore::GetPlayerCount() const {
|
||||||
|
s8 active_players = 0;
|
||||||
|
for (std::size_t player_index = 0; player_index < 8; player_index++) {
|
||||||
|
const auto* controller = GetEmulatedControllerByIndex(player_index);
|
||||||
|
if (controller->IsConnected()) {
|
||||||
|
active_players++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return active_players;
|
||||||
|
}
|
||||||
|
|
||||||
|
NpadIdType HIDCore::GetFirstNpadId() const {
|
||||||
|
for (std::size_t player_index = 0; player_index < 10; player_index++) {
|
||||||
|
const auto* controller = GetEmulatedControllerByIndex(player_index);
|
||||||
|
if (controller->IsConnected()) {
|
||||||
|
return controller->GetNpadIdType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NpadIdType::Player1;
|
||||||
|
}
|
||||||
|
|
||||||
void HIDCore::ReloadInputDevices() {
|
void HIDCore::ReloadInputDevices() {
|
||||||
player_1->ReloadFromSettings();
|
player_1->ReloadFromSettings();
|
||||||
player_2->ReloadFromSettings();
|
player_2->ReloadFromSettings();
|
||||||
|
|
|
@ -35,10 +35,16 @@ public:
|
||||||
void SetSupportedStyleTag(NpadStyleTag style_tag);
|
void SetSupportedStyleTag(NpadStyleTag style_tag);
|
||||||
NpadStyleTag GetSupportedStyleTag() const;
|
NpadStyleTag GetSupportedStyleTag() const;
|
||||||
|
|
||||||
// Reloads all input devices from settings
|
/// Counts the connected players from P1-P8
|
||||||
|
s8 GetPlayerCount() const;
|
||||||
|
|
||||||
|
/// Returns the first connected npad id
|
||||||
|
NpadIdType GetFirstNpadId() const;
|
||||||
|
|
||||||
|
/// Reloads all input devices from settings
|
||||||
void ReloadInputDevices();
|
void ReloadInputDevices();
|
||||||
|
|
||||||
// Removes all callbacks from input common
|
/// Removes all callbacks from input common
|
||||||
void UnloadInputDevices();
|
void UnloadInputDevices();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -243,19 +243,11 @@ void Controller::Execute() {
|
||||||
void Controller::ConfigurationComplete() {
|
void Controller::ConfigurationComplete() {
|
||||||
ControllerSupportResultInfo result_info{};
|
ControllerSupportResultInfo result_info{};
|
||||||
|
|
||||||
const auto& players = Settings::values.players.GetValue();
|
|
||||||
|
|
||||||
// If enable_single_mode is enabled, player_count is 1 regardless of any other parameters.
|
// If enable_single_mode is enabled, player_count is 1 regardless of any other parameters.
|
||||||
// Otherwise, only count connected players from P1-P8.
|
// Otherwise, only count connected players from P1-P8.
|
||||||
result_info.player_count =
|
result_info.player_count = is_single_mode ? 1 : system.HIDCore().GetPlayerCount();
|
||||||
is_single_mode
|
|
||||||
? 1
|
|
||||||
: static_cast<s8>(std::count_if(players.begin(), players.end() - 2,
|
|
||||||
[](const auto& player) { return player.connected; }));
|
|
||||||
|
|
||||||
result_info.selected_id = HID::Controller_NPad::IndexToNPad(std::distance(
|
result_info.selected_id = static_cast<u32>(system.HIDCore().GetFirstNpadId());
|
||||||
players.begin(), std::find_if(players.begin(), players.end(),
|
|
||||||
[](const auto& player) { return player.connected; })));
|
|
||||||
|
|
||||||
result_info.result = 0;
|
result_info.result = 0;
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,17 @@ struct InputSubsystem::Impl {
|
||||||
keyboard = std::make_shared<Keyboard>("keyboard");
|
keyboard = std::make_shared<Keyboard>("keyboard");
|
||||||
keyboard->SetMappingCallback(mapping_callback);
|
keyboard->SetMappingCallback(mapping_callback);
|
||||||
keyboard_factory = std::make_shared<InputFactory>(keyboard);
|
keyboard_factory = std::make_shared<InputFactory>(keyboard);
|
||||||
|
keyboard_output_factory = std::make_shared<OutputFactory>(keyboard);
|
||||||
Input::RegisterFactory<Input::InputDevice>(keyboard->GetEngineName(), keyboard_factory);
|
Input::RegisterFactory<Input::InputDevice>(keyboard->GetEngineName(), keyboard_factory);
|
||||||
|
Input::RegisterFactory<Input::OutputDevice>(keyboard->GetEngineName(),
|
||||||
|
keyboard_output_factory);
|
||||||
|
|
||||||
mouse = std::make_shared<Mouse>("mouse");
|
mouse = std::make_shared<Mouse>("mouse");
|
||||||
mouse->SetMappingCallback(mapping_callback);
|
mouse->SetMappingCallback(mapping_callback);
|
||||||
mouse_factory = std::make_shared<InputFactory>(mouse);
|
mouse_factory = std::make_shared<InputFactory>(mouse);
|
||||||
|
mouse_output_factory = std::make_shared<OutputFactory>(mouse);
|
||||||
Input::RegisterFactory<Input::InputDevice>(mouse->GetEngineName(), mouse_factory);
|
Input::RegisterFactory<Input::InputDevice>(mouse->GetEngineName(), mouse_factory);
|
||||||
|
Input::RegisterFactory<Input::OutputDevice>(mouse->GetEngineName(), mouse_output_factory);
|
||||||
|
|
||||||
touch_screen = std::make_shared<TouchScreen>("touch");
|
touch_screen = std::make_shared<TouchScreen>("touch");
|
||||||
touch_screen_factory = std::make_shared<InputFactory>(touch_screen);
|
touch_screen_factory = std::make_shared<InputFactory>(touch_screen);
|
||||||
|
@ -61,7 +66,9 @@ struct InputSubsystem::Impl {
|
||||||
tas_input = std::make_shared<TasInput::Tas>("tas");
|
tas_input = std::make_shared<TasInput::Tas>("tas");
|
||||||
tas_input->SetMappingCallback(mapping_callback);
|
tas_input->SetMappingCallback(mapping_callback);
|
||||||
tas_input_factory = std::make_shared<InputFactory>(tas_input);
|
tas_input_factory = std::make_shared<InputFactory>(tas_input);
|
||||||
|
tas_output_factory = std::make_shared<OutputFactory>(tas_input);
|
||||||
Input::RegisterFactory<Input::InputDevice>(tas_input->GetEngineName(), tas_input_factory);
|
Input::RegisterFactory<Input::InputDevice>(tas_input->GetEngineName(), tas_input_factory);
|
||||||
|
Input::RegisterFactory<Input::OutputDevice>(tas_input->GetEngineName(), tas_output_factory);
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
sdl = std::make_shared<SDLDriver>("sdl");
|
sdl = std::make_shared<SDLDriver>("sdl");
|
||||||
|
@ -268,7 +275,10 @@ struct InputSubsystem::Impl {
|
||||||
std::shared_ptr<InputFactory> udp_client_factory;
|
std::shared_ptr<InputFactory> udp_client_factory;
|
||||||
std::shared_ptr<InputFactory> tas_input_factory;
|
std::shared_ptr<InputFactory> tas_input_factory;
|
||||||
|
|
||||||
|
std::shared_ptr<OutputFactory> keyboard_output_factory;
|
||||||
|
std::shared_ptr<OutputFactory> mouse_output_factory;
|
||||||
std::shared_ptr<OutputFactory> gcadapter_output_factory;
|
std::shared_ptr<OutputFactory> gcadapter_output_factory;
|
||||||
|
std::shared_ptr<OutputFactory> tas_output_factory;
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
std::shared_ptr<SDLDriver> sdl;
|
std::shared_ptr<SDLDriver> sdl;
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/hid/emulated_controller.h"
|
||||||
|
#include "core/hid/hid_types.h"
|
||||||
#include "core/hle/lock.h"
|
#include "core/hle/lock.h"
|
||||||
#include "core/hle/service/hid/controllers/npad.h"
|
#include "core/hle/service/hid/controllers/npad.h"
|
||||||
#include "core/hle/service/hid/hid.h"
|
#include "core/hle/service/hid/hid.h"
|
||||||
|
@ -26,48 +28,31 @@ namespace {
|
||||||
|
|
||||||
constexpr std::size_t HANDHELD_INDEX = 8;
|
constexpr std::size_t HANDHELD_INDEX = 8;
|
||||||
|
|
||||||
constexpr std::array<std::array<bool, 4>, 8> led_patterns{{
|
void UpdateController(Core::HID::EmulatedController* controller, Core::HID::NpadType controller_type, bool connected) {
|
||||||
{true, false, false, false},
|
if (controller->IsConnected()) {
|
||||||
{true, true, false, false},
|
controller->Disconnect();
|
||||||
{true, true, true, false},
|
}
|
||||||
{true, true, true, true},
|
controller->SetNpadType(controller_type);
|
||||||
{true, false, false, true},
|
if (connected) {
|
||||||
{true, false, true, false},
|
controller->Connect();
|
||||||
{true, false, true, true},
|
|
||||||
{false, true, true, false},
|
|
||||||
}};
|
|
||||||
|
|
||||||
void UpdateController(Settings::ControllerType controller_type, std::size_t npad_index,
|
|
||||||
bool connected, Core::System& system) {
|
|
||||||
if (!system.IsPoweredOn()) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& npad =
|
|
||||||
system.ServiceManager()
|
|
||||||
.GetService<Service::HID::Hid>("hid")
|
|
||||||
->GetAppletResource()
|
|
||||||
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);
|
|
||||||
|
|
||||||
npad.UpdateControllerAt(Core::HID::EmulatedController::MapSettingsTypeToNPad(controller_type),
|
|
||||||
npad_index, connected);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the given controller type is compatible with the given parameters.
|
// Returns true if the given controller type is compatible with the given parameters.
|
||||||
bool IsControllerCompatible(Settings::ControllerType controller_type,
|
bool IsControllerCompatible(Core::HID::NpadType controller_type,
|
||||||
Core::Frontend::ControllerParameters parameters) {
|
Core::Frontend::ControllerParameters parameters) {
|
||||||
switch (controller_type) {
|
switch (controller_type) {
|
||||||
case Settings::ControllerType::ProController:
|
case Core::HID::NpadType::ProController:
|
||||||
return parameters.allow_pro_controller;
|
return parameters.allow_pro_controller;
|
||||||
case Settings::ControllerType::DualJoyconDetached:
|
case Core::HID::NpadType::JoyconDual:
|
||||||
return parameters.allow_dual_joycons;
|
return parameters.allow_dual_joycons;
|
||||||
case Settings::ControllerType::LeftJoycon:
|
case Core::HID::NpadType::JoyconLeft:
|
||||||
return parameters.allow_left_joycon;
|
return parameters.allow_left_joycon;
|
||||||
case Settings::ControllerType::RightJoycon:
|
case Core::HID::NpadType::JoyconRight:
|
||||||
return parameters.allow_right_joycon;
|
return parameters.allow_right_joycon;
|
||||||
case Settings::ControllerType::Handheld:
|
case Core::HID::NpadType::Handheld:
|
||||||
return parameters.enable_single_mode && parameters.allow_handheld;
|
return parameters.enable_single_mode && parameters.allow_handheld;
|
||||||
case Settings::ControllerType::GameCube:
|
case Core::HID::NpadType::GameCube:
|
||||||
return parameters.allow_gamecube_controller;
|
return parameters.allow_gamecube_controller;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -198,7 +183,7 @@ QtControllerSelectorDialog::QtControllerSelectorDialog(
|
||||||
connect(emulated_controllers[i], qOverload<int>(&QComboBox::currentIndexChanged),
|
connect(emulated_controllers[i], qOverload<int>(&QComboBox::currentIndexChanged),
|
||||||
[this, i](int index) {
|
[this, i](int index) {
|
||||||
UpdateDockedState(GetControllerTypeFromIndex(index, i) ==
|
UpdateDockedState(GetControllerTypeFromIndex(index, i) ==
|
||||||
Settings::ControllerType::Handheld);
|
Core::HID::NpadType::Handheld);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,17 +236,17 @@ void QtControllerSelectorDialog::ApplyConfiguration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtControllerSelectorDialog::LoadConfiguration() {
|
void QtControllerSelectorDialog::LoadConfiguration() {
|
||||||
|
const auto* handheld = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
|
for (std::size_t index = 0; index < NUM_PLAYERS; ++index) {
|
||||||
const auto connected =
|
const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
Settings::values.players.GetValue()[index].connected ||
|
const auto connected = controller->IsConnected() || (index == 0 && handheld->IsConnected());
|
||||||
(index == 0 && Settings::values.players.GetValue()[HANDHELD_INDEX].connected);
|
|
||||||
player_groupboxes[index]->setChecked(connected);
|
player_groupboxes[index]->setChecked(connected);
|
||||||
connected_controller_checkboxes[index]->setChecked(connected);
|
connected_controller_checkboxes[index]->setChecked(connected);
|
||||||
emulated_controllers[index]->setCurrentIndex(GetIndexFromControllerType(
|
emulated_controllers[index]->setCurrentIndex(
|
||||||
Settings::values.players.GetValue()[index].controller_type, index));
|
GetIndexFromControllerType(controller->GetNpadType(), index));
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateDockedState(Settings::values.players.GetValue()[HANDHELD_INDEX].connected);
|
UpdateDockedState(handheld->IsConnected());
|
||||||
|
|
||||||
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
|
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
|
||||||
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
|
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
|
||||||
|
@ -417,33 +402,32 @@ void QtControllerSelectorDialog::SetEmulatedControllers(std::size_t player_index
|
||||||
emulated_controllers[player_index]->clear();
|
emulated_controllers[player_index]->clear();
|
||||||
|
|
||||||
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
||||||
Settings::ControllerType::ProController);
|
Core::HID::NpadType::ProController);
|
||||||
emulated_controllers[player_index]->addItem(tr("Pro Controller"));
|
emulated_controllers[player_index]->addItem(tr("Pro Controller"));
|
||||||
|
|
||||||
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
||||||
Settings::ControllerType::DualJoyconDetached);
|
Core::HID::NpadType::JoyconDual);
|
||||||
emulated_controllers[player_index]->addItem(tr("Dual Joycons"));
|
emulated_controllers[player_index]->addItem(tr("Dual Joycons"));
|
||||||
|
|
||||||
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
||||||
Settings::ControllerType::LeftJoycon);
|
Core::HID::NpadType::JoyconLeft);
|
||||||
emulated_controllers[player_index]->addItem(tr("Left Joycon"));
|
emulated_controllers[player_index]->addItem(tr("Left Joycon"));
|
||||||
|
|
||||||
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
||||||
Settings::ControllerType::RightJoycon);
|
Core::HID::NpadType::JoyconRight);
|
||||||
emulated_controllers[player_index]->addItem(tr("Right Joycon"));
|
emulated_controllers[player_index]->addItem(tr("Right Joycon"));
|
||||||
|
|
||||||
if (player_index == 0) {
|
if (player_index == 0) {
|
||||||
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
||||||
Settings::ControllerType::Handheld);
|
Core::HID::NpadType::Handheld);
|
||||||
emulated_controllers[player_index]->addItem(tr("Handheld"));
|
emulated_controllers[player_index]->addItem(tr("Handheld"));
|
||||||
}
|
}
|
||||||
|
|
||||||
pairs.emplace_back(emulated_controllers[player_index]->count(),
|
pairs.emplace_back(emulated_controllers[player_index]->count(), Core::HID::NpadType::GameCube);
|
||||||
Settings::ControllerType::GameCube);
|
|
||||||
emulated_controllers[player_index]->addItem(tr("GameCube Controller"));
|
emulated_controllers[player_index]->addItem(tr("GameCube Controller"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::ControllerType QtControllerSelectorDialog::GetControllerTypeFromIndex(
|
Core::HID::NpadType QtControllerSelectorDialog::GetControllerTypeFromIndex(
|
||||||
int index, std::size_t player_index) const {
|
int index, std::size_t player_index) const {
|
||||||
const auto& pairs = index_controller_type_pairs[player_index];
|
const auto& pairs = index_controller_type_pairs[player_index];
|
||||||
|
|
||||||
|
@ -451,13 +435,13 @@ Settings::ControllerType QtControllerSelectorDialog::GetControllerTypeFromIndex(
|
||||||
[index](const auto& pair) { return pair.first == index; });
|
[index](const auto& pair) { return pair.first == index; });
|
||||||
|
|
||||||
if (it == pairs.end()) {
|
if (it == pairs.end()) {
|
||||||
return Settings::ControllerType::ProController;
|
return Core::HID::NpadType::ProController;
|
||||||
}
|
}
|
||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QtControllerSelectorDialog::GetIndexFromControllerType(Settings::ControllerType type,
|
int QtControllerSelectorDialog::GetIndexFromControllerType(Core::HID::NpadType type,
|
||||||
std::size_t player_index) const {
|
std::size_t player_index) const {
|
||||||
const auto& pairs = index_controller_type_pairs[player_index];
|
const auto& pairs = index_controller_type_pairs[player_index];
|
||||||
|
|
||||||
|
@ -481,16 +465,16 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
|
||||||
const QString stylesheet = [this, player_index] {
|
const QString stylesheet = [this, player_index] {
|
||||||
switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(),
|
switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(),
|
||||||
player_index)) {
|
player_index)) {
|
||||||
case Settings::ControllerType::ProController:
|
case Core::HID::NpadType::ProController:
|
||||||
case Settings::ControllerType::GameCube:
|
case Core::HID::NpadType::GameCube:
|
||||||
return QStringLiteral("image: url(:/controller/applet_pro_controller%0); ");
|
return QStringLiteral("image: url(:/controller/applet_pro_controller%0); ");
|
||||||
case Settings::ControllerType::DualJoyconDetached:
|
case Core::HID::NpadType::JoyconDual:
|
||||||
return QStringLiteral("image: url(:/controller/applet_dual_joycon%0); ");
|
return QStringLiteral("image: url(:/controller/applet_dual_joycon%0); ");
|
||||||
case Settings::ControllerType::LeftJoycon:
|
case Core::HID::NpadType::JoyconLeft:
|
||||||
return QStringLiteral("image: url(:/controller/applet_joycon_left%0); ");
|
return QStringLiteral("image: url(:/controller/applet_joycon_left%0); ");
|
||||||
case Settings::ControllerType::RightJoycon:
|
case Core::HID::NpadType::JoyconRight:
|
||||||
return QStringLiteral("image: url(:/controller/applet_joycon_right%0); ");
|
return QStringLiteral("image: url(:/controller/applet_joycon_right%0); ");
|
||||||
case Settings::ControllerType::Handheld:
|
case Core::HID::NpadType::Handheld:
|
||||||
return QStringLiteral("image: url(:/controller/applet_handheld%0); ");
|
return QStringLiteral("image: url(:/controller/applet_handheld%0); ");
|
||||||
default:
|
default:
|
||||||
return QString{};
|
return QString{};
|
||||||
|
@ -518,54 +502,42 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index) {
|
void QtControllerSelectorDialog::UpdateControllerState(std::size_t player_index) {
|
||||||
auto& player = Settings::values.players.GetValue()[player_index];
|
auto* controller = system.HIDCore().GetEmulatedControllerByIndex(player_index);
|
||||||
|
|
||||||
const auto controller_type = GetControllerTypeFromIndex(
|
const auto controller_type = GetControllerTypeFromIndex(
|
||||||
emulated_controllers[player_index]->currentIndex(), player_index);
|
emulated_controllers[player_index]->currentIndex(), player_index);
|
||||||
const auto player_connected = player_groupboxes[player_index]->isChecked() &&
|
const auto player_connected = player_groupboxes[player_index]->isChecked() &&
|
||||||
controller_type != Settings::ControllerType::Handheld;
|
controller_type != Core::HID::NpadType::Handheld;
|
||||||
|
|
||||||
if (player.controller_type == controller_type && player.connected == player_connected) {
|
if (controller->GetNpadType() == controller_type &&
|
||||||
|
controller->IsConnected() == player_connected) {
|
||||||
// Set vibration devices in the event that the input device has changed.
|
// Set vibration devices in the event that the input device has changed.
|
||||||
ConfigureVibration::SetVibrationDevices(player_index);
|
ConfigureVibration::SetVibrationDevices(player_index);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect the controller first.
|
// Disconnect the controller first.
|
||||||
UpdateController(controller_type, player_index, false, system);
|
UpdateController(controller, controller_type, false);
|
||||||
|
|
||||||
player.controller_type = controller_type;
|
|
||||||
player.connected = player_connected;
|
|
||||||
|
|
||||||
ConfigureVibration::SetVibrationDevices(player_index);
|
ConfigureVibration::SetVibrationDevices(player_index);
|
||||||
|
|
||||||
// Handheld
|
// Handheld
|
||||||
if (player_index == 0) {
|
if (player_index == 0) {
|
||||||
auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX];
|
if (controller_type == Core::HID::NpadType::Handheld) {
|
||||||
if (controller_type == Settings::ControllerType::Handheld) {
|
auto* handheld =
|
||||||
handheld = player;
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
UpdateController(handheld, Core::HID::NpadType::Handheld,
|
||||||
|
player_groupboxes[player_index]->isChecked());
|
||||||
}
|
}
|
||||||
handheld.connected = player_groupboxes[player_index]->isChecked() &&
|
|
||||||
controller_type == Settings::ControllerType::Handheld;
|
|
||||||
UpdateController(Settings::ControllerType::Handheld, 8, handheld.connected, system);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!player.connected) {
|
UpdateController(controller, controller_type, player_connected);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This emulates a delay between disconnecting and reconnecting controllers as some games
|
|
||||||
// do not respond to a change in controller type if it was instantaneous.
|
|
||||||
using namespace std::chrono_literals;
|
|
||||||
std::this_thread::sleep_for(60ms);
|
|
||||||
|
|
||||||
UpdateController(controller_type, player_index, player_connected, system);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtControllerSelectorDialog::UpdateLEDPattern(std::size_t player_index) {
|
void QtControllerSelectorDialog::UpdateLEDPattern(std::size_t player_index) {
|
||||||
if (!player_groupboxes[player_index]->isChecked() ||
|
if (!player_groupboxes[player_index]->isChecked() ||
|
||||||
GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(),
|
GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(),
|
||||||
player_index) == Settings::ControllerType::Handheld) {
|
player_index) == Core::HID::NpadType::Handheld) {
|
||||||
led_patterns_boxes[player_index][0]->setChecked(false);
|
led_patterns_boxes[player_index][0]->setChecked(false);
|
||||||
led_patterns_boxes[player_index][1]->setChecked(false);
|
led_patterns_boxes[player_index][1]->setChecked(false);
|
||||||
led_patterns_boxes[player_index][2]->setChecked(false);
|
led_patterns_boxes[player_index][2]->setChecked(false);
|
||||||
|
@ -573,10 +545,12 @@ void QtControllerSelectorDialog::UpdateLEDPattern(std::size_t player_index) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
led_patterns_boxes[player_index][0]->setChecked(led_patterns[player_index][0]);
|
const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(player_index);
|
||||||
led_patterns_boxes[player_index][1]->setChecked(led_patterns[player_index][1]);
|
const auto led_pattern = controller->GetLedPattern();
|
||||||
led_patterns_boxes[player_index][2]->setChecked(led_patterns[player_index][2]);
|
led_patterns_boxes[player_index][0]->setChecked(led_pattern.position1);
|
||||||
led_patterns_boxes[player_index][3]->setChecked(led_patterns[player_index][3]);
|
led_patterns_boxes[player_index][1]->setChecked(led_pattern.position2);
|
||||||
|
led_patterns_boxes[player_index][2]->setChecked(led_pattern.position3);
|
||||||
|
led_patterns_boxes[player_index][3]->setChecked(led_pattern.position4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtControllerSelectorDialog::UpdateBorderColor(std::size_t player_index) {
|
void QtControllerSelectorDialog::UpdateBorderColor(std::size_t player_index) {
|
||||||
|
@ -656,10 +630,9 @@ void QtControllerSelectorDialog::DisableUnsupportedPlayers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t index = max_supported_players; index < NUM_PLAYERS; ++index) {
|
for (std::size_t index = max_supported_players; index < NUM_PLAYERS; ++index) {
|
||||||
|
auto* controller = system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||||
// Disconnect any unsupported players here and disable or hide them if applicable.
|
// Disconnect any unsupported players here and disable or hide them if applicable.
|
||||||
Settings::values.players.GetValue()[index].connected = false;
|
UpdateController(controller, controller->GetNpadType(), false);
|
||||||
UpdateController(Settings::values.players.GetValue()[index].controller_type, index, false,
|
|
||||||
system);
|
|
||||||
// Hide the player widgets when max_supported_controllers is less than or equal to 4.
|
// Hide the player widgets when max_supported_controllers is less than or equal to 4.
|
||||||
if (max_supported_players <= 4) {
|
if (max_supported_players <= 4) {
|
||||||
player_widgets[index]->hide();
|
player_widgets[index]->hide();
|
||||||
|
|
|
@ -23,10 +23,6 @@ namespace InputCommon {
|
||||||
class InputSubsystem;
|
class InputSubsystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Settings {
|
|
||||||
enum class ControllerType;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class QtControllerSelectorDialog;
|
class QtControllerSelectorDialog;
|
||||||
}
|
}
|
||||||
|
@ -35,6 +31,10 @@ namespace Core {
|
||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Core::HID {
|
||||||
|
enum class NpadType : u8;
|
||||||
|
}
|
||||||
|
|
||||||
class QtControllerSelectorDialog final : public QDialog {
|
class QtControllerSelectorDialog final : public QDialog {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -74,10 +74,10 @@ private:
|
||||||
void SetEmulatedControllers(std::size_t player_index);
|
void SetEmulatedControllers(std::size_t player_index);
|
||||||
|
|
||||||
// Gets the Controller Type for a given controller combobox index per player.
|
// Gets the Controller Type for a given controller combobox index per player.
|
||||||
Settings::ControllerType GetControllerTypeFromIndex(int index, std::size_t player_index) const;
|
Core::HID::NpadType GetControllerTypeFromIndex(int index, std::size_t player_index) const;
|
||||||
|
|
||||||
// Gets the controller combobox index for a given Controller Type per player.
|
// Gets the controller combobox index for a given Controller Type per player.
|
||||||
int GetIndexFromControllerType(Settings::ControllerType type, std::size_t player_index) const;
|
int GetIndexFromControllerType(Core::HID::NpadType type, std::size_t player_index) const;
|
||||||
|
|
||||||
// Updates the controller icons per player.
|
// Updates the controller icons per player.
|
||||||
void UpdateControllerIcon(std::size_t player_index);
|
void UpdateControllerIcon(std::size_t player_index);
|
||||||
|
@ -139,7 +139,7 @@ private:
|
||||||
std::array<QComboBox*, NUM_PLAYERS> emulated_controllers;
|
std::array<QComboBox*, NUM_PLAYERS> emulated_controllers;
|
||||||
|
|
||||||
/// Pairs of emulated controller index and Controller Type enum per player.
|
/// Pairs of emulated controller index and Controller Type enum per player.
|
||||||
std::array<std::vector<std::pair<int, Settings::ControllerType>>, NUM_PLAYERS>
|
std::array<std::vector<std::pair<int, Core::HID::NpadType>>, NUM_PLAYERS>
|
||||||
index_controller_type_pairs;
|
index_controller_type_pairs;
|
||||||
|
|
||||||
// Labels representing the number of connected controllers
|
// Labels representing the number of connected controllers
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/hid/emulated_controller.h"
|
||||||
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hid/hid_types.h"
|
#include "core/hid/hid_types.h"
|
||||||
#include "core/hid/input_interpreter.h"
|
#include "core/hid/input_interpreter.h"
|
||||||
#include "ui_qt_software_keyboard.h"
|
#include "ui_qt_software_keyboard.h"
|
||||||
|
@ -796,9 +798,10 @@ void QtSoftwareKeyboardDialog::SetTextDrawType() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtSoftwareKeyboardDialog::SetControllerImage() {
|
void QtSoftwareKeyboardDialog::SetControllerImage() {
|
||||||
const auto controller_type = Settings::values.players.GetValue()[8].connected
|
const auto* handheld = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
? Settings::values.players.GetValue()[8].controller_type
|
const auto* player_1 = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
: Settings::values.players.GetValue()[0].controller_type;
|
const auto controller_type =
|
||||||
|
handheld->IsConnected() ? handheld->GetNpadType() : player_1->GetNpadType();
|
||||||
|
|
||||||
const QString theme = [] {
|
const QString theme = [] {
|
||||||
if (QIcon::themeName().contains(QStringLiteral("dark")) ||
|
if (QIcon::themeName().contains(QStringLiteral("dark")) ||
|
||||||
|
@ -810,8 +813,8 @@ void QtSoftwareKeyboardDialog::SetControllerImage() {
|
||||||
}();
|
}();
|
||||||
|
|
||||||
switch (controller_type) {
|
switch (controller_type) {
|
||||||
case Settings::ControllerType::ProController:
|
case Core::HID::NpadType::ProController:
|
||||||
case Settings::ControllerType::GameCube:
|
case Core::HID::NpadType::GameCube:
|
||||||
ui->icon_controller->setStyleSheet(
|
ui->icon_controller->setStyleSheet(
|
||||||
QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
|
QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
|
||||||
ui->icon_controller_shift->setStyleSheet(
|
ui->icon_controller_shift->setStyleSheet(
|
||||||
|
@ -819,7 +822,7 @@ void QtSoftwareKeyboardDialog::SetControllerImage() {
|
||||||
ui->icon_controller_num->setStyleSheet(
|
ui->icon_controller_num->setStyleSheet(
|
||||||
QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
|
QStringLiteral("image: url(:/overlay/controller_pro%1.png);").arg(theme));
|
||||||
break;
|
break;
|
||||||
case Settings::ControllerType::DualJoyconDetached:
|
case Core::HID::NpadType::JoyconDual:
|
||||||
ui->icon_controller->setStyleSheet(
|
ui->icon_controller->setStyleSheet(
|
||||||
QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
|
QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
|
||||||
ui->icon_controller_shift->setStyleSheet(
|
ui->icon_controller_shift->setStyleSheet(
|
||||||
|
@ -827,7 +830,7 @@ void QtSoftwareKeyboardDialog::SetControllerImage() {
|
||||||
ui->icon_controller_num->setStyleSheet(
|
ui->icon_controller_num->setStyleSheet(
|
||||||
QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
|
QStringLiteral("image: url(:/overlay/controller_dual_joycon%1.png);").arg(theme));
|
||||||
break;
|
break;
|
||||||
case Settings::ControllerType::LeftJoycon:
|
case Core::HID::NpadType::JoyconLeft:
|
||||||
ui->icon_controller->setStyleSheet(
|
ui->icon_controller->setStyleSheet(
|
||||||
QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
|
QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
|
||||||
.arg(theme));
|
.arg(theme));
|
||||||
|
@ -838,7 +841,7 @@ void QtSoftwareKeyboardDialog::SetControllerImage() {
|
||||||
QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
|
QStringLiteral("image: url(:/overlay/controller_single_joycon_left%1.png);")
|
||||||
.arg(theme));
|
.arg(theme));
|
||||||
break;
|
break;
|
||||||
case Settings::ControllerType::RightJoycon:
|
case Core::HID::NpadType::JoyconRight:
|
||||||
ui->icon_controller->setStyleSheet(
|
ui->icon_controller->setStyleSheet(
|
||||||
QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
|
QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
|
||||||
.arg(theme));
|
.arg(theme));
|
||||||
|
@ -849,7 +852,7 @@ void QtSoftwareKeyboardDialog::SetControllerImage() {
|
||||||
QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
|
QStringLiteral("image: url(:/overlay/controller_single_joycon_right%1.png);")
|
||||||
.arg(theme));
|
.arg(theme));
|
||||||
break;
|
break;
|
||||||
case Settings::ControllerType::Handheld:
|
case Core::HID::NpadType::Handheld:
|
||||||
ui->icon_controller->setStyleSheet(
|
ui->icon_controller->setStyleSheet(
|
||||||
QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
|
QStringLiteral("image: url(:/overlay/controller_handheld%1.png);").arg(theme));
|
||||||
ui->icon_controller_shift->setStyleSheet(
|
ui->icon_controller_shift->setStyleSheet(
|
||||||
|
|
|
@ -211,8 +211,10 @@ void ConfigureInput::RetranslateUI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureInput::LoadConfiguration() {
|
void ConfigureInput::LoadConfiguration() {
|
||||||
|
const auto* handheld = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
|
||||||
LoadPlayerControllerIndices();
|
LoadPlayerControllerIndices();
|
||||||
UpdateDockedState(Settings::values.players.GetValue()[8].connected);
|
UpdateDockedState(handheld->IsConnected());
|
||||||
|
|
||||||
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
|
ui->vibrationGroup->setChecked(Settings::values.vibration_enabled.GetValue());
|
||||||
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
|
ui->motionGroup->setChecked(Settings::values.motion_enabled.GetValue());
|
||||||
|
@ -220,9 +222,16 @@ void ConfigureInput::LoadConfiguration() {
|
||||||
|
|
||||||
void ConfigureInput::LoadPlayerControllerIndices() {
|
void ConfigureInput::LoadPlayerControllerIndices() {
|
||||||
for (std::size_t i = 0; i < player_connected.size(); ++i) {
|
for (std::size_t i = 0; i < player_connected.size(); ++i) {
|
||||||
const auto connected = Settings::values.players.GetValue()[i].connected ||
|
if (i == 0) {
|
||||||
(i == 0 && Settings::values.players.GetValue()[8].connected);
|
auto* handheld =
|
||||||
player_connected[i]->setChecked(connected);
|
system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
if (handheld->IsConnected()) {
|
||||||
|
player_connected[i]->setChecked(true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto* controller = system.HIDCore().GetEmulatedControllerByIndex(i);
|
||||||
|
player_connected[i]->setChecked(controller->IsConnected());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,8 +104,8 @@ void PlayerControlPreview::UpdateColors() {
|
||||||
colors.left = colors.primary;
|
colors.left = colors.primary;
|
||||||
colors.right = colors.primary;
|
colors.right = colors.primary;
|
||||||
// Possible alternative to set colors from settings
|
// Possible alternative to set colors from settings
|
||||||
// colors.left = QColor(Settings::values.players.GetValue()[player_index].body_color_left);
|
// colors.left = QColor(controller->GetColors().left.body);
|
||||||
// colors.right = QColor(Settings::values.players.GetValue()[player_index].body_color_right);
|
// colors.right = QColor(controller->GetColors().right.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerControlPreview::ResetInputs() {
|
void PlayerControlPreview::ResetInputs() {
|
||||||
|
|
|
@ -832,15 +832,16 @@ void GMainWindow::InitializeWidgets() {
|
||||||
dock_status_button->setFocusPolicy(Qt::NoFocus);
|
dock_status_button->setFocusPolicy(Qt::NoFocus);
|
||||||
connect(dock_status_button, &QPushButton::clicked, [&] {
|
connect(dock_status_button, &QPushButton::clicked, [&] {
|
||||||
const bool is_docked = Settings::values.use_docked_mode.GetValue();
|
const bool is_docked = Settings::values.use_docked_mode.GetValue();
|
||||||
auto& controller_type = Settings::values.players.GetValue()[0].controller_type;
|
auto* player_1 = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||||
|
auto* handheld = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||||
|
|
||||||
if (!is_docked && controller_type == Settings::ControllerType::Handheld) {
|
if (!is_docked && handheld->IsConnected()) {
|
||||||
QMessageBox::warning(this, tr("Invalid config detected"),
|
QMessageBox::warning(this, tr("Invalid config detected"),
|
||||||
tr("Handheld controller can't be used on docked mode. Pro "
|
tr("Handheld controller can't be used on docked mode. Pro "
|
||||||
"controller will be selected."));
|
"controller will be selected."));
|
||||||
controller_type = Settings::ControllerType::ProController;
|
handheld->Disconnect();
|
||||||
ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get(), *system);
|
player_1->SetNpadType(Core::HID::NpadType::ProController);
|
||||||
configure_dialog.ApplyConfiguration();
|
player_1->Connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::values.use_docked_mode.SetValue(!is_docked);
|
Settings::values.use_docked_mode.SetValue(!is_docked);
|
||||||
|
|
Loading…
Reference in a new issue