committed by
Narr the Reg
2 changed files with 585 additions and 0 deletions
@ -0,0 +1,361 @@ |
|||||
|
// Copyright 2021 yuzu Emulator Project
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included
|
||||
|
|
||||
|
#include "common/logging/log.h"
|
||||
|
#include "common/param_package.h"
|
||||
|
#include "input_common/input_engine.h"
|
||||
|
|
||||
|
namespace InputCommon { |
||||
|
|
||||
|
void InputEngine::PreSetController(const PadIdentifier& identifier) { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
if (!controller_list.contains(identifier)) { |
||||
|
controller_list.insert_or_assign(identifier, ControllerData{}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::PreSetButton(const PadIdentifier& identifier, int button) { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!controller.buttons.contains(button)) { |
||||
|
controller.buttons.insert_or_assign(button, false); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::PreSetHatButton(const PadIdentifier& identifier, int button) { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!controller.hat_buttons.contains(button)) { |
||||
|
controller.hat_buttons.insert_or_assign(button, u8{0}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::PreSetAxis(const PadIdentifier& identifier, int axis) { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!controller.axes.contains(axis)) { |
||||
|
controller.axes.insert_or_assign(axis, 0.0f); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::PreSetMotion(const PadIdentifier& identifier, int motion) { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!controller.motions.contains(motion)) { |
||||
|
controller.motions.insert_or_assign(motion, BasicMotion{}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::SetButton(const PadIdentifier& identifier, int button, bool value) { |
||||
|
{ |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!configuring) { |
||||
|
controller.buttons.insert_or_assign(button, value); |
||||
|
} |
||||
|
} |
||||
|
TriggerOnButtonChange(identifier, button, value); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::SetHatButton(const PadIdentifier& identifier, int button, u8 value) { |
||||
|
{ |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!configuring) { |
||||
|
controller.hat_buttons.insert_or_assign(button, value); |
||||
|
} |
||||
|
} |
||||
|
TriggerOnHatButtonChange(identifier, button, value); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::SetAxis(const PadIdentifier& identifier, int axis, f32 value) { |
||||
|
{ |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!configuring) { |
||||
|
controller.axes.insert_or_assign(axis, value); |
||||
|
} |
||||
|
} |
||||
|
TriggerOnAxisChange(identifier, axis, value); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::SetBattery(const PadIdentifier& identifier, BatteryLevel value) { |
||||
|
{ |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!configuring) { |
||||
|
controller.battery = value; |
||||
|
} |
||||
|
} |
||||
|
TriggerOnBatteryChange(identifier, value); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::SetMotion(const PadIdentifier& identifier, int motion, BasicMotion value) { |
||||
|
{ |
||||
|
std::lock_guard lock{mutex}; |
||||
|
ControllerData& controller = controller_list.at(identifier); |
||||
|
if (!configuring) { |
||||
|
controller.motions.insert_or_assign(motion, value); |
||||
|
} |
||||
|
} |
||||
|
TriggerOnMotionChange(identifier, motion, value); |
||||
|
} |
||||
|
|
||||
|
bool InputEngine::GetButton(const PadIdentifier& identifier, int button) const { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
if (!controller_list.contains(identifier)) { |
||||
|
LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.Format(), |
||||
|
identifier.pad, identifier.port); |
||||
|
return false; |
||||
|
} |
||||
|
ControllerData controller = controller_list.at(identifier); |
||||
|
if (!controller.buttons.contains(button)) { |
||||
|
LOG_ERROR(Input, "Invalid button {}", button); |
||||
|
return false; |
||||
|
} |
||||
|
return controller.buttons.at(button); |
||||
|
} |
||||
|
|
||||
|
bool InputEngine::GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
if (!controller_list.contains(identifier)) { |
||||
|
LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.Format(), |
||||
|
identifier.pad, identifier.port); |
||||
|
return false; |
||||
|
} |
||||
|
ControllerData controller = controller_list.at(identifier); |
||||
|
if (!controller.hat_buttons.contains(button)) { |
||||
|
LOG_ERROR(Input, "Invalid hat button {}", button); |
||||
|
return false; |
||||
|
} |
||||
|
return (controller.hat_buttons.at(button) & direction) != 0; |
||||
|
} |
||||
|
|
||||
|
f32 InputEngine::GetAxis(const PadIdentifier& identifier, int axis) const { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
if (!controller_list.contains(identifier)) { |
||||
|
LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.Format(), |
||||
|
identifier.pad, identifier.port); |
||||
|
return 0.0f; |
||||
|
} |
||||
|
ControllerData controller = controller_list.at(identifier); |
||||
|
if (!controller.axes.contains(axis)) { |
||||
|
LOG_ERROR(Input, "Invalid axis {}", axis); |
||||
|
return 0.0f; |
||||
|
} |
||||
|
return controller.axes.at(axis); |
||||
|
} |
||||
|
|
||||
|
BatteryLevel InputEngine::GetBattery(const PadIdentifier& identifier) const { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
if (!controller_list.contains(identifier)) { |
||||
|
LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.Format(), |
||||
|
identifier.pad, identifier.port); |
||||
|
return BatteryLevel::Charging; |
||||
|
} |
||||
|
ControllerData controller = controller_list.at(identifier); |
||||
|
return controller.battery; |
||||
|
} |
||||
|
|
||||
|
BasicMotion InputEngine::GetMotion(const PadIdentifier& identifier, int motion) const { |
||||
|
std::lock_guard lock{mutex}; |
||||
|
if (!controller_list.contains(identifier)) { |
||||
|
LOG_ERROR(Input, "Invalid identifier guid={}, pad={}, port={}", identifier.guid.Format(), |
||||
|
identifier.pad, identifier.port); |
||||
|
return {}; |
||||
|
} |
||||
|
ControllerData controller = controller_list.at(identifier); |
||||
|
return controller.motions.at(motion); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::ResetButtonState() { |
||||
|
for (std::pair<PadIdentifier, ControllerData> controller : controller_list) { |
||||
|
for (std::pair<int, bool> button : controller.second.buttons) { |
||||
|
SetButton(controller.first, button.first, false); |
||||
|
} |
||||
|
for (std::pair<int, bool> button : controller.second.hat_buttons) { |
||||
|
SetHatButton(controller.first, button.first, false); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::ResetAnalogState() { |
||||
|
for (std::pair<PadIdentifier, ControllerData> controller : controller_list) { |
||||
|
for (std::pair<int, float> axis : controller.second.axes) { |
||||
|
SetAxis(controller.first, axis.first, 0.0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
for (const std::pair<int, InputIdentifier> poller_pair : callback_list) { |
||||
|
const InputIdentifier& poller = poller_pair.second; |
||||
|
if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Button, button)) { |
||||
|
continue; |
||||
|
} |
||||
|
if (poller.callback.on_change) { |
||||
|
poller.callback.on_change(); |
||||
|
} |
||||
|
} |
||||
|
if (!configuring || !mapping_callback.on_data) { |
||||
|
return; |
||||
|
} |
||||
|
if (value == GetButton(identifier, button)) { |
||||
|
return; |
||||
|
} |
||||
|
mapping_callback.on_data(MappingData{ |
||||
|
.engine = GetEngineName(), |
||||
|
.pad = identifier, |
||||
|
.type = EngineInputType::Button, |
||||
|
.index = button, |
||||
|
.button_value = value, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
for (const std::pair<int, InputIdentifier> poller_pair : callback_list) { |
||||
|
const InputIdentifier& poller = poller_pair.second; |
||||
|
if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::HatButton, button)) { |
||||
|
continue; |
||||
|
} |
||||
|
if (poller.callback.on_change) { |
||||
|
poller.callback.on_change(); |
||||
|
} |
||||
|
} |
||||
|
if (!configuring || !mapping_callback.on_data) { |
||||
|
return; |
||||
|
} |
||||
|
for (std::size_t index = 1; index < 0xff; index <<= 1) { |
||||
|
bool button_value = (value & index) != 0; |
||||
|
if (button_value == GetHatButton(identifier, button, static_cast<u8>(index))) { |
||||
|
continue; |
||||
|
} |
||||
|
mapping_callback.on_data(MappingData{ |
||||
|
.engine = GetEngineName(), |
||||
|
.pad = identifier, |
||||
|
.type = EngineInputType::HatButton, |
||||
|
.index = button, |
||||
|
.hat_name = GetHatButtonName(static_cast<u8>(index)), |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::TriggerOnAxisChange(const PadIdentifier& identifier, int axis, f32 value) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
for (const std::pair<int, InputIdentifier> poller_pair : callback_list) { |
||||
|
const InputIdentifier& poller = poller_pair.second; |
||||
|
if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Analog, axis)) { |
||||
|
continue; |
||||
|
} |
||||
|
if (poller.callback.on_change) { |
||||
|
poller.callback.on_change(); |
||||
|
} |
||||
|
} |
||||
|
if (!configuring || !mapping_callback.on_data) { |
||||
|
return; |
||||
|
} |
||||
|
if (std::abs(value - GetAxis(identifier, axis)) < 0.5f) { |
||||
|
return; |
||||
|
} |
||||
|
mapping_callback.on_data(MappingData{ |
||||
|
.engine = GetEngineName(), |
||||
|
.pad = identifier, |
||||
|
.type = EngineInputType::Analog, |
||||
|
.index = axis, |
||||
|
.axis_value = value, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::TriggerOnBatteryChange(const PadIdentifier& identifier, |
||||
|
[[maybe_unused]] BatteryLevel value) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
for (const std::pair<int, InputIdentifier> poller_pair : callback_list) { |
||||
|
const InputIdentifier& poller = poller_pair.second; |
||||
|
if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Battery, 0)) { |
||||
|
continue; |
||||
|
} |
||||
|
if (poller.callback.on_change) { |
||||
|
poller.callback.on_change(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void InputEngine::TriggerOnMotionChange(const PadIdentifier& identifier, int motion, |
||||
|
BasicMotion value) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
for (const std::pair<int, InputIdentifier> poller_pair : callback_list) { |
||||
|
const InputIdentifier& poller = poller_pair.second; |
||||
|
if (!IsInputIdentifierEqual(poller, identifier, EngineInputType::Motion, motion)) { |
||||
|
continue; |
||||
|
} |
||||
|
if (poller.callback.on_change) { |
||||
|
poller.callback.on_change(); |
||||
|
} |
||||
|
} |
||||
|
if (!configuring || !mapping_callback.on_data) { |
||||
|
return; |
||||
|
} |
||||
|
if (std::abs(value.gyro_x) < 1.0f && std::abs(value.gyro_y) < 1.0f && |
||||
|
std::abs(value.gyro_z) < 1.0f) { |
||||
|
return; |
||||
|
} |
||||
|
mapping_callback.on_data(MappingData{ |
||||
|
.engine = GetEngineName(), |
||||
|
.pad = identifier, |
||||
|
.type = EngineInputType::Motion, |
||||
|
.index = motion, |
||||
|
.motion_value = value, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
bool InputEngine::IsInputIdentifierEqual(const InputIdentifier& input_identifier, |
||||
|
const PadIdentifier& identifier, EngineInputType type, |
||||
|
std::size_t index) const { |
||||
|
if (input_identifier.type != type) { |
||||
|
return false; |
||||
|
} |
||||
|
if (input_identifier.index != index) { |
||||
|
return false; |
||||
|
} |
||||
|
if (input_identifier.identifier != identifier) { |
||||
|
return false; |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
void InputEngine::BeginConfiguration() { |
||||
|
configuring = true; |
||||
|
} |
||||
|
|
||||
|
void InputEngine::EndConfiguration() { |
||||
|
configuring = false; |
||||
|
} |
||||
|
|
||||
|
const std::string& InputEngine::GetEngineName() const { |
||||
|
return input_engine; |
||||
|
} |
||||
|
|
||||
|
int InputEngine::SetCallback(InputIdentifier input_identifier) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
callback_list.insert_or_assign(last_callback_key, input_identifier); |
||||
|
return last_callback_key++; |
||||
|
} |
||||
|
|
||||
|
void InputEngine::SetMappingCallback(MappingCallback callback) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
mapping_callback = std::move(callback); |
||||
|
} |
||||
|
|
||||
|
void InputEngine::DeleteCallback(int key) { |
||||
|
std::lock_guard lock{mutex_callback}; |
||||
|
if (!callback_list.contains(key)) { |
||||
|
LOG_ERROR(Input, "Tried to delete non-existent callback {}", key); |
||||
|
return; |
||||
|
} |
||||
|
callback_list.erase(key); |
||||
|
} |
||||
|
|
||||
|
} // namespace InputCommon
|
||||
@ -0,0 +1,224 @@ |
|||||
|
// Copyright 2021 yuzu Emulator Project |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <functional> |
||||
|
#include <mutex> |
||||
|
#include <unordered_map> |
||||
|
|
||||
|
#include "common/common_types.h" |
||||
|
#include "common/input.h" |
||||
|
#include "common/param_package.h" |
||||
|
#include "common/uuid.h" |
||||
|
#include "input_common/main.h" |
||||
|
|
||||
|
// Pad Identifier of data source |
||||
|
struct PadIdentifier { |
||||
|
Common::UUID guid{}; |
||||
|
std::size_t port{}; |
||||
|
std::size_t pad{}; |
||||
|
|
||||
|
friend constexpr bool operator==(const PadIdentifier&, const PadIdentifier&) = default; |
||||
|
}; |
||||
|
|
||||
|
// Basic motion data containing data from the sensors and a timestamp in microsecons |
||||
|
struct BasicMotion { |
||||
|
float gyro_x; |
||||
|
float gyro_y; |
||||
|
float gyro_z; |
||||
|
float accel_x; |
||||
|
float accel_y; |
||||
|
float accel_z; |
||||
|
u64 delta_timestamp; |
||||
|
}; |
||||
|
|
||||
|
// Stages of a battery charge |
||||
|
enum class BatteryLevel { |
||||
|
Empty, |
||||
|
Critical, |
||||
|
Low, |
||||
|
Medium, |
||||
|
Full, |
||||
|
Charging, |
||||
|
}; |
||||
|
|
||||
|
// Types of input that are stored in the engine |
||||
|
enum class EngineInputType { |
||||
|
None, |
||||
|
Button, |
||||
|
HatButton, |
||||
|
Analog, |
||||
|
Motion, |
||||
|
Battery, |
||||
|
}; |
||||
|
|
||||
|
namespace std { |
||||
|
// Hash used to create lists from PadIdentifier data |
||||
|
template <> |
||||
|
struct hash<PadIdentifier> { |
||||
|
size_t operator()(const PadIdentifier& pad_id) const noexcept { |
||||
|
u64 hash_value = pad_id.guid.uuid[1] ^ pad_id.guid.uuid[0]; |
||||
|
hash_value ^= (static_cast<u64>(pad_id.port) << 32); |
||||
|
hash_value ^= static_cast<u64>(pad_id.pad); |
||||
|
return static_cast<size_t>(hash_value); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
} // namespace std |
||||
|
|
||||
|
namespace InputCommon { |
||||
|
|
||||
|
// Data from the engine and device needed for creating a ParamPackage |
||||
|
struct MappingData { |
||||
|
std::string engine{}; |
||||
|
PadIdentifier pad{}; |
||||
|
EngineInputType type{}; |
||||
|
int index{}; |
||||
|
bool button_value{}; |
||||
|
std::string hat_name{}; |
||||
|
f32 axis_value{}; |
||||
|
BasicMotion motion_value{}; |
||||
|
}; |
||||
|
|
||||
|
// Triggered if data changed on the controller |
||||
|
struct UpdateCallback { |
||||
|
std::function<void()> on_change; |
||||
|
}; |
||||
|
|
||||
|
// Triggered if data changed on the controller and the engine is on configuring mode |
||||
|
struct MappingCallback { |
||||
|
std::function<void(MappingData)> on_data; |
||||
|
}; |
||||
|
|
||||
|
// Input Identifier of data source |
||||
|
struct InputIdentifier { |
||||
|
PadIdentifier identifier; |
||||
|
EngineInputType type; |
||||
|
std::size_t index; |
||||
|
UpdateCallback callback; |
||||
|
}; |
||||
|
|
||||
|
class InputEngine { |
||||
|
public: |
||||
|
explicit InputEngine(const std::string& input_engine_) : input_engine(input_engine_) { |
||||
|
callback_list.clear(); |
||||
|
} |
||||
|
|
||||
|
virtual ~InputEngine() = default; |
||||
|
|
||||
|
// Enable configuring mode for mapping |
||||
|
void BeginConfiguration(); |
||||
|
|
||||
|
// Disable configuring mode for mapping |
||||
|
void EndConfiguration(); |
||||
|
|
||||
|
// Sets rumble to a controller |
||||
|
virtual bool SetRumble([[maybe_unused]] const PadIdentifier& identifier, |
||||
|
[[maybe_unused]] const Input::VibrationStatus vibration) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
// Sets a led pattern for a controller |
||||
|
virtual void SetLeds([[maybe_unused]] const PadIdentifier& identifier, |
||||
|
[[maybe_unused]] const Input::LedStatus led_status) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// Returns the engine name |
||||
|
[[nodiscard]] const std::string& GetEngineName() const; |
||||
|
|
||||
|
/// Used for automapping features |
||||
|
virtual std::vector<Common::ParamPackage> GetInputDevices() const { |
||||
|
return {}; |
||||
|
}; |
||||
|
|
||||
|
/// Retrieves the button mappings for the given device |
||||
|
virtual InputCommon::ButtonMapping GetButtonMappingForDevice( |
||||
|
[[maybe_unused]] const Common::ParamPackage& params) { |
||||
|
return {}; |
||||
|
}; |
||||
|
|
||||
|
/// Retrieves the analog mappings for the given device |
||||
|
virtual InputCommon::AnalogMapping GetAnalogMappingForDevice( |
||||
|
[[maybe_unused]] const Common::ParamPackage& params) { |
||||
|
return {}; |
||||
|
}; |
||||
|
|
||||
|
/// Retrieves the motion mappings for the given device |
||||
|
virtual InputCommon::MotionMapping GetMotionMappingForDevice( |
||||
|
[[maybe_unused]] const Common::ParamPackage& params) { |
||||
|
return {}; |
||||
|
}; |
||||
|
|
||||
|
/// Retrieves the name of the given input. |
||||
|
virtual std::string GetUIName([[maybe_unused]] const Common::ParamPackage& params) const { |
||||
|
return GetEngineName(); |
||||
|
}; |
||||
|
|
||||
|
/// Retrieves the index number of the given hat button direction |
||||
|
virtual u8 GetHatButtonId([[maybe_unused]] const std::string direction_name) const { |
||||
|
return 0; |
||||
|
}; |
||||
|
|
||||
|
void PreSetController(const PadIdentifier& identifier); |
||||
|
void PreSetButton(const PadIdentifier& identifier, int button); |
||||
|
void PreSetHatButton(const PadIdentifier& identifier, int button); |
||||
|
void PreSetAxis(const PadIdentifier& identifier, int axis); |
||||
|
void PreSetMotion(const PadIdentifier& identifier, int motion); |
||||
|
void ResetButtonState(); |
||||
|
void ResetAnalogState(); |
||||
|
|
||||
|
bool GetButton(const PadIdentifier& identifier, int button) const; |
||||
|
bool GetHatButton(const PadIdentifier& identifier, int button, u8 direction) const; |
||||
|
f32 GetAxis(const PadIdentifier& identifier, int axis) const; |
||||
|
BatteryLevel GetBattery(const PadIdentifier& identifier) const; |
||||
|
BasicMotion GetMotion(const PadIdentifier& identifier, int motion) const; |
||||
|
|
||||
|
int SetCallback(InputIdentifier input_identifier); |
||||
|
void SetMappingCallback(MappingCallback callback); |
||||
|
void DeleteCallback(int key); |
||||
|
|
||||
|
protected: |
||||
|
void SetButton(const PadIdentifier& identifier, int button, bool value); |
||||
|
void SetHatButton(const PadIdentifier& identifier, int button, u8 value); |
||||
|
void SetAxis(const PadIdentifier& identifier, int axis, f32 value); |
||||
|
void SetBattery(const PadIdentifier& identifier, BatteryLevel value); |
||||
|
void SetMotion(const PadIdentifier& identifier, int motion, BasicMotion value); |
||||
|
|
||||
|
virtual std::string GetHatButtonName([[maybe_unused]] u8 direction_value) const { |
||||
|
return "Unknown"; |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
struct ControllerData { |
||||
|
std::unordered_map<int, bool> buttons; |
||||
|
std::unordered_map<int, u8> hat_buttons; |
||||
|
std::unordered_map<int, float> axes; |
||||
|
std::unordered_map<int, BasicMotion> motions; |
||||
|
BatteryLevel battery; |
||||
|
}; |
||||
|
|
||||
|
void TriggerOnButtonChange(const PadIdentifier& identifier, int button, bool value); |
||||
|
void TriggerOnHatButtonChange(const PadIdentifier& identifier, int button, u8 value); |
||||
|
void TriggerOnAxisChange(const PadIdentifier& identifier, int button, f32 value); |
||||
|
void TriggerOnBatteryChange(const PadIdentifier& identifier, BatteryLevel value); |
||||
|
void TriggerOnMotionChange(const PadIdentifier& identifier, int motion, BasicMotion value); |
||||
|
|
||||
|
bool IsInputIdentifierEqual(const InputIdentifier& input_identifier, |
||||
|
const PadIdentifier& identifier, EngineInputType type, |
||||
|
std::size_t index) const; |
||||
|
|
||||
|
mutable std::mutex mutex; |
||||
|
mutable std::mutex mutex_callback; |
||||
|
bool configuring{false}; |
||||
|
bool is_callback_enabled{true}; |
||||
|
const std::string input_engine; |
||||
|
int last_callback_key = 0; |
||||
|
std::unordered_map<PadIdentifier, ControllerData> controller_list; |
||||
|
std::unordered_map<int, InputIdentifier> callback_list; |
||||
|
MappingCallback mapping_callback; |
||||
|
}; |
||||
|
|
||||
|
} // namespace InputCommon |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue