mirror of https://github.com/PCSX2/pcsx2.git
160 lines
5.3 KiB
C++
160 lines
5.3 KiB
C++
/* PCSX2 - PS2 Emulator for PCs
|
|
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
|
*
|
|
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "PrecompiledHeader.h"
|
|
#include "Input/InputSource.h"
|
|
#include "common/StringUtil.h"
|
|
|
|
InputSource::InputSource() = default;
|
|
|
|
InputSource::~InputSource() = default;
|
|
|
|
void InputSource::UpdateMotorState(InputBindingKey large_key, InputBindingKey small_key, float large_intensity, float small_intensity)
|
|
{
|
|
if (large_key.bits != 0)
|
|
UpdateMotorState(large_key, large_intensity);
|
|
if (small_key.bits != 0)
|
|
UpdateMotorState(small_key, small_intensity);
|
|
}
|
|
|
|
InputBindingKey InputSource::MakeGenericControllerAxisKey(InputSourceType clazz, u32 controller_index, s32 axis_index)
|
|
{
|
|
InputBindingKey key = {};
|
|
key.source_type = clazz;
|
|
key.source_index = controller_index;
|
|
key.source_subtype = InputSubclass::ControllerAxis;
|
|
key.data = static_cast<u32>(axis_index);
|
|
return key;
|
|
}
|
|
|
|
InputBindingKey InputSource::MakeGenericControllerButtonKey(
|
|
InputSourceType clazz, u32 controller_index, s32 button_index)
|
|
{
|
|
InputBindingKey key = {};
|
|
key.source_type = clazz;
|
|
key.source_index = controller_index;
|
|
key.source_subtype = InputSubclass::ControllerButton;
|
|
key.data = static_cast<u32>(button_index);
|
|
return key;
|
|
}
|
|
|
|
InputBindingKey InputSource::MakeGenericControllerHatKey(InputSourceType clazz, u32 controller_index, s32 hat_index, u8 hat_direction, u32 num_directions)
|
|
{
|
|
InputBindingKey key = {};
|
|
key.source_type = clazz;
|
|
key.source_index = controller_index;
|
|
key.source_subtype = InputSubclass::ControllerHat;
|
|
key.data = static_cast<u32>(hat_index) * num_directions + hat_direction;
|
|
return key;
|
|
}
|
|
|
|
InputBindingKey InputSource::MakeGenericControllerMotorKey(InputSourceType clazz, u32 controller_index, s32 motor_index)
|
|
{
|
|
InputBindingKey key = {};
|
|
key.source_type = clazz;
|
|
key.source_index = controller_index;
|
|
key.source_subtype = InputSubclass::ControllerMotor;
|
|
key.data = static_cast<u32>(motor_index);
|
|
return key;
|
|
}
|
|
|
|
std::optional<InputBindingKey> InputSource::ParseGenericControllerKey(
|
|
InputSourceType clazz, const std::string_view& source, const std::string_view& sub_binding)
|
|
{
|
|
// try to find the number, this function doesn't care about whether it's xinput or sdl or whatever
|
|
std::string_view::size_type pos = 0;
|
|
while (pos < source.size())
|
|
{
|
|
if (source[pos] >= '0' && source[pos] <= '9')
|
|
break;
|
|
pos++;
|
|
}
|
|
if (pos == source.size())
|
|
return std::nullopt;
|
|
|
|
const std::optional<s32> source_index = StringUtil::FromChars<s32>(source.substr(pos));
|
|
if (source_index.has_value() || source_index.value() < 0)
|
|
return std::nullopt;
|
|
|
|
InputBindingKey key = {};
|
|
key.source_type = clazz;
|
|
key.source_index = source_index.value();
|
|
|
|
if (StringUtil::StartsWith(sub_binding, "+Axis") || StringUtil::StartsWith(sub_binding, "-Axis"))
|
|
{
|
|
const std::optional<s32> axis_number = StringUtil::FromChars<s32>(sub_binding.substr(5));
|
|
if (!axis_number.has_value() || axis_number.value() < 0)
|
|
return std::nullopt;
|
|
|
|
key.source_subtype = InputSubclass::ControllerAxis;
|
|
key.data = static_cast<u32>(axis_number.value());
|
|
|
|
if (sub_binding[0] == '+')
|
|
key.modifier = InputModifier::None;
|
|
else if (sub_binding[0] == '-')
|
|
key.modifier = InputModifier::Negate;
|
|
else
|
|
return std::nullopt;
|
|
}
|
|
else if (StringUtil::StartsWith(sub_binding, "FullAxis"))
|
|
{
|
|
const std::optional<s32> axis_number = StringUtil::FromChars<s32>(sub_binding.substr(8));
|
|
if (!axis_number.has_value() || axis_number.value() < 0)
|
|
return std::nullopt;
|
|
key.source_subtype = InputSubclass::ControllerAxis;
|
|
key.data = static_cast<u32>(axis_number.value());
|
|
key.modifier = InputModifier::FullAxis;
|
|
}
|
|
else if (StringUtil::StartsWith(sub_binding, "Button"))
|
|
{
|
|
const std::optional<s32> button_number = StringUtil::FromChars<s32>(sub_binding.substr(6));
|
|
if (!button_number.has_value() || button_number.value() < 0)
|
|
return std::nullopt;
|
|
|
|
key.source_subtype = InputSubclass::ControllerButton;
|
|
key.data = static_cast<u32>(button_number.value());
|
|
}
|
|
else
|
|
{
|
|
return std::nullopt;
|
|
}
|
|
|
|
return key;
|
|
}
|
|
|
|
std::string InputSource::ConvertGenericControllerKeyToString(InputBindingKey key)
|
|
{
|
|
if (key.source_subtype == InputSubclass::ControllerAxis)
|
|
{
|
|
const char* modifier = "";
|
|
switch (key.modifier) {
|
|
case InputModifier::None: modifier = "+"; break;
|
|
case InputModifier::Negate: modifier = "-"; break;
|
|
case InputModifier::FullAxis: modifier = "Full"; break;
|
|
}
|
|
return StringUtil::StdStringFromFormat("%s-%u/%sAxis%u", InputManager::InputSourceToString(key.source_type),
|
|
key.source_index, modifier, key.data);
|
|
}
|
|
else if (key.source_subtype == InputSubclass::ControllerButton)
|
|
{
|
|
return StringUtil::StdStringFromFormat(
|
|
"%s%u/Button%u", InputManager::InputSourceToString(key.source_type), key.source_index, key.data);
|
|
}
|
|
else
|
|
{
|
|
return {};
|
|
}
|
|
}
|