diff options
Diffstat (limited to 'src/core/frontend')
-rw-r--r-- | src/core/frontend/applets/controller.cpp | 81 | ||||
-rw-r--r-- | src/core/frontend/applets/controller.h | 56 | ||||
-rw-r--r-- | src/core/frontend/emu_window.h | 4 | ||||
-rw-r--r-- | src/core/frontend/framebuffer_layout.h | 1 | ||||
-rw-r--r-- | src/core/frontend/input.h | 25 |
5 files changed, 161 insertions, 6 deletions
diff --git a/src/core/frontend/applets/controller.cpp b/src/core/frontend/applets/controller.cpp new file mode 100644 index 000000000..c5d65f2d0 --- /dev/null +++ b/src/core/frontend/applets/controller.cpp @@ -0,0 +1,81 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#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" + +namespace Core::Frontend { + +ControllerApplet::~ControllerApplet() = default; + +DefaultControllerApplet::DefaultControllerApplet(Service::SM::ServiceManager& service_manager_) + : service_manager{service_manager_} {} + +DefaultControllerApplet::~DefaultControllerApplet() = default; + +void DefaultControllerApplet::ReconfigureControllers(std::function<void()> callback, + 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; + + const std::size_t min_supported_players = + parameters.enable_single_mode ? 1 : parameters.min_players; + + // Disconnect Handheld first. + npad.DisconnectNPadAtIndex(8); + + // Deduce the best configuration based on the input parameters. + for (std::size_t index = 0; index < players.size() - 2; ++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); + + // Only connect the minimum number of required players. + if (index >= min_supported_players) { + continue; + } + + // 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( + npad.MapSettingsTypeToNPad(Settings::ControllerType::ProController), index); + } else if (parameters.allow_dual_joycons) { + npad.AddNewControllerAt( + npad.MapSettingsTypeToNPad(Settings::ControllerType::DualJoyconDetached), index); + } 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( + npad.MapSettingsTypeToNPad(Settings::ControllerType::LeftJoycon), index); + } else { + npad.AddNewControllerAt( + npad.MapSettingsTypeToNPad(Settings::ControllerType::RightJoycon), index); + } + } else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld && + !Settings::values.use_docked_mode) { + // We should *never* reach here under any normal circumstances. + npad.AddNewControllerAt(npad.MapSettingsTypeToNPad(Settings::ControllerType::Handheld), + index); + } else { + UNREACHABLE_MSG("Unable to add a new controller based on the given parameters!"); + } + } + + callback(); +} + +} // namespace Core::Frontend diff --git a/src/core/frontend/applets/controller.h b/src/core/frontend/applets/controller.h new file mode 100644 index 000000000..3e49cdbb9 --- /dev/null +++ b/src/core/frontend/applets/controller.h @@ -0,0 +1,56 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <functional> + +#include "common/common_types.h" + +namespace Service::SM { +class ServiceManager; +} + +namespace Core::Frontend { + +using BorderColor = std::array<u8, 4>; +using ExplainText = std::array<char, 0x81>; + +struct ControllerParameters { + s8 min_players{}; + s8 max_players{}; + bool keep_controllers_connected{}; + bool enable_single_mode{}; + bool enable_border_color{}; + std::vector<BorderColor> border_colors{}; + bool enable_explain_text{}; + std::vector<ExplainText> explain_text{}; + bool allow_pro_controller{}; + bool allow_handheld{}; + bool allow_dual_joycons{}; + bool allow_left_joycon{}; + bool allow_right_joycon{}; +}; + +class ControllerApplet { +public: + virtual ~ControllerApplet(); + + virtual void ReconfigureControllers(std::function<void()> callback, + ControllerParameters parameters) const = 0; +}; + +class DefaultControllerApplet final : public ControllerApplet { +public: + explicit DefaultControllerApplet(Service::SM::ServiceManager& service_manager_); + ~DefaultControllerApplet() override; + + void ReconfigureControllers(std::function<void()> callback, + ControllerParameters parameters) const override; + +private: + Service::SM::ServiceManager& service_manager; +}; + +} // namespace Core::Frontend diff --git a/src/core/frontend/emu_window.h b/src/core/frontend/emu_window.h index 13aa14934..3e8780243 100644 --- a/src/core/frontend/emu_window.h +++ b/src/core/frontend/emu_window.h @@ -39,7 +39,7 @@ public: class Scoped { public: - explicit Scoped(GraphicsContext& context_) : context(context_) { + [[nodiscard]] explicit Scoped(GraphicsContext& context_) : context(context_) { context.MakeCurrent(); } ~Scoped() { @@ -52,7 +52,7 @@ public: /// Calls MakeCurrent on the context and calls DoneCurrent when the scope for the returned value /// ends - Scoped Acquire() { + [[nodiscard]] Scoped Acquire() { return Scoped{*this}; } }; diff --git a/src/core/frontend/framebuffer_layout.h b/src/core/frontend/framebuffer_layout.h index 91ecc30ab..e2e3bbbb3 100644 --- a/src/core/frontend/framebuffer_layout.h +++ b/src/core/frontend/framebuffer_layout.h @@ -4,6 +4,7 @@ #pragma once +#include "common/common_types.h" #include "common/math_util.h" namespace Layout { diff --git a/src/core/frontend/input.h b/src/core/frontend/input.h index 2b098b7c6..277b70e53 100644 --- a/src/core/frontend/input.h +++ b/src/core/frontend/input.h @@ -33,6 +33,9 @@ public: virtual bool GetAnalogDirectionStatus(AnalogDirection direction) const { return {}; } + virtual bool SetRumblePlay(f32 amp_high, f32 amp_low, f32 freq_high, f32 freq_low) const { + return {}; + } }; /// An abstract class template for a factory that can create input devices. @@ -119,11 +122,11 @@ using ButtonDevice = InputDevice<bool>; using AnalogDevice = InputDevice<std::tuple<float, float>>; /** - * A motion device is an input device that returns a tuple of accelerometer state vector and - * gyroscope state vector. + * A motion status is an object that returns a tuple of accelerometer state vector, + * gyroscope state vector, rotation state vector and orientation state matrix. * * For both vectors: - * x+ is the same direction as LEFT on D-pad. + * x+ is the same direction as RIGHT on D-pad. * y+ is normal to the touch screen, pointing outward. * z+ is the same direction as UP on D-pad. * @@ -133,8 +136,22 @@ using AnalogDevice = InputDevice<std::tuple<float, float>>; * For gyroscope state vector: * Orientation is determined by right-hand rule. * Units: deg/sec + * + * For rotation state vector + * Units: rotations + * + * For orientation state matrix + * x vector + * y vector + * z vector + */ +using MotionStatus = std::tuple<Common::Vec3<float>, Common::Vec3<float>, Common::Vec3<float>, + std::array<Common::Vec3f, 3>>; + +/** + * A motion device is an input device that returns a motion status object */ -using MotionDevice = InputDevice<std::tuple<Common::Vec3<float>, Common::Vec3<float>>>; +using MotionDevice = InputDevice<MotionStatus>; /** * A touch device is an input device that returns a tuple of two floats and a bool. The floats are |