mirror of https://github.com/PCSX2/pcsx2.git
PAD: Add automatic mapping functions
This commit is contained in:
parent
51d47a1455
commit
fdc3ca1227
|
@ -18,6 +18,7 @@
|
||||||
#include "common/StringUtil.h"
|
#include "common/StringUtil.h"
|
||||||
#include "common/SettingsInterface.h"
|
#include "common/SettingsInterface.h"
|
||||||
|
|
||||||
|
#include "Frontend/InputManager.h"
|
||||||
#include "HostSettings.h"
|
#include "HostSettings.h"
|
||||||
|
|
||||||
#include "PAD/Host/Global.h"
|
#include "PAD/Host/Global.h"
|
||||||
|
@ -219,31 +220,9 @@ void PAD::SetDefaultConfig(SettingsInterface& si)
|
||||||
si.SetBoolValue("InputSources", "XInput", false);
|
si.SetBoolValue("InputSources", "XInput", false);
|
||||||
|
|
||||||
// PCSX2 Controller Settings - Controller 1 / Controller 2 / ...
|
// PCSX2 Controller Settings - Controller 1 / Controller 2 / ...
|
||||||
|
// Use the automapper to set this up.
|
||||||
si.SetStringValue("Pad1", "Type", GetDefaultPadType(0));
|
si.SetStringValue("Pad1", "Type", GetDefaultPadType(0));
|
||||||
si.SetStringValue("Pad1", "Up", "Keyboard/Up");
|
MapController(si, 0, InputManager::GetGenericBindingMapping("Keyboard"));
|
||||||
si.SetStringValue("Pad1", "Right", "Keyboard/Right");
|
|
||||||
si.SetStringValue("Pad1", "Down", "Keyboard/Down");
|
|
||||||
si.SetStringValue("Pad1", "Left", "Keyboard/Left");
|
|
||||||
si.SetStringValue("Pad1", "LUp", "Keyboard/W");
|
|
||||||
si.SetStringValue("Pad1", "LRight", "Keyboard/D");
|
|
||||||
si.SetStringValue("Pad1", "LDown", "Keyboard/S");
|
|
||||||
si.SetStringValue("Pad1", "LLeft", "Keyboard/A");
|
|
||||||
si.SetStringValue("Pad1", "RUp", "Keyboard/T");
|
|
||||||
si.SetStringValue("Pad1", "RRight", "Keyboard/H");
|
|
||||||
si.SetStringValue("Pad1", "RDown", "Keyboard/G");
|
|
||||||
si.SetStringValue("Pad1", "RLeft", "Keyboard/F");
|
|
||||||
si.SetStringValue("Pad1", "Triangle", "Keyboard/I");
|
|
||||||
si.SetStringValue("Pad1", "Circle", "Keyboard/L");
|
|
||||||
si.SetStringValue("Pad1", "Cross", "Keyboard/K");
|
|
||||||
si.SetStringValue("Pad1", "Square", "Keyboard/J");
|
|
||||||
si.SetStringValue("Pad1", "L1", "Keyboard/Q");
|
|
||||||
si.SetStringValue("Pad1", "L2", "Keyboard/1");
|
|
||||||
si.SetStringValue("Pad1", "L3", "Keyboard/2");
|
|
||||||
si.SetStringValue("Pad1", "R1", "Keyboard/E");
|
|
||||||
si.SetStringValue("Pad1", "R2", "Keyboard/3");
|
|
||||||
si.SetStringValue("Pad1", "R3", "Keyboard/4");
|
|
||||||
si.SetStringValue("Pad1", "Start", "Keyboard/Return");
|
|
||||||
si.SetStringValue("Pad1", "Select", "Keyboard/Backspace");
|
|
||||||
|
|
||||||
// PCSX2 Controller Settings - Hotkeys
|
// PCSX2 Controller Settings - Hotkeys
|
||||||
|
|
||||||
|
@ -284,57 +263,154 @@ void PAD::Update()
|
||||||
UpdateMacroButtons();
|
UpdateMacroButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ControllerBindingInfo
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
GenericInputBinding generic_mapping;
|
||||||
|
};
|
||||||
|
struct ControllerInfo
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
const ControllerBindingInfo* bindings;
|
||||||
|
u32 num_bindings;
|
||||||
|
PAD::VibrationCapabilities vibration_caps;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ControllerBindingInfo s_dualshock2_binds[] = {
|
||||||
|
{"Up", GenericInputBinding::DPadUp },
|
||||||
|
{"Right",GenericInputBinding::DPadRight },
|
||||||
|
{"Down", GenericInputBinding::DPadDown },
|
||||||
|
{"Left", GenericInputBinding::DPadLeft },
|
||||||
|
{"Triangle", GenericInputBinding::Triangle },
|
||||||
|
{"Circle", GenericInputBinding::Circle },
|
||||||
|
{"Cross", GenericInputBinding::Cross },
|
||||||
|
{"Square", GenericInputBinding::Square },
|
||||||
|
{"Select", GenericInputBinding::Select },
|
||||||
|
{"Start", GenericInputBinding::Start },
|
||||||
|
{"L1", GenericInputBinding::L1 },
|
||||||
|
{"L2", GenericInputBinding::L2 },
|
||||||
|
{"R1", GenericInputBinding::R1 },
|
||||||
|
{"R2", GenericInputBinding::R2 },
|
||||||
|
{"L3", GenericInputBinding::L3 },
|
||||||
|
{"R3", GenericInputBinding::R3 },
|
||||||
|
{"LUp", GenericInputBinding::LeftStickUp },
|
||||||
|
{"LRight", GenericInputBinding::LeftStickRight },
|
||||||
|
{"LDown", GenericInputBinding::LeftStickDown },
|
||||||
|
{"LLeft", GenericInputBinding::LeftStickLeft },
|
||||||
|
{"RUp", GenericInputBinding::RightStickUp },
|
||||||
|
{"RRight", GenericInputBinding::RightStickRight },
|
||||||
|
{"RDown", GenericInputBinding::RightStickDown },
|
||||||
|
{"RLeft", GenericInputBinding::RightStickLeft },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ControllerInfo s_controller_info[] = {
|
||||||
|
{ "DualShock2", s_dualshock2_binds, std::size(s_dualshock2_binds), PAD::VibrationCapabilities::LargeSmallMotors },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ControllerInfo* GetControllerInfo(const std::string_view& name)
|
||||||
|
{
|
||||||
|
for (const ControllerInfo& info : s_controller_info)
|
||||||
|
{
|
||||||
|
if (name == info.name)
|
||||||
|
return &info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> PAD::GetControllerTypeNames()
|
std::vector<std::string> PAD::GetControllerTypeNames()
|
||||||
{
|
{
|
||||||
return {"DualShock2"};
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
|
for (const ControllerInfo& info : s_controller_info)
|
||||||
|
ret.emplace_back(info.name);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> PAD::GetControllerBinds(const std::string_view& type)
|
std::vector<std::string> PAD::GetControllerBinds(const std::string_view& type)
|
||||||
{
|
{
|
||||||
if (type == "DualShock2")
|
std::vector<std::string> ret;
|
||||||
|
|
||||||
|
const ControllerInfo* info = GetControllerInfo(type);
|
||||||
|
if (info)
|
||||||
{
|
{
|
||||||
return {
|
for (u32 i = 0; i < info->num_bindings; i++)
|
||||||
"Up",
|
ret.emplace_back(info->bindings[i].name);
|
||||||
"Right",
|
|
||||||
"Down",
|
|
||||||
"Left",
|
|
||||||
"Triangle",
|
|
||||||
"Circle",
|
|
||||||
"Cross",
|
|
||||||
"Square",
|
|
||||||
"Select",
|
|
||||||
"Start",
|
|
||||||
"L1",
|
|
||||||
"L2",
|
|
||||||
"R1",
|
|
||||||
"R2",
|
|
||||||
"L3",
|
|
||||||
"R3",
|
|
||||||
"LUp",
|
|
||||||
"LRight",
|
|
||||||
"LDown",
|
|
||||||
"LLeft",
|
|
||||||
"RUp",
|
|
||||||
"RRight",
|
|
||||||
"RDown",
|
|
||||||
"RLeft"};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
PAD::VibrationCapabilities PAD::GetControllerVibrationCapabilities(const std::string_view& type)
|
PAD::VibrationCapabilities PAD::GetControllerVibrationCapabilities(const std::string_view& type)
|
||||||
{
|
{
|
||||||
if (type == "DualShock2")
|
const ControllerInfo* info = GetControllerInfo(type);
|
||||||
|
return info ? info->vibration_caps : VibrationCapabilities::NoVibration;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 TryMapGenericMapping(SettingsInterface& si, const std::string& section,
|
||||||
|
const GenericInputBindingMapping& mapping, GenericInputBinding generic_name,
|
||||||
|
const char* bind_name)
|
||||||
|
{
|
||||||
|
// find the mapping it corresponds to
|
||||||
|
const std::string* found_mapping = nullptr;
|
||||||
|
for (const std::pair<GenericInputBinding, std::string>& it : mapping)
|
||||||
{
|
{
|
||||||
return VibrationCapabilities::LargeSmallMotors;
|
if (it.first == generic_name)
|
||||||
|
{
|
||||||
|
found_mapping = &it.second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_mapping)
|
||||||
|
{
|
||||||
|
Console.WriteLn("(MapController) Map %s/%s to '%s'", section.c_str(), bind_name, found_mapping->c_str());
|
||||||
|
si.SetStringValue(section.c_str(), bind_name, found_mapping->c_str());
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return VibrationCapabilities::NoVibration;
|
si.DeleteValue(section.c_str(), bind_name);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PAD::MapController(SettingsInterface& si, u32 controller,
|
||||||
|
const std::vector<std::pair<GenericInputBinding, std::string>>& mapping)
|
||||||
|
{
|
||||||
|
const std::string section(StringUtil::StdStringFromFormat("Pad%u", controller + 1));
|
||||||
|
const std::string type(si.GetStringValue(section.c_str(), "Type", GetDefaultPadType(controller)));
|
||||||
|
const ControllerInfo* info = GetControllerInfo(type);
|
||||||
|
if (!info)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
u32 num_mappings = 0;
|
||||||
|
for (u32 i = 0; i < info->num_bindings; i++)
|
||||||
|
{
|
||||||
|
const ControllerBindingInfo& bi = info->bindings[i];
|
||||||
|
if (bi.generic_mapping == GenericInputBinding::Unknown)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
num_mappings += TryMapGenericMapping(si, section, mapping, bi.generic_mapping, bi.name);
|
||||||
|
}
|
||||||
|
if (info->vibration_caps == VibrationCapabilities::LargeSmallMotors)
|
||||||
|
{
|
||||||
|
num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::SmallMotor, "SmallMotor");
|
||||||
|
num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::LargeMotor, "LargeMotor");
|
||||||
|
}
|
||||||
|
else if (info->vibration_caps == VibrationCapabilities::SingleMotor)
|
||||||
|
{
|
||||||
|
if (TryMapGenericMapping(si, section, mapping, GenericInputBinding::LargeMotor, "Motor") == 0)
|
||||||
|
num_mappings += TryMapGenericMapping(si, section, mapping, GenericInputBinding::SmallMotor, "Motor");
|
||||||
|
else
|
||||||
|
num_mappings++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (num_mappings > 0);
|
||||||
|
}
|
||||||
|
|
||||||
void PAD::SetControllerState(u32 controller, u32 bind, float value)
|
void PAD::SetControllerState(u32 controller, u32 bind, float value)
|
||||||
{
|
{
|
||||||
if (controller >= GAMEPAD_NUMBER || bind >= MAX_KEYS)
|
if (controller >= GAMEPAD_NUMBER || bind >= MAX_KEYS)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "PAD/Host/Global.h"
|
#include "PAD/Host/Global.h"
|
||||||
|
@ -23,6 +24,7 @@
|
||||||
|
|
||||||
class SettingsInterface;
|
class SettingsInterface;
|
||||||
struct WindowInfo;
|
struct WindowInfo;
|
||||||
|
enum class GenericInputBinding : u8;
|
||||||
|
|
||||||
s32 PADinit();
|
s32 PADinit();
|
||||||
void PADshutdown();
|
void PADshutdown();
|
||||||
|
@ -64,6 +66,10 @@ namespace PAD
|
||||||
/// Returns the vibration configuration for the specified controller type.
|
/// Returns the vibration configuration for the specified controller type.
|
||||||
VibrationCapabilities GetControllerVibrationCapabilities(const std::string_view& type);
|
VibrationCapabilities GetControllerVibrationCapabilities(const std::string_view& type);
|
||||||
|
|
||||||
|
/// Performs automatic controller mapping with the provided list of generic mappings.
|
||||||
|
bool MapController(SettingsInterface& si, u32 controller,
|
||||||
|
const std::vector<std::pair<GenericInputBinding, std::string>>& mapping);
|
||||||
|
|
||||||
/// Sets the specified bind on a controller to the specified pressure (normalized to 0..1).
|
/// Sets the specified bind on a controller to the specified pressure (normalized to 0..1).
|
||||||
void SetControllerState(u32 controller, u32 bind, float value);
|
void SetControllerState(u32 controller, u32 bind, float value);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue