android: Input mapping
This commit is contained in:
parent
ac33847b30
commit
50ecad547e
83 changed files with 5707 additions and 990 deletions
|
@ -2,8 +2,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
add_library(input_common STATIC
|
||||
drivers/android.cpp
|
||||
drivers/android.h
|
||||
drivers/camera.cpp
|
||||
drivers/camera.h
|
||||
drivers/keyboard.cpp
|
||||
|
@ -94,3 +92,11 @@ target_link_libraries(input_common PUBLIC hid_core PRIVATE common Boost::headers
|
|||
if (YUZU_USE_PRECOMPILED_HEADERS)
|
||||
target_precompile_headers(input_common PRIVATE precompiled_headers.h)
|
||||
endif()
|
||||
|
||||
if (ANDROID)
|
||||
target_sources(input_common PRIVATE
|
||||
drivers/android.cpp
|
||||
drivers/android.h
|
||||
)
|
||||
target_link_libraries(input_common PRIVATE android)
|
||||
endif()
|
||||
|
|
|
@ -1,30 +1,47 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include <set>
|
||||
#include <common/settings_input.h>
|
||||
#include <jni.h>
|
||||
#include "common/android/android_common.h"
|
||||
#include "common/android/id_cache.h"
|
||||
#include "input_common/drivers/android.h"
|
||||
|
||||
namespace InputCommon {
|
||||
|
||||
Android::Android(std::string input_engine_) : InputEngine(std::move(input_engine_)) {}
|
||||
|
||||
void Android::RegisterController(std::size_t controller_number) {
|
||||
PreSetController(GetIdentifier(controller_number));
|
||||
void Android::RegisterController(jobject j_input_device) {
|
||||
auto env = Common::Android::GetEnvForThread();
|
||||
const std::string guid = Common::Android::GetJString(
|
||||
env, static_cast<jstring>(
|
||||
env->CallObjectMethod(j_input_device, Common::Android::GetYuzuDeviceGetGUID())));
|
||||
const s32 port = env->CallIntMethod(j_input_device, Common::Android::GetYuzuDeviceGetPort());
|
||||
const auto identifier = GetIdentifier(guid, static_cast<size_t>(port));
|
||||
PreSetController(identifier);
|
||||
|
||||
if (input_devices.find(identifier) != input_devices.end()) {
|
||||
env->DeleteGlobalRef(input_devices[identifier]);
|
||||
}
|
||||
auto new_device = env->NewGlobalRef(j_input_device);
|
||||
input_devices[identifier] = new_device;
|
||||
}
|
||||
|
||||
void Android::SetButtonState(std::size_t controller_number, int button_id, bool value) {
|
||||
const auto identifier = GetIdentifier(controller_number);
|
||||
void Android::SetButtonState(std::string guid, size_t port, int button_id, bool value) {
|
||||
const auto identifier = GetIdentifier(guid, port);
|
||||
SetButton(identifier, button_id, value);
|
||||
}
|
||||
|
||||
void Android::SetAxisState(std::size_t controller_number, int axis_id, float value) {
|
||||
const auto identifier = GetIdentifier(controller_number);
|
||||
void Android::SetAxisPosition(std::string guid, size_t port, int axis_id, float value) {
|
||||
const auto identifier = GetIdentifier(guid, port);
|
||||
SetAxis(identifier, axis_id, value);
|
||||
}
|
||||
|
||||
void Android::SetMotionState(std::size_t controller_number, u64 delta_timestamp, float gyro_x,
|
||||
void Android::SetMotionState(std::string guid, size_t port, u64 delta_timestamp, float gyro_x,
|
||||
float gyro_y, float gyro_z, float accel_x, float accel_y,
|
||||
float accel_z) {
|
||||
const auto identifier = GetIdentifier(controller_number);
|
||||
const auto identifier = GetIdentifier(guid, port);
|
||||
const BasicMotion motion_data{
|
||||
.gyro_x = gyro_x,
|
||||
.gyro_y = gyro_y,
|
||||
|
@ -37,10 +54,295 @@ void Android::SetMotionState(std::size_t controller_number, u64 delta_timestamp,
|
|||
SetMotion(identifier, 0, motion_data);
|
||||
}
|
||||
|
||||
PadIdentifier Android::GetIdentifier(std::size_t controller_number) const {
|
||||
Common::Input::DriverResult Android::SetVibration(
|
||||
[[maybe_unused]] const PadIdentifier& identifier,
|
||||
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
|
||||
auto device = input_devices.find(identifier);
|
||||
if (device != input_devices.end()) {
|
||||
Common::Android::RunJNIOnFiber<void>([&](JNIEnv* env) {
|
||||
float average_intensity =
|
||||
static_cast<float>((vibration.high_amplitude + vibration.low_amplitude) / 2.0);
|
||||
env->CallVoidMethod(device->second, Common::Android::GetYuzuDeviceVibrate(),
|
||||
average_intensity);
|
||||
});
|
||||
return Common::Input::DriverResult::Success;
|
||||
}
|
||||
return Common::Input::DriverResult::NotSupported;
|
||||
}
|
||||
|
||||
bool Android::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
|
||||
auto device = input_devices.find(identifier);
|
||||
if (device != input_devices.end()) {
|
||||
return Common::Android::RunJNIOnFiber<bool>([&](JNIEnv* env) {
|
||||
return static_cast<bool>(env->CallBooleanMethod(
|
||||
device->second, Common::Android::GetYuzuDeviceGetSupportsVibration()));
|
||||
});
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<Common::ParamPackage> Android::GetInputDevices() const {
|
||||
std::vector<Common::ParamPackage> devices;
|
||||
auto env = Common::Android::GetEnvForThread();
|
||||
for (const auto& [key, value] : input_devices) {
|
||||
auto name_object = static_cast<jstring>(
|
||||
env->CallObjectMethod(value, Common::Android::GetYuzuDeviceGetName()));
|
||||
const std::string name =
|
||||
fmt::format("{} {}", Common::Android::GetJString(env, name_object), key.port);
|
||||
devices.emplace_back(Common::ParamPackage{
|
||||
{"engine", GetEngineName()},
|
||||
{"display", std::move(name)},
|
||||
{"guid", key.guid.RawString()},
|
||||
{"port", std::to_string(key.port)},
|
||||
});
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
std::set<s32> Android::GetDeviceAxes(JNIEnv* env, jobject& j_device) const {
|
||||
auto j_axes = static_cast<jobjectArray>(
|
||||
env->CallObjectMethod(j_device, Common::Android::GetYuzuDeviceGetAxes()));
|
||||
std::set<s32> axes;
|
||||
for (int i = 0; i < env->GetArrayLength(j_axes); ++i) {
|
||||
jobject axis = env->GetObjectArrayElement(j_axes, i);
|
||||
axes.insert(env->GetIntField(axis, Common::Android::GetIntegerValueField()));
|
||||
}
|
||||
return axes;
|
||||
}
|
||||
|
||||
Common::ParamPackage Android::BuildParamPackageForAnalog(PadIdentifier identifier, int axis_x,
|
||||
int axis_y) const {
|
||||
Common::ParamPackage params;
|
||||
params.Set("engine", GetEngineName());
|
||||
params.Set("port", static_cast<int>(identifier.port));
|
||||
params.Set("guid", identifier.guid.RawString());
|
||||
params.Set("axis_x", axis_x);
|
||||
params.Set("axis_y", axis_y);
|
||||
params.Set("offset_x", 0);
|
||||
params.Set("offset_y", 0);
|
||||
params.Set("invert_x", "+");
|
||||
|
||||
// Invert Y-Axis by default
|
||||
params.Set("invert_y", "-");
|
||||
return params;
|
||||
}
|
||||
|
||||
Common::ParamPackage Android::BuildAnalogParamPackageForButton(PadIdentifier identifier, s32 axis,
|
||||
bool invert) const {
|
||||
Common::ParamPackage params{};
|
||||
params.Set("engine", GetEngineName());
|
||||
params.Set("port", static_cast<int>(identifier.port));
|
||||
params.Set("guid", identifier.guid.RawString());
|
||||
params.Set("axis", axis);
|
||||
params.Set("threshold", "0.5");
|
||||
params.Set("invert", invert ? "-" : "+");
|
||||
return params;
|
||||
}
|
||||
|
||||
Common::ParamPackage Android::BuildButtonParamPackageForButton(PadIdentifier identifier,
|
||||
s32 button) const {
|
||||
Common::ParamPackage params{};
|
||||
params.Set("engine", GetEngineName());
|
||||
params.Set("port", static_cast<int>(identifier.port));
|
||||
params.Set("guid", identifier.guid.RawString());
|
||||
params.Set("button", button);
|
||||
return params;
|
||||
}
|
||||
|
||||
bool Android::MatchVID(Common::UUID device, const std::vector<std::string>& vids) const {
|
||||
for (size_t i = 0; i < vids.size(); ++i) {
|
||||
auto fucker = device.RawString();
|
||||
if (fucker.find(vids[i]) != std::string::npos) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
AnalogMapping Android::GetAnalogMappingForDevice(const Common::ParamPackage& params) {
|
||||
if (!params.Has("guid") || !params.Has("port")) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto identifier =
|
||||
GetIdentifier(params.Get("guid", ""), static_cast<size_t>(params.Get("port", 0)));
|
||||
auto& j_device = input_devices[identifier];
|
||||
if (j_device == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto env = Common::Android::GetEnvForThread();
|
||||
std::set<s32> axes = GetDeviceAxes(env, j_device);
|
||||
if (axes.size() == 0) {
|
||||
return {};
|
||||
}
|
||||
|
||||
AnalogMapping mapping = {};
|
||||
if (axes.find(AXIS_X) != axes.end() && axes.find(AXIS_Y) != axes.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeAnalog::LStick,
|
||||
BuildParamPackageForAnalog(identifier, AXIS_X, AXIS_Y));
|
||||
}
|
||||
|
||||
if (axes.find(AXIS_RX) != axes.end() && axes.find(AXIS_RY) != axes.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeAnalog::RStick,
|
||||
BuildParamPackageForAnalog(identifier, AXIS_RX, AXIS_RY));
|
||||
} else if (axes.find(AXIS_Z) != axes.end() && axes.find(AXIS_RZ) != axes.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeAnalog::RStick,
|
||||
BuildParamPackageForAnalog(identifier, AXIS_Z, AXIS_RZ));
|
||||
}
|
||||
return mapping;
|
||||
}
|
||||
|
||||
ButtonMapping Android::GetButtonMappingForDevice(const Common::ParamPackage& params) {
|
||||
if (!params.Has("guid") || !params.Has("port")) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto identifier =
|
||||
GetIdentifier(params.Get("guid", ""), static_cast<size_t>(params.Get("port", 0)));
|
||||
auto& j_device = input_devices[identifier];
|
||||
if (j_device == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto env = Common::Android::GetEnvForThread();
|
||||
jintArray j_keys = env->NewIntArray(static_cast<int>(keycode_ids.size()));
|
||||
env->SetIntArrayRegion(j_keys, 0, static_cast<int>(keycode_ids.size()), keycode_ids.data());
|
||||
auto j_has_keys_object = static_cast<jbooleanArray>(
|
||||
env->CallObjectMethod(j_device, Common::Android::GetYuzuDeviceHasKeys(), j_keys));
|
||||
jboolean isCopy = false;
|
||||
jboolean* j_has_keys = env->GetBooleanArrayElements(j_has_keys_object, &isCopy);
|
||||
|
||||
std::set<s32> available_keys;
|
||||
for (size_t i = 0; i < keycode_ids.size(); ++i) {
|
||||
if (j_has_keys[i]) {
|
||||
available_keys.insert(keycode_ids[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Some devices use axes instead of buttons for certain controls so we need all the axes here
|
||||
std::set<s32> axes = GetDeviceAxes(env, j_device);
|
||||
|
||||
ButtonMapping mapping = {};
|
||||
if (axes.find(AXIS_HAT_X) != axes.end() && axes.find(AXIS_HAT_Y) != axes.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::DUp,
|
||||
BuildAnalogParamPackageForButton(identifier, AXIS_HAT_Y, true));
|
||||
mapping.insert_or_assign(Settings::NativeButton::DDown,
|
||||
BuildAnalogParamPackageForButton(identifier, AXIS_HAT_Y, false));
|
||||
mapping.insert_or_assign(Settings::NativeButton::DLeft,
|
||||
BuildAnalogParamPackageForButton(identifier, AXIS_HAT_X, true));
|
||||
mapping.insert_or_assign(Settings::NativeButton::DRight,
|
||||
BuildAnalogParamPackageForButton(identifier, AXIS_HAT_X, false));
|
||||
} else if (available_keys.find(KEYCODE_DPAD_UP) != available_keys.end() &&
|
||||
available_keys.find(KEYCODE_DPAD_DOWN) != available_keys.end() &&
|
||||
available_keys.find(KEYCODE_DPAD_LEFT) != available_keys.end() &&
|
||||
available_keys.find(KEYCODE_DPAD_RIGHT) != available_keys.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::DUp,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_DPAD_UP));
|
||||
mapping.insert_or_assign(Settings::NativeButton::DDown,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_DPAD_DOWN));
|
||||
mapping.insert_or_assign(Settings::NativeButton::DLeft,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_DPAD_LEFT));
|
||||
mapping.insert_or_assign(Settings::NativeButton::DRight,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_DPAD_RIGHT));
|
||||
}
|
||||
|
||||
if (axes.find(AXIS_LTRIGGER) != axes.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::ZL, BuildAnalogParamPackageForButton(
|
||||
identifier, AXIS_LTRIGGER, false));
|
||||
} else if (available_keys.find(KEYCODE_BUTTON_L2) != available_keys.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::ZL,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_L2));
|
||||
}
|
||||
|
||||
if (axes.find(AXIS_RTRIGGER) != axes.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::ZR, BuildAnalogParamPackageForButton(
|
||||
identifier, AXIS_RTRIGGER, false));
|
||||
} else if (available_keys.find(KEYCODE_BUTTON_R2) != available_keys.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::ZR,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_R2));
|
||||
}
|
||||
|
||||
if (available_keys.find(KEYCODE_BUTTON_A) != available_keys.end()) {
|
||||
if (MatchVID(identifier.guid, flipped_ab_vids)) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::B, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_A));
|
||||
} else {
|
||||
mapping.insert_or_assign(Settings::NativeButton::A, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_A));
|
||||
}
|
||||
}
|
||||
if (available_keys.find(KEYCODE_BUTTON_B) != available_keys.end()) {
|
||||
if (MatchVID(identifier.guid, flipped_ab_vids)) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::A, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_B));
|
||||
} else {
|
||||
mapping.insert_or_assign(Settings::NativeButton::B, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_B));
|
||||
}
|
||||
}
|
||||
if (available_keys.find(KEYCODE_BUTTON_X) != available_keys.end()) {
|
||||
if (MatchVID(identifier.guid, flipped_xy_vids)) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::Y, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_X));
|
||||
} else {
|
||||
mapping.insert_or_assign(Settings::NativeButton::X, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_X));
|
||||
}
|
||||
}
|
||||
if (available_keys.find(KEYCODE_BUTTON_Y) != available_keys.end()) {
|
||||
if (MatchVID(identifier.guid, flipped_xy_vids)) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::X, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_Y));
|
||||
} else {
|
||||
mapping.insert_or_assign(Settings::NativeButton::Y, BuildButtonParamPackageForButton(
|
||||
identifier, KEYCODE_BUTTON_Y));
|
||||
}
|
||||
}
|
||||
|
||||
if (available_keys.find(KEYCODE_BUTTON_L1) != available_keys.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::L,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_L1));
|
||||
}
|
||||
if (available_keys.find(KEYCODE_BUTTON_R1) != available_keys.end()) {
|
||||
mapping.insert_or_assign(Settings::NativeButton::R,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_R1));
|
||||
}
|
||||
|
||||
if (available_keys.find(KEYCODE_BUTTON_THUMBL) != available_keys.end()) {
|
||||
mapping.insert_or_assign(
|
||||
Settings::NativeButton::LStick,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_THUMBL));
|
||||
}
|
||||
if (available_keys.find(KEYCODE_BUTTON_THUMBR) != available_keys.end()) {
|
||||
mapping.insert_or_assign(
|
||||
Settings::NativeButton::RStick,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_THUMBR));
|
||||
}
|
||||
|
||||
if (available_keys.find(KEYCODE_BUTTON_START) != available_keys.end()) {
|
||||
mapping.insert_or_assign(
|
||||
Settings::NativeButton::Plus,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_START));
|
||||
}
|
||||
if (available_keys.find(KEYCODE_BUTTON_SELECT) != available_keys.end()) {
|
||||
mapping.insert_or_assign(
|
||||
Settings::NativeButton::Minus,
|
||||
BuildButtonParamPackageForButton(identifier, KEYCODE_BUTTON_SELECT));
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
Common::Input::ButtonNames Android::GetUIName(
|
||||
[[maybe_unused]] const Common::ParamPackage& params) const {
|
||||
return Common::Input::ButtonNames::Value;
|
||||
}
|
||||
|
||||
PadIdentifier Android::GetIdentifier(const std::string& guid, size_t port) const {
|
||||
return {
|
||||
.guid = Common::UUID{},
|
||||
.port = controller_number,
|
||||
.guid = Common::UUID{guid},
|
||||
.port = port,
|
||||
.pad = 0,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <jni.h>
|
||||
#include "input_common/input_engine.h"
|
||||
|
||||
namespace InputCommon {
|
||||
|
@ -15,40 +17,121 @@ public:
|
|||
explicit Android(std::string input_engine_);
|
||||
|
||||
/**
|
||||
* Registers controller number to accept new inputs
|
||||
* @param controller_number the controller number that will take this action
|
||||
* Registers controller number to accept new inputs.
|
||||
* @param j_input_device YuzuInputDevice object from the Android frontend to register.
|
||||
*/
|
||||
void RegisterController(std::size_t controller_number);
|
||||
void RegisterController(jobject j_input_device);
|
||||
|
||||
/**
|
||||
* Sets the status of all buttons bound with the key to pressed
|
||||
* @param controller_number the controller number that will take this action
|
||||
* @param button_id the id of the button
|
||||
* @param value indicates if the button is pressed or not
|
||||
* Sets the status of a button on a specific controller.
|
||||
* @param guid 32 character hexadecimal string consisting of the controller's PID+VID.
|
||||
* @param port Port determined by controller connection order.
|
||||
* @param button_id The Android Keycode corresponding to this event.
|
||||
* @param value Whether the button is pressed or not.
|
||||
*/
|
||||
void SetButtonState(std::size_t controller_number, int button_id, bool value);
|
||||
void SetButtonState(std::string guid, size_t port, int button_id, bool value);
|
||||
|
||||
/**
|
||||
* Sets the status of a analog input to a specific player index
|
||||
* @param controller_number the controller number that will take this action
|
||||
* @param axis_id the id of the axis to move
|
||||
* @param value the analog position of the axis
|
||||
* Sets the status of an axis on a specific controller.
|
||||
* @param guid 32 character hexadecimal string consisting of the controller's PID+VID.
|
||||
* @param port Port determined by controller connection order.
|
||||
* @param axis_id The Android axis ID corresponding to this event.
|
||||
* @param value Value along the given axis.
|
||||
*/
|
||||
void SetAxisState(std::size_t controller_number, int axis_id, float value);
|
||||
void SetAxisPosition(std::string guid, size_t port, int axis_id, float value);
|
||||
|
||||
/**
|
||||
* Sets the status of the motion sensor to a specific player index
|
||||
* @param controller_number the controller number that will take this action
|
||||
* @param delta_timestamp time passed since last reading
|
||||
* @param gyro_x,gyro_y,gyro_z the gyro sensor readings
|
||||
* @param accel_x,accel_y,accel_z the accelerometer reading
|
||||
* Sets the status of the motion sensor on a specific controller
|
||||
* @param guid 32 character hexadecimal string consisting of the controller's PID+VID.
|
||||
* @param port Port determined by controller connection order.
|
||||
* @param delta_timestamp Time passed since the last read.
|
||||
* @param gyro_x,gyro_y,gyro_z Gyro sensor readings.
|
||||
* @param accel_x,accel_y,accel_z Accelerometer sensor readings.
|
||||
*/
|
||||
void SetMotionState(std::size_t controller_number, u64 delta_timestamp, float gyro_x,
|
||||
void SetMotionState(std::string guid, size_t port, u64 delta_timestamp, float gyro_x,
|
||||
float gyro_y, float gyro_z, float accel_x, float accel_y, float accel_z);
|
||||
|
||||
Common::Input::DriverResult SetVibration(
|
||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
||||
|
||||
bool IsVibrationEnabled(const PadIdentifier& identifier) override;
|
||||
|
||||
std::vector<Common::ParamPackage> GetInputDevices() const override;
|
||||
|
||||
/**
|
||||
* Gets the axes reported by the YuzuInputDevice.
|
||||
* @param env JNI environment pointer.
|
||||
* @param j_device YuzuInputDevice from the Android frontend.
|
||||
* @return Set of the axes reported by the underlying Android InputDevice
|
||||
*/
|
||||
std::set<s32> GetDeviceAxes(JNIEnv* env, jobject& j_device) const;
|
||||
|
||||
Common::ParamPackage BuildParamPackageForAnalog(PadIdentifier identifier, int axis_x,
|
||||
int axis_y) const;
|
||||
|
||||
Common::ParamPackage BuildAnalogParamPackageForButton(PadIdentifier identifier, s32 axis,
|
||||
bool invert) const;
|
||||
|
||||
Common::ParamPackage BuildButtonParamPackageForButton(PadIdentifier identifier,
|
||||
s32 button) const;
|
||||
|
||||
bool MatchVID(Common::UUID device, const std::vector<std::string>& vids) const;
|
||||
|
||||
AnalogMapping GetAnalogMappingForDevice(const Common::ParamPackage& params) override;
|
||||
|
||||
ButtonMapping GetButtonMappingForDevice(const Common::ParamPackage& params) override;
|
||||
|
||||
Common::Input::ButtonNames GetUIName(const Common::ParamPackage& params) const override;
|
||||
|
||||
private:
|
||||
std::unordered_map<PadIdentifier, jobject> input_devices;
|
||||
|
||||
/// Returns the correct identifier corresponding to the player index
|
||||
PadIdentifier GetIdentifier(std::size_t controller_number) const;
|
||||
PadIdentifier GetIdentifier(const std::string& guid, size_t port) const;
|
||||
|
||||
static constexpr s32 AXIS_X = 0;
|
||||
static constexpr s32 AXIS_Y = 1;
|
||||
static constexpr s32 AXIS_Z = 11;
|
||||
static constexpr s32 AXIS_RX = 12;
|
||||
static constexpr s32 AXIS_RY = 13;
|
||||
static constexpr s32 AXIS_RZ = 14;
|
||||
static constexpr s32 AXIS_HAT_X = 15;
|
||||
static constexpr s32 AXIS_HAT_Y = 16;
|
||||
static constexpr s32 AXIS_LTRIGGER = 17;
|
||||
static constexpr s32 AXIS_RTRIGGER = 18;
|
||||
|
||||
static constexpr s32 KEYCODE_DPAD_UP = 19;
|
||||
static constexpr s32 KEYCODE_DPAD_DOWN = 20;
|
||||
static constexpr s32 KEYCODE_DPAD_LEFT = 21;
|
||||
static constexpr s32 KEYCODE_DPAD_RIGHT = 22;
|
||||
static constexpr s32 KEYCODE_BUTTON_A = 96;
|
||||
static constexpr s32 KEYCODE_BUTTON_B = 97;
|
||||
static constexpr s32 KEYCODE_BUTTON_X = 99;
|
||||
static constexpr s32 KEYCODE_BUTTON_Y = 100;
|
||||
static constexpr s32 KEYCODE_BUTTON_L1 = 102;
|
||||
static constexpr s32 KEYCODE_BUTTON_R1 = 103;
|
||||
static constexpr s32 KEYCODE_BUTTON_L2 = 104;
|
||||
static constexpr s32 KEYCODE_BUTTON_R2 = 105;
|
||||
static constexpr s32 KEYCODE_BUTTON_THUMBL = 106;
|
||||
static constexpr s32 KEYCODE_BUTTON_THUMBR = 107;
|
||||
static constexpr s32 KEYCODE_BUTTON_START = 108;
|
||||
static constexpr s32 KEYCODE_BUTTON_SELECT = 109;
|
||||
const std::vector<s32> keycode_ids{
|
||||
KEYCODE_DPAD_UP, KEYCODE_DPAD_DOWN, KEYCODE_DPAD_LEFT, KEYCODE_DPAD_RIGHT,
|
||||
KEYCODE_BUTTON_A, KEYCODE_BUTTON_B, KEYCODE_BUTTON_X, KEYCODE_BUTTON_Y,
|
||||
KEYCODE_BUTTON_L1, KEYCODE_BUTTON_R1, KEYCODE_BUTTON_L2, KEYCODE_BUTTON_R2,
|
||||
KEYCODE_BUTTON_THUMBL, KEYCODE_BUTTON_THUMBR, KEYCODE_BUTTON_START, KEYCODE_BUTTON_SELECT,
|
||||
};
|
||||
|
||||
const std::string sony_vid{"054c"};
|
||||
const std::string nintendo_vid{"057e"};
|
||||
const std::string razer_vid{"1532"};
|
||||
const std::string redmagic_vid{"3537"};
|
||||
const std::string backbone_labs_vid{"358a"};
|
||||
const std::vector<std::string> flipped_ab_vids{sony_vid, nintendo_vid, razer_vid, redmagic_vid,
|
||||
backbone_labs_vid};
|
||||
const std::vector<std::string> flipped_xy_vids{sony_vid, razer_vid, redmagic_vid,
|
||||
backbone_labs_vid};
|
||||
};
|
||||
|
||||
} // namespace InputCommon
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <memory>
|
||||
#include "common/input.h"
|
||||
#include "common/param_package.h"
|
||||
#include "input_common/drivers/android.h"
|
||||
#include "input_common/drivers/camera.h"
|
||||
#include "input_common/drivers/keyboard.h"
|
||||
#include "input_common/drivers/mouse.h"
|
||||
|
@ -28,6 +27,10 @@
|
|||
#include "input_common/drivers/sdl_driver.h"
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "input_common/drivers/android.h"
|
||||
#endif
|
||||
|
||||
namespace InputCommon {
|
||||
|
||||
/// Dummy engine to get periodic updates
|
||||
|
@ -79,7 +82,9 @@ struct InputSubsystem::Impl {
|
|||
RegisterEngine("cemuhookudp", udp_client);
|
||||
RegisterEngine("tas", tas_input);
|
||||
RegisterEngine("camera", camera);
|
||||
#ifdef ANDROID
|
||||
RegisterEngine("android", android);
|
||||
#endif
|
||||
RegisterEngine("virtual_amiibo", virtual_amiibo);
|
||||
RegisterEngine("virtual_gamepad", virtual_gamepad);
|
||||
#ifdef HAVE_SDL2
|
||||
|
@ -111,7 +116,9 @@ struct InputSubsystem::Impl {
|
|||
UnregisterEngine(udp_client);
|
||||
UnregisterEngine(tas_input);
|
||||
UnregisterEngine(camera);
|
||||
#ifdef ANDROID
|
||||
UnregisterEngine(android);
|
||||
#endif
|
||||
UnregisterEngine(virtual_amiibo);
|
||||
UnregisterEngine(virtual_gamepad);
|
||||
#ifdef HAVE_SDL2
|
||||
|
@ -128,12 +135,16 @@ struct InputSubsystem::Impl {
|
|||
Common::ParamPackage{{"display", "Any"}, {"engine", "any"}},
|
||||
};
|
||||
|
||||
#ifndef ANDROID
|
||||
auto keyboard_devices = keyboard->GetInputDevices();
|
||||
devices.insert(devices.end(), keyboard_devices.begin(), keyboard_devices.end());
|
||||
auto mouse_devices = mouse->GetInputDevices();
|
||||
devices.insert(devices.end(), mouse_devices.begin(), mouse_devices.end());
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
auto android_devices = android->GetInputDevices();
|
||||
devices.insert(devices.end(), android_devices.begin(), android_devices.end());
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
auto gcadapter_devices = gcadapter->GetInputDevices();
|
||||
devices.insert(devices.end(), gcadapter_devices.begin(), gcadapter_devices.end());
|
||||
|
@ -162,9 +173,11 @@ struct InputSubsystem::Impl {
|
|||
if (engine == mouse->GetEngineName()) {
|
||||
return mouse;
|
||||
}
|
||||
#ifdef ANDROID
|
||||
if (engine == android->GetEngineName()) {
|
||||
return android;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
if (engine == gcadapter->GetEngineName()) {
|
||||
return gcadapter;
|
||||
|
@ -245,9 +258,11 @@ struct InputSubsystem::Impl {
|
|||
if (engine == mouse->GetEngineName()) {
|
||||
return true;
|
||||
}
|
||||
#ifdef ANDROID
|
||||
if (engine == android->GetEngineName()) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
if (engine == gcadapter->GetEngineName()) {
|
||||
return true;
|
||||
|
@ -276,7 +291,9 @@ struct InputSubsystem::Impl {
|
|||
void BeginConfiguration() {
|
||||
keyboard->BeginConfiguration();
|
||||
mouse->BeginConfiguration();
|
||||
#ifdef ANDROID
|
||||
android->BeginConfiguration();
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
gcadapter->BeginConfiguration();
|
||||
#endif
|
||||
|
@ -290,7 +307,9 @@ struct InputSubsystem::Impl {
|
|||
void EndConfiguration() {
|
||||
keyboard->EndConfiguration();
|
||||
mouse->EndConfiguration();
|
||||
#ifdef ANDROID
|
||||
android->EndConfiguration();
|
||||
#endif
|
||||
#ifdef HAVE_LIBUSB
|
||||
gcadapter->EndConfiguration();
|
||||
#endif
|
||||
|
@ -321,7 +340,6 @@ struct InputSubsystem::Impl {
|
|||
std::shared_ptr<TasInput::Tas> tas_input;
|
||||
std::shared_ptr<CemuhookUDP::UDPClient> udp_client;
|
||||
std::shared_ptr<Camera> camera;
|
||||
std::shared_ptr<Android> android;
|
||||
std::shared_ptr<VirtualAmiibo> virtual_amiibo;
|
||||
std::shared_ptr<VirtualGamepad> virtual_gamepad;
|
||||
|
||||
|
@ -333,6 +351,10 @@ struct InputSubsystem::Impl {
|
|||
std::shared_ptr<SDLDriver> sdl;
|
||||
std::shared_ptr<Joycons> joycon;
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
std::shared_ptr<Android> android;
|
||||
#endif
|
||||
};
|
||||
|
||||
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
|
||||
|
@ -387,6 +409,7 @@ const Camera* InputSubsystem::GetCamera() const {
|
|||
return impl->camera.get();
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
Android* InputSubsystem::GetAndroid() {
|
||||
return impl->android.get();
|
||||
}
|
||||
|
@ -394,6 +417,7 @@ Android* InputSubsystem::GetAndroid() {
|
|||
const Android* InputSubsystem::GetAndroid() const {
|
||||
return impl->android.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
VirtualAmiibo* InputSubsystem::GetVirtualAmiibo() {
|
||||
return impl->virtual_amiibo.get();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue