parent
95cf66b655
commit
b5e72de753
|
@ -5,16 +5,16 @@
|
|||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/frontend/applets/controller.h"
|
||||
#include "core/hle/service/hid/controllers/npad.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/sm/sm.h"
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/hid_core.h"
|
||||
#include "core/hid/hid_types.h"
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
||||
ControllerApplet::~ControllerApplet() = default;
|
||||
|
||||
DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_)
|
||||
: service_manager{service_manager_} {}
|
||||
DefaultControllerApplet::DefaultControllerApplet(HID::HIDCore& hid_core_)
|
||||
: hid_core{hid_core_} {}
|
||||
|
||||
DefaultControllerApplet::~DefaultControllerApplet() = default;
|
||||
|
||||
|
@ -22,24 +22,20 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
|
|||
const ControllerParameters& parameters) const {
|
||||
LOG_INFO(Service_HID, "called, deducing the best configuration based on the given parameters!");
|
||||
|
||||
auto& npad =
|
||||
service_manager.GetService<Service::HID::Hid>("hid")
|
||||
->GetAppletResource()
|
||||
->GetController<Service::HID::Controller_NPad>(Service::HID::HidController::NPad);
|
||||
|
||||
auto& players = Settings::values.players.GetValue();
|
||||
|
||||
const std::size_t min_supported_players =
|
||||
parameters.enable_single_mode ? 1 : parameters.min_players;
|
||||
|
||||
// Disconnect Handheld first.
|
||||
npad.DisconnectNpadAtIndex(8);
|
||||
auto* handheld =hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||
handheld->Disconnect();
|
||||
|
||||
// Deduce the best configuration based on the input parameters.
|
||||
for (std::size_t index = 0; index < players.size() - 2; ++index) {
|
||||
for (std::size_t index = 0; index < hid_core.available_controllers - 2; ++index) {
|
||||
auto* controller = hid_core.GetEmulatedControllerByIndex(index);
|
||||
|
||||
// First, disconnect all controllers regardless of the value of keep_controllers_connected.
|
||||
// This makes it easy to connect the desired controllers.
|
||||
npad.DisconnectNpadAtIndex(index);
|
||||
controller->Disconnect();
|
||||
|
||||
// Only connect the minimum number of required players.
|
||||
if (index >= min_supported_players) {
|
||||
|
@ -49,32 +45,27 @@ void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callb
|
|||
// Connect controllers based on the following priority list from highest to lowest priority:
|
||||
// Pro Controller -> Dual Joycons -> Left Joycon/Right Joycon -> Handheld
|
||||
if (parameters.allow_pro_controller) {
|
||||
npad.AddNewControllerAt(Core::HID::EmulatedController::MapSettingsTypeToNPad(
|
||||
Settings::ControllerType::ProController),
|
||||
index);
|
||||
controller->SetNpadType(Core::HID::NpadType::ProController);
|
||||
controller->Connect();
|
||||
} else if (parameters.allow_dual_joycons) {
|
||||
npad.AddNewControllerAt(Core::HID::EmulatedController::MapSettingsTypeToNPad(
|
||||
Settings::ControllerType::DualJoyconDetached),
|
||||
index);
|
||||
controller->SetNpadType(Core::HID::NpadType::JoyconDual);
|
||||
controller->Connect();
|
||||
} else if (parameters.allow_left_joycon && parameters.allow_right_joycon) {
|
||||
// Assign left joycons to even player indices and right joycons to odd player indices.
|
||||
// We do this since Captain Toad Treasure Tracker expects a left joycon for Player 1 and
|
||||
// a right Joycon for Player 2 in 2 Player Assist mode.
|
||||
if (index % 2 == 0) {
|
||||
npad.AddNewControllerAt(Core::HID::EmulatedController::MapSettingsTypeToNPad(
|
||||
Settings::ControllerType::LeftJoycon),
|
||||
index);
|
||||
controller->SetNpadType(Core::HID::NpadType::JoyconLeft);
|
||||
controller->Connect();
|
||||
} else {
|
||||
npad.AddNewControllerAt(Core::HID::EmulatedController::MapSettingsTypeToNPad(
|
||||
Settings::ControllerType::RightJoycon),
|
||||
index);
|
||||
controller->SetNpadType(Core::HID::NpadType::JoyconRight);
|
||||
controller->Connect();
|
||||
}
|
||||
} else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld &&
|
||||
!Settings::values.use_docked_mode.GetValue()) {
|
||||
// We should *never* reach here under any normal circumstances.
|
||||
npad.AddNewControllerAt(Core::HID::EmulatedController::MapSettingsTypeToNPad(
|
||||
Settings::ControllerType::Handheld),
|
||||
index);
|
||||
controller->SetNpadType(Core::HID::NpadType::Handheld);
|
||||
controller->Connect();
|
||||
} else {
|
||||
UNREACHABLE_MSG("Unable to add a new controller based on the given parameters!");
|
||||
}
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Service::SM {
|
||||
class ServiceManager;
|
||||
namespace Core::HID {
|
||||
class HIDCore;
|
||||
}
|
||||
|
||||
namespace Core::Frontend {
|
||||
|
@ -44,14 +44,14 @@ public:
|
|||
|
||||
class DefaultControllerApplet final : public ControllerApplet {
|
||||
public:
|
||||
explicit DefaultControllerApplet(Service::SM::ServiceManager& service_manager_);
|
||||
explicit DefaultControllerApplet(HID::HIDCore& hid_core_);
|
||||
~DefaultControllerApplet() override;
|
||||
|
||||
void ReconfigureControllers(std::function<void()> callback,
|
||||
const ControllerParameters& parameters) const override;
|
||||
|
||||
private:
|
||||
Service::SM::ServiceManager& service_manager;
|
||||
HID::HIDCore& hid_core;
|
||||
};
|
||||
|
||||
} // namespace Core::Frontend
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "core/hid/emulated_console.h"
|
||||
#include "core/hid/input_converter.h"
|
||||
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "core/hid/emulated_controller.h"
|
||||
#include "core/hid/input_converter.h"
|
||||
|
||||
|
@ -635,6 +633,9 @@ void EmulatedController::SetBattery(Input::CallbackStatus callback, std::size_t
|
|||
}
|
||||
|
||||
bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) {
|
||||
if (device_index >= output_devices.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!output_devices[device_index]) {
|
||||
return false;
|
||||
}
|
||||
|
@ -659,6 +660,9 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
|
|||
}
|
||||
|
||||
bool EmulatedController::TestVibration(std::size_t device_index) {
|
||||
if (device_index >= output_devices.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!output_devices[device_index]) {
|
||||
return false;
|
||||
}
|
||||
|
@ -733,7 +737,9 @@ bool EmulatedController::IsConnected(bool temporary) const {
|
|||
}
|
||||
|
||||
bool EmulatedController::IsVibrationEnabled() const {
|
||||
return is_vibration_enabled;
|
||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||
return player.vibration_enabled;
|
||||
}
|
||||
|
||||
NpadIdType EmulatedController::GetNpadIdType() const {
|
||||
|
|
|
@ -337,7 +337,6 @@ private:
|
|||
bool is_connected{false};
|
||||
bool temporary_is_connected{false};
|
||||
bool is_configuring{false};
|
||||
bool is_vibration_enabled{true};
|
||||
f32 motion_sensitivity{0.01f};
|
||||
|
||||
ButtonParams button_params;
|
||||
|
|
|
@ -113,7 +113,7 @@ NpadStyleTag HIDCore::GetSupportedStyleTag() const {
|
|||
|
||||
s8 HIDCore::GetPlayerCount() const {
|
||||
s8 active_players = 0;
|
||||
for (std::size_t player_index = 0; player_index < 8; player_index++) {
|
||||
for (std::size_t player_index = 0; player_index < available_controllers -2; player_index++) {
|
||||
const auto* controller = GetEmulatedControllerByIndex(player_index);
|
||||
if (controller->IsConnected()) {
|
||||
active_players++;
|
||||
|
@ -123,7 +123,7 @@ s8 HIDCore::GetPlayerCount() const {
|
|||
}
|
||||
|
||||
NpadIdType HIDCore::GetFirstNpadId() const {
|
||||
for (std::size_t player_index = 0; player_index < 10; player_index++) {
|
||||
for (std::size_t player_index = 0; player_index < available_controllers; player_index++) {
|
||||
const auto* controller = GetEmulatedControllerByIndex(player_index);
|
||||
if (controller->IsConnected()) {
|
||||
return controller->GetNpadIdType();
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
/// Removes all callbacks from input common
|
||||
void UnloadInputDevices();
|
||||
|
||||
/// Number of emulated controllers
|
||||
const std::size_t available_controllers{10};
|
||||
|
||||
private:
|
||||
std::unique_ptr<EmulatedController> player_1;
|
||||
std::unique_ptr<EmulatedController> player_2;
|
||||
|
|
|
@ -231,7 +231,7 @@ void AppletManager::SetDefaultAppletFrontendSet() {
|
|||
void AppletManager::SetDefaultAppletsIfMissing() {
|
||||
if (frontend.controller == nullptr) {
|
||||
frontend.controller =
|
||||
std::make_unique<Core::Frontend::DefaultControllerApplet>(system.ServiceManager());
|
||||
std::make_unique<Core::Frontend::DefaultControllerApplet>(system.HIDCore());
|
||||
}
|
||||
|
||||
if (frontend.error == nullptr) {
|
||||
|
|
|
@ -608,15 +608,15 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing
|
|||
sixaxis_fullkey_state.sampling_number =
|
||||
npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
sixaxis_handheld_state.sampling_number =
|
||||
npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
npad.sixaxis_handheld_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
sixaxis_dual_left_state.sampling_number =
|
||||
npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
npad.sixaxis_dual_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
sixaxis_dual_right_state.sampling_number =
|
||||
npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
npad.sixaxis_dual_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
sixaxis_left_lifo_state.sampling_number =
|
||||
npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
npad.sixaxis_left_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
sixaxis_right_lifo_state.sampling_number =
|
||||
npad.sixaxis_fullkey_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
npad.sixaxis_right_lifo.ReadCurrentEntry().state.sampling_number + 1;
|
||||
|
||||
npad.sixaxis_fullkey_lifo.WriteNextEntry(sixaxis_fullkey_state);
|
||||
npad.sixaxis_handheld_lifo.WriteNextEntry(sixaxis_handheld_state);
|
||||
|
|
|
@ -342,7 +342,7 @@ private:
|
|||
INSERT_PADDING_BYTES(0x4);
|
||||
};
|
||||
|
||||
// This is nn::hid::server::NpadGcTriggerState
|
||||
// This is nn::hid::system::AppletFooterUiType
|
||||
enum class AppletFooterUiType : u8 {
|
||||
None = 0,
|
||||
HandheldNone = 1,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_shared_memory.h"
|
||||
|
@ -34,7 +33,7 @@
|
|||
namespace Service::HID {
|
||||
|
||||
// Updating period for each HID device.
|
||||
// Period time is obtained by measuring the number of samples in a second
|
||||
// Period time is obtained by measuring the number of samples in a second on HW using a homebrew
|
||||
constexpr auto pad_update_ns = std::chrono::nanoseconds{4 * 1000 * 1000}; // (4ms, 250Hz)
|
||||
constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
|
||||
constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
|
||||
|
|
|
@ -268,6 +268,8 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
|
|||
SetButton(identifier, touch_id, true);
|
||||
continue;
|
||||
}
|
||||
SetAxis(identifier, touch_id * 2, 0);
|
||||
SetAxis(identifier, touch_id * 2 + 1, 0);
|
||||
SetButton(identifier, touch_id, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright 2021 yuzu Emulator Project
|
||||
// Copyright 2018 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
// Copyright 2017 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
|
|
@ -87,25 +87,30 @@ struct InputSubsystem::Impl {
|
|||
|
||||
void Shutdown() {
|
||||
Input::UnregisterFactory<Input::InputDevice>(keyboard->GetEngineName());
|
||||
Input::UnregisterFactory<Input::OutputDevice>(keyboard->GetEngineName());
|
||||
keyboard.reset();
|
||||
|
||||
Input::UnregisterFactory<Input::InputDevice>(mouse->GetEngineName());
|
||||
Input::UnregisterFactory<Input::OutputDevice>(mouse->GetEngineName());
|
||||
mouse.reset();
|
||||
|
||||
Input::UnregisterFactory<Input::InputDevice>(touch_screen->GetEngineName());
|
||||
touch_screen.reset();
|
||||
|
||||
Input::UnregisterFactory<Input::InputDevice>(gcadapter->GetEngineName());
|
||||
Input::UnregisterFactory<Input::OutputDevice>(gcadapter->GetEngineName());
|
||||
gcadapter.reset();
|
||||
|
||||
Input::UnregisterFactory<Input::InputDevice>(udp_client->GetEngineName());
|
||||
udp_client.reset();
|
||||
|
||||
Input::UnregisterFactory<Input::InputDevice>(tas_input->GetEngineName());
|
||||
Input::UnregisterFactory<Input::OutputDevice>(tas_input->GetEngineName());
|
||||
tas_input.reset();
|
||||
|
||||
#ifdef HAVE_SDL2
|
||||
Input::UnregisterFactory<Input::InputDevice>(sdl->GetEngineName());
|
||||
Input::UnregisterFactory<Input::OutputDevice>(sdl->GetEngineName());
|
||||
sdl.reset();
|
||||
#endif
|
||||
|
||||
|
@ -124,8 +129,6 @@ struct InputSubsystem::Impl {
|
|||
devices.insert(devices.end(), mouse_devices.begin(), mouse_devices.end());
|
||||
auto gcadapter_devices = gcadapter->GetInputDevices();
|
||||
devices.insert(devices.end(), gcadapter_devices.begin(), gcadapter_devices.end());
|
||||
auto tas_input_devices = tas_input->GetInputDevices();
|
||||
devices.insert(devices.end(), tas_input_devices.begin(), tas_input_devices.end());
|
||||
#ifdef HAVE_SDL2
|
||||
auto sdl_devices = sdl->GetInputDevices();
|
||||
devices.insert(devices.end(), sdl_devices.begin(), sdl_devices.end());
|
||||
|
|
Reference in New Issue