| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #include "common/settings.h"
- #include "input_common/input_engine.h"
- #include "input_common/input_mapping.h"
- namespace InputCommon {
- MappingFactory::MappingFactory() = default;
- void MappingFactory::BeginMapping(Polling::InputType type) {
- is_enabled = true;
- input_type = type;
- input_queue.Clear();
- first_axis = -1;
- second_axis = -1;
- }
- Common::ParamPackage MappingFactory::GetNextInput() {
- Common::ParamPackage input;
- input_queue.Pop(input);
- return input;
- }
- void MappingFactory::RegisterInput(const MappingData& data) {
- if (!is_enabled) {
- return;
- }
- if (!IsDriverValid(data)) {
- return;
- }
- switch (input_type) {
- case Polling::InputType::Button:
- RegisterButton(data);
- return;
- case Polling::InputType::Stick:
- RegisterStick(data);
- return;
- case Polling::InputType::Motion:
- RegisterMotion(data);
- return;
- default:
- return;
- }
- }
- void MappingFactory::StopMapping() {
- is_enabled = false;
- input_type = Polling::InputType::None;
- input_queue.Clear();
- }
- void MappingFactory::RegisterButton(const MappingData& data) {
- Common::ParamPackage new_input;
- new_input.Set("engine", data.engine);
- if (data.pad.guid.IsValid()) {
- new_input.Set("guid", data.pad.guid.RawString());
- }
- new_input.Set("port", static_cast<int>(data.pad.port));
- new_input.Set("pad", static_cast<int>(data.pad.pad));
- switch (data.type) {
- case EngineInputType::Button:
- // Workaround for old compatibility
- if (data.engine == "keyboard") {
- new_input.Set("code", data.index);
- break;
- }
- new_input.Set("button", data.index);
- break;
- case EngineInputType::HatButton:
- new_input.Set("hat", data.index);
- new_input.Set("direction", data.hat_name);
- break;
- case EngineInputType::Analog:
- // Ignore mouse axis when mapping buttons
- if (data.engine == "mouse" && data.index != 4) {
- return;
- }
- new_input.Set("axis", data.index);
- new_input.Set("threshold", 0.5f);
- break;
- case EngineInputType::Motion:
- new_input.Set("motion", data.index);
- break;
- default:
- return;
- }
- input_queue.Push(new_input);
- }
- void MappingFactory::RegisterStick(const MappingData& data) {
- Common::ParamPackage new_input;
- new_input.Set("engine", data.engine);
- if (data.pad.guid.IsValid()) {
- new_input.Set("guid", data.pad.guid.RawString());
- }
- new_input.Set("port", static_cast<int>(data.pad.port));
- new_input.Set("pad", static_cast<int>(data.pad.pad));
- // If engine is mouse map the mouse position as a joystick
- if (data.engine == "mouse") {
- new_input.Set("axis_x", 0);
- new_input.Set("axis_y", 1);
- new_input.Set("threshold", 0.5f);
- new_input.Set("range", 1.0f);
- new_input.Set("deadzone", 0.0f);
- input_queue.Push(new_input);
- return;
- }
- switch (data.type) {
- case EngineInputType::Button:
- case EngineInputType::HatButton:
- RegisterButton(data);
- return;
- case EngineInputType::Analog:
- if (first_axis == data.index) {
- return;
- }
- if (first_axis == -1) {
- first_axis = data.index;
- return;
- }
- new_input.Set("axis_x", first_axis);
- new_input.Set("axis_y", data.index);
- new_input.Set("threshold", 0.5f);
- new_input.Set("range", 0.95f);
- new_input.Set("deadzone", 0.15f);
- break;
- default:
- return;
- }
- input_queue.Push(new_input);
- }
- void MappingFactory::RegisterMotion(const MappingData& data) {
- Common::ParamPackage new_input;
- new_input.Set("engine", data.engine);
- if (data.pad.guid.IsValid()) {
- new_input.Set("guid", data.pad.guid.RawString());
- }
- new_input.Set("port", static_cast<int>(data.pad.port));
- new_input.Set("pad", static_cast<int>(data.pad.pad));
- // If engine is mouse map it automatically to mouse motion
- if (data.engine == "mouse") {
- new_input.Set("motion", 0);
- new_input.Set("pad", 1);
- new_input.Set("threshold", 0.001f);
- input_queue.Push(new_input);
- return;
- }
- switch (data.type) {
- case EngineInputType::Button:
- case EngineInputType::HatButton:
- RegisterButton(data);
- return;
- case EngineInputType::Analog:
- if (first_axis == data.index) {
- return;
- }
- if (second_axis == data.index) {
- return;
- }
- if (first_axis == -1) {
- first_axis = data.index;
- return;
- }
- if (second_axis == -1) {
- second_axis = data.index;
- return;
- }
- new_input.Set("axis_x", first_axis);
- new_input.Set("axis_y", second_axis);
- new_input.Set("axis_z", data.index);
- new_input.Set("range", 1.0f);
- new_input.Set("deadzone", 0.20f);
- break;
- case EngineInputType::Motion:
- new_input.Set("motion", data.index);
- break;
- default:
- return;
- }
- input_queue.Push(new_input);
- }
- bool MappingFactory::IsDriverValid(const MappingData& data) const {
- // Only port 0 can be mapped on the keyboard
- if (data.engine == "keyboard" && data.pad.port != 0) {
- return false;
- }
- // Only port 0 can be mapped on the mouse
- if (data.engine == "mouse" && data.pad.port != 0) {
- return false;
- }
- // To prevent mapping with two devices we disable any UDP except motion
- if (!Settings::values.enable_udp_controller && data.engine == "cemuhookudp" &&
- data.type != EngineInputType::Motion) {
- return false;
- }
- // The following drivers don't need to be mapped
- if (data.engine == "touch_from_button") {
- return false;
- }
- if (data.engine == "analog_from_button") {
- return false;
- }
- if (data.engine == "virtual_gamepad") {
- return false;
- }
- return true;
- }
- } // namespace InputCommon
|