mirror of
https://github.com/Lime3DS/Lime3DS.git
synced 2026-06-05 07:14:59 -06:00
qt: Add controller touchpad support (#777)
This commit is contained in:
parent
a3db3be4a6
commit
1febb83942
@ -199,6 +199,8 @@ if (ENABLE_QT)
|
|||||||
"name"
|
"name"
|
||||||
"bind"
|
"bind"
|
||||||
"profile"
|
"profile"
|
||||||
|
"use_touchpad"
|
||||||
|
"controller_touch_device"
|
||||||
"use_touch_from_button"
|
"use_touch_from_button"
|
||||||
"touch_from_button_map"
|
"touch_from_button_map"
|
||||||
"touch_from_button_maps" # Why are these two so similar? Basically typo bait
|
"touch_from_button_maps" # Why are these two so similar? Basically typo bait
|
||||||
|
|||||||
@ -405,6 +405,11 @@ void QtConfig::ReadControlValues() {
|
|||||||
ReadSetting(Settings::QKeys::touch_device, QStringLiteral("engine:emu_window"))
|
ReadSetting(Settings::QKeys::touch_device, QStringLiteral("engine:emu_window"))
|
||||||
.toString()
|
.toString()
|
||||||
.toStdString();
|
.toStdString();
|
||||||
|
profile.use_touchpad = ReadSetting(Settings::QKeys::use_touchpad, false).toBool();
|
||||||
|
profile.controller_touch_device =
|
||||||
|
ReadSetting(Settings::QKeys::controller_touch_device, QStringLiteral(""))
|
||||||
|
.toString()
|
||||||
|
.toStdString();
|
||||||
profile.use_touch_from_button =
|
profile.use_touch_from_button =
|
||||||
ReadSetting(Settings::QKeys::use_touch_from_button, false).toBool();
|
ReadSetting(Settings::QKeys::use_touch_from_button, false).toBool();
|
||||||
profile.touch_from_button_map_index =
|
profile.touch_from_button_map_index =
|
||||||
@ -1005,6 +1010,9 @@ void QtConfig::SaveControlValues() {
|
|||||||
QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01,tilt_clamp:90.0"));
|
QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01,tilt_clamp:90.0"));
|
||||||
WriteSetting(Settings::QKeys::touch_device, QString::fromStdString(profile.touch_device),
|
WriteSetting(Settings::QKeys::touch_device, QString::fromStdString(profile.touch_device),
|
||||||
QStringLiteral("engine:emu_window"));
|
QStringLiteral("engine:emu_window"));
|
||||||
|
WriteSetting(Settings::QKeys::use_touchpad, profile.use_touchpad, false);
|
||||||
|
WriteSetting(Settings::QKeys::controller_touch_device,
|
||||||
|
QString::fromStdString(profile.controller_touch_device), QStringLiteral(""));
|
||||||
WriteSetting(Settings::QKeys::use_touch_from_button, profile.use_touch_from_button, false);
|
WriteSetting(Settings::QKeys::use_touch_from_button, profile.use_touch_from_button, false);
|
||||||
WriteSetting(Settings::QKeys::touch_from_button_map, profile.touch_from_button_map_index,
|
WriteSetting(Settings::QKeys::touch_from_button_map, profile.touch_from_button_map_index,
|
||||||
0);
|
0);
|
||||||
|
|||||||
@ -139,6 +139,7 @@ void ConfigureMotionTouch::SetConfiguration() {
|
|||||||
ui->touch_provider->findData(QString::fromStdString(touch_engine)));
|
ui->touch_provider->findData(QString::fromStdString(touch_engine)));
|
||||||
ui->touch_from_button_checkbox->setChecked(
|
ui->touch_from_button_checkbox->setChecked(
|
||||||
Settings::values.current_input_profile.use_touch_from_button);
|
Settings::values.current_input_profile.use_touch_from_button);
|
||||||
|
ui->touchpad_checkbox->setChecked(Settings::values.current_input_profile.use_touchpad);
|
||||||
touch_from_button_maps = Settings::values.touch_from_button_maps;
|
touch_from_button_maps = Settings::values.touch_from_button_maps;
|
||||||
for (const auto& touch_map : touch_from_button_maps) {
|
for (const auto& touch_map : touch_from_button_maps) {
|
||||||
ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name));
|
ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name));
|
||||||
@ -164,7 +165,7 @@ void ConfigureMotionTouch::SetConfiguration() {
|
|||||||
void ConfigureMotionTouch::UpdateUiDisplay() {
|
void ConfigureMotionTouch::UpdateUiDisplay() {
|
||||||
const std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
|
const std::string motion_engine = ui->motion_provider->currentData().toString().toStdString();
|
||||||
const std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
|
const std::string touch_engine = ui->touch_provider->currentData().toString().toStdString();
|
||||||
|
ui->touchpad_config_btn->setEnabled(ui->touchpad_checkbox->isChecked());
|
||||||
if (motion_engine == "motion_emu") {
|
if (motion_engine == "motion_emu") {
|
||||||
ui->motion_sensitivity_label->setVisible(true);
|
ui->motion_sensitivity_label->setVisible(true);
|
||||||
ui->motion_sensitivity->setVisible(true);
|
ui->motion_sensitivity->setVisible(true);
|
||||||
@ -229,6 +230,33 @@ void ConfigureMotionTouch::ConnectEvents() {
|
|||||||
poll_timer->start(200); // Check for new inputs every 200ms
|
poll_timer->start(200); // Check for new inputs every 200ms
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(ui->touchpad_checkbox, &QCheckBox::checkStateChanged, this,
|
||||||
|
[this]() { UpdateUiDisplay(); });
|
||||||
|
connect(ui->touchpad_config_btn, &QPushButton::clicked, this, [this]() {
|
||||||
|
if (QMessageBox::information(this, tr("Information"),
|
||||||
|
tr("After pressing OK, tap the touchpad on the controller "
|
||||||
|
"you want to track."),
|
||||||
|
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
|
||||||
|
ui->touchpad_config_btn->setText(tr("[press touchpad]"));
|
||||||
|
ui->touchpad_config_btn->setFocus();
|
||||||
|
|
||||||
|
input_setter = [this](const Common::ParamPackage& params) {
|
||||||
|
tpguid = params.Get("guid", "0");
|
||||||
|
tpport = params.Get("port", 0);
|
||||||
|
tp = params.Get("touchpad", 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
device_pollers =
|
||||||
|
InputCommon::Polling::GetPollers(InputCommon::Polling::DeviceType::Touchpad);
|
||||||
|
|
||||||
|
for (auto& poller : device_pollers) {
|
||||||
|
poller->Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout_timer->start(5000); // Cancel after 5 seconds
|
||||||
|
poll_timer->start(200); // Check for new inputs every 200ms
|
||||||
|
}
|
||||||
|
});
|
||||||
connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest);
|
connect(ui->udp_test, &QPushButton::clicked, this, &ConfigureMotionTouch::OnCemuhookUDPTest);
|
||||||
connect(ui->touch_calibration_config, &QPushButton::clicked, this,
|
connect(ui->touch_calibration_config, &QPushButton::clicked, this,
|
||||||
&ConfigureMotionTouch::OnConfigureTouchCalibration);
|
&ConfigureMotionTouch::OnConfigureTouchCalibration);
|
||||||
@ -253,7 +281,7 @@ void ConfigureMotionTouch::SetPollingResult(const Common::ParamPackage& params,
|
|||||||
if (!abort && input_setter) {
|
if (!abort && input_setter) {
|
||||||
(*input_setter)(params);
|
(*input_setter)(params);
|
||||||
}
|
}
|
||||||
|
ui->touchpad_config_btn->setText(tr("Configure"));
|
||||||
ui->motion_controller_button->setText(tr("Configure"));
|
ui->motion_controller_button->setText(tr("Configure"));
|
||||||
input_setter.reset();
|
input_setter.reset();
|
||||||
}
|
}
|
||||||
@ -291,7 +319,6 @@ void ConfigureMotionTouch::OnConfigureTouchCalibration() {
|
|||||||
"UDP touchpad calibration config success: min_x={}, min_y={}, max_x={}, max_y={}",
|
"UDP touchpad calibration config success: min_x={}, min_y={}, max_x={}, max_y={}",
|
||||||
min_x, min_y, max_x, max_y);
|
min_x, min_y, max_x, max_y);
|
||||||
UpdateUiDisplay();
|
UpdateUiDisplay();
|
||||||
} else {
|
|
||||||
LOG_ERROR(Frontend, "UDP touchpad calibration config failed");
|
LOG_ERROR(Frontend, "UDP touchpad calibration config failed");
|
||||||
}
|
}
|
||||||
ui->touch_calibration_config->setEnabled(true);
|
ui->touch_calibration_config->setEnabled(true);
|
||||||
@ -374,12 +401,21 @@ void ConfigureMotionTouch::ApplyConfiguration() {
|
|||||||
touch_param.Set("max_y", max_y);
|
touch_param.Set("max_y", max_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::ParamPackage touchpad_param{};
|
||||||
|
if (ui->touchpad_checkbox->isChecked()) {
|
||||||
|
touchpad_param.Set("engine", "sdl");
|
||||||
|
touchpad_param.Set("guid", tpguid);
|
||||||
|
touchpad_param.Set("port", tpport);
|
||||||
|
touchpad_param.Set("touchpad", tp);
|
||||||
|
}
|
||||||
Settings::values.current_input_profile.motion_device = motion_param.Serialize();
|
Settings::values.current_input_profile.motion_device = motion_param.Serialize();
|
||||||
Settings::values.current_input_profile.touch_device = touch_param.Serialize();
|
Settings::values.current_input_profile.touch_device = touch_param.Serialize();
|
||||||
Settings::values.current_input_profile.use_touch_from_button =
|
Settings::values.current_input_profile.use_touch_from_button =
|
||||||
ui->touch_from_button_checkbox->isChecked();
|
ui->touch_from_button_checkbox->isChecked();
|
||||||
Settings::values.current_input_profile.touch_from_button_map_index =
|
Settings::values.current_input_profile.touch_from_button_map_index =
|
||||||
ui->touch_from_button_map->currentIndex();
|
ui->touch_from_button_map->currentIndex();
|
||||||
|
Settings::values.current_input_profile.use_touchpad = ui->touchpad_checkbox->isChecked();
|
||||||
|
Settings::values.current_input_profile.controller_touch_device = touchpad_param.Serialize();
|
||||||
Settings::values.touch_from_button_maps = touch_from_button_maps;
|
Settings::values.touch_from_button_maps = touch_from_button_maps;
|
||||||
Settings::values.current_input_profile.udp_input_address = ui->udp_server->text().toStdString();
|
Settings::values.current_input_profile.udp_input_address = ui->udp_server->text().toStdString();
|
||||||
Settings::values.current_input_profile.udp_input_port =
|
Settings::values.current_input_profile.udp_input_port =
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2018 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -76,6 +76,9 @@ private:
|
|||||||
// Used for SDL input polling
|
// Used for SDL input polling
|
||||||
std::string guid;
|
std::string guid;
|
||||||
int port;
|
int port;
|
||||||
|
std::string tpguid; // guid for touchpad
|
||||||
|
int tpport; // port for touchpad
|
||||||
|
int tp; // which touchpad
|
||||||
std::unique_ptr<QTimer> timeout_timer;
|
std::unique_ptr<QTimer> timeout_timer;
|
||||||
std::unique_ptr<QTimer> poll_timer;
|
std::unique_ptr<QTimer> poll_timer;
|
||||||
std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers;
|
std::vector<std::unique_ptr<InputCommon::Polling::DevicePoller>> device_pollers;
|
||||||
|
|||||||
@ -2,17 +2,17 @@
|
|||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>ConfigureMotionTouch</class>
|
<class>ConfigureMotionTouch</class>
|
||||||
<widget class="QDialog" name="ConfigureMotionTouch">
|
<widget class="QDialog" name="ConfigureMotionTouch">
|
||||||
<property name="windowTitle">
|
|
||||||
<string>Configure Motion / Touch</string>
|
|
||||||
</property>
|
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>500</width>
|
<width>517</width>
|
||||||
<height>450</height>
|
<height>659</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Configure Motion / Touch</string>
|
||||||
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="motion_group_box">
|
<widget class="QGroupBox" name="motion_group_box">
|
||||||
@ -175,6 +175,27 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="touchpad_hlayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="touchpad_checkbox">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Map touchpads on controllers like the DualSense directly to touch</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use controller touchpad</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item alignment="Qt::AlignRight">
|
||||||
|
<widget class="QPushButton" name="touchpad_config_btn">
|
||||||
|
<property name="text">
|
||||||
|
<string>Configure</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@ -324,4 +345,5 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|||||||
@ -442,6 +442,8 @@ struct InputProfile {
|
|||||||
std::array<std::string, NativeAnalog::NumAnalogs> analogs;
|
std::array<std::string, NativeAnalog::NumAnalogs> analogs;
|
||||||
std::string motion_device;
|
std::string motion_device;
|
||||||
std::string touch_device;
|
std::string touch_device;
|
||||||
|
std::string controller_touch_device;
|
||||||
|
bool use_touchpad;
|
||||||
bool use_touch_from_button;
|
bool use_touch_from_button;
|
||||||
int touch_from_button_map_index;
|
int touch_from_button_map_index;
|
||||||
std::string udp_input_address;
|
std::string udp_input_address;
|
||||||
|
|||||||
@ -115,6 +115,7 @@ DirectionState GetStickDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Module::LoadInputDevices() {
|
void Module::LoadInputDevices() {
|
||||||
|
LOG_DEBUG(Frontend, "Loading input devices");
|
||||||
std::transform(Settings::values.current_input_profile.buttons.begin() +
|
std::transform(Settings::values.current_input_profile.buttons.begin() +
|
||||||
Settings::NativeButton::BUTTON_HID_BEGIN,
|
Settings::NativeButton::BUTTON_HID_BEGIN,
|
||||||
Settings::values.current_input_profile.buttons.begin() +
|
Settings::values.current_input_profile.buttons.begin() +
|
||||||
@ -126,6 +127,13 @@ void Module::LoadInputDevices() {
|
|||||||
Settings::values.current_input_profile.motion_device);
|
Settings::values.current_input_profile.motion_device);
|
||||||
touch_device = Input::CreateDevice<Input::TouchDevice>(
|
touch_device = Input::CreateDevice<Input::TouchDevice>(
|
||||||
Settings::values.current_input_profile.touch_device);
|
Settings::values.current_input_profile.touch_device);
|
||||||
|
if (Settings::values.current_input_profile.use_touchpad &&
|
||||||
|
Settings::values.current_input_profile.controller_touch_device != "") {
|
||||||
|
controller_touch_device = Input::CreateDevice<Input::TouchDevice>(
|
||||||
|
Settings::values.current_input_profile.controller_touch_device);
|
||||||
|
} else {
|
||||||
|
controller_touch_device.reset();
|
||||||
|
}
|
||||||
if (Settings::values.current_input_profile.use_touch_from_button) {
|
if (Settings::values.current_input_profile.use_touch_from_button) {
|
||||||
touch_btn_device = Input::CreateDevice<Input::TouchDevice>("engine:touch_from_button");
|
touch_btn_device = Input::CreateDevice<Input::TouchDevice>("engine:touch_from_button");
|
||||||
} else {
|
} else {
|
||||||
@ -278,6 +286,9 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
|
|||||||
if (!pressed && touch_btn_device) {
|
if (!pressed && touch_btn_device) {
|
||||||
std::tie(x, y, pressed) = touch_btn_device->GetStatus();
|
std::tie(x, y, pressed) = touch_btn_device->GetStatus();
|
||||||
}
|
}
|
||||||
|
if (!pressed && controller_touch_device) {
|
||||||
|
std::tie(x, y, pressed) = controller_touch_device->GetStatus();
|
||||||
|
}
|
||||||
touch_entry.x = static_cast<u16>(x * Core::kScreenBottomWidth);
|
touch_entry.x = static_cast<u16>(x * Core::kScreenBottomWidth);
|
||||||
touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight);
|
touch_entry.y = static_cast<u16>(y * Core::kScreenBottomHeight);
|
||||||
touch_entry.valid.Assign(pressed ? 1 : 0);
|
touch_entry.valid.Assign(pressed ? 1 : 0);
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2015 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -390,6 +390,7 @@ private:
|
|||||||
buttons;
|
buttons;
|
||||||
std::unique_ptr<Input::AnalogDevice> circle_pad;
|
std::unique_ptr<Input::AnalogDevice> circle_pad;
|
||||||
std::unique_ptr<Input::MotionDevice> motion_device;
|
std::unique_ptr<Input::MotionDevice> motion_device;
|
||||||
|
std::unique_ptr<Input::TouchDevice> controller_touch_device;
|
||||||
std::unique_ptr<Input::TouchDevice> touch_device;
|
std::unique_ptr<Input::TouchDevice> touch_device;
|
||||||
std::unique_ptr<Input::TouchDevice> touch_btn_device;
|
std::unique_ptr<Input::TouchDevice> touch_btn_device;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2017 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ void ReloadInputDevices();
|
|||||||
|
|
||||||
namespace Polling {
|
namespace Polling {
|
||||||
|
|
||||||
enum class DeviceType { Button, Analog };
|
enum class DeviceType { Button, Analog, Touchpad };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that can be used to get inputs from an input device like controllers without having to
|
* A class that can be used to get inputs from an input device like controllers without having to
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2018 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2018 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -182,6 +182,11 @@ public:
|
|||||||
return has_gyro || has_accel;
|
return has_gyro || has_accel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetTouchpad(float x, float y, int touchpad, bool down) {
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
|
state.touchpad[touchpad] = std::make_tuple(x, y, down);
|
||||||
|
}
|
||||||
|
|
||||||
void SetButton(int button, bool value) {
|
void SetButton(int button, bool value) {
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
state.buttons[button] = value;
|
state.buttons[button] = value;
|
||||||
@ -246,6 +251,11 @@ public:
|
|||||||
return std::make_tuple(state.accel, state.gyro);
|
return std::make_tuple(state.accel, state.gyro);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<float, float, bool> GetTouch(int pad) {
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
|
return state.touchpad[pad];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The guid of the joystick
|
* The guid of the joystick
|
||||||
*/
|
*/
|
||||||
@ -280,6 +290,7 @@ private:
|
|||||||
std::unordered_map<int, Uint8> hats;
|
std::unordered_map<int, Uint8> hats;
|
||||||
Common::Vec3<float> accel;
|
Common::Vec3<float> accel;
|
||||||
Common::Vec3<float> gyro;
|
Common::Vec3<float> gyro;
|
||||||
|
std::unordered_map<int, std::tuple<float, float, bool>> touchpad;
|
||||||
} state;
|
} state;
|
||||||
std::string guid;
|
std::string guid;
|
||||||
int port;
|
int port;
|
||||||
@ -590,6 +601,19 @@ void SDLState::HandleGameControllerEvent(const SDL_Event& event) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||||
|
case SDL_CONTROLLERTOUCHPADMOTION:
|
||||||
|
if (auto joystick = GetSDLJoystickBySDLID(event.ctouchpad.which)) {
|
||||||
|
joystick->SetTouchpad(event.ctouchpad.x, event.ctouchpad.y, event.ctouchpad.touchpad,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLERTOUCHPADUP:
|
||||||
|
if (auto joystick = GetSDLJoystickBySDLID(event.ctouchpad.which)) {
|
||||||
|
joystick->SetTouchpad(event.ctouchpad.x, event.ctouchpad.y, event.ctouchpad.touchpad,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case SDL_JOYDEVICEREMOVED:
|
case SDL_JOYDEVICEREMOVED:
|
||||||
LOG_DEBUG(Input, "Joystick removed with Instance_ID {}", event.jdevice.which);
|
LOG_DEBUG(Input, "Joystick removed with Instance_ID {}", event.jdevice.which);
|
||||||
@ -691,6 +715,20 @@ private:
|
|||||||
std::shared_ptr<SDLJoystick> joystick;
|
std::shared_ptr<SDLJoystick> joystick;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SDLTouch final : public Input::TouchDevice {
|
||||||
|
public:
|
||||||
|
explicit SDLTouch(std::shared_ptr<SDLJoystick> joystick_, int pad_)
|
||||||
|
: joystick(std::move(joystick_)), pad(pad_) {}
|
||||||
|
|
||||||
|
std::tuple<float, float, bool> GetStatus() const override {
|
||||||
|
return joystick->GetTouch(pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<SDLJoystick> joystick;
|
||||||
|
const int pad;
|
||||||
|
};
|
||||||
|
|
||||||
/// A button device factory that creates button devices from SDL joystick
|
/// A button device factory that creates button devices from SDL joystick
|
||||||
class SDLButtonFactory final : public Input::Factory<Input::ButtonDevice> {
|
class SDLButtonFactory final : public Input::Factory<Input::ButtonDevice> {
|
||||||
public:
|
public:
|
||||||
@ -810,6 +848,30 @@ public:
|
|||||||
return std::make_unique<SDLMotion>(joystick);
|
return std::make_unique<SDLMotion>(joystick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SDLState& state;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* A factory that creates a TouchDevice from an SDL Touchpad
|
||||||
|
*/
|
||||||
|
class SDLTouchFactory final : public Input::Factory<Input::TouchDevice> {
|
||||||
|
public:
|
||||||
|
explicit SDLTouchFactory(SDLState& state_) : state(state_) {}
|
||||||
|
/**
|
||||||
|
* Creates touch device from touchpad
|
||||||
|
* @param params contains parameters for creating the device:
|
||||||
|
* - "guid": the guid of the joystick to bind
|
||||||
|
* - "port": the nth joystick of the same type
|
||||||
|
* - "touchpad": which touchpad to bind
|
||||||
|
*/
|
||||||
|
std::unique_ptr<Input::TouchDevice> Create(const Common::ParamPackage& params) override {
|
||||||
|
const std::string guid = params.Get("guid", "0");
|
||||||
|
const int port = params.Get("port", 0);
|
||||||
|
const int touchpad = params.Get("touchpad", 0);
|
||||||
|
auto joystick = state.GetSDLJoystickByGUID(guid, port);
|
||||||
|
return std::make_unique<SDLTouch>(joystick, touchpad);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDLState& state;
|
SDLState& state;
|
||||||
};
|
};
|
||||||
@ -819,7 +881,7 @@ SDLState::SDLState() {
|
|||||||
RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>(*this));
|
RegisterFactory<ButtonDevice>("sdl", std::make_shared<SDLButtonFactory>(*this));
|
||||||
RegisterFactory<AnalogDevice>("sdl", std::make_shared<SDLAnalogFactory>(*this));
|
RegisterFactory<AnalogDevice>("sdl", std::make_shared<SDLAnalogFactory>(*this));
|
||||||
RegisterFactory<MotionDevice>("sdl", std::make_shared<SDLMotionFactory>(*this));
|
RegisterFactory<MotionDevice>("sdl", std::make_shared<SDLMotionFactory>(*this));
|
||||||
|
RegisterFactory<TouchDevice>("sdl", std::make_shared<SDLTouchFactory>(*this));
|
||||||
// If the frontend is going to manage the event loop, then we dont start one here
|
// If the frontend is going to manage the event loop, then we dont start one here
|
||||||
start_thread = !SDL_WasInit(SDL_INIT_GAMECONTROLLER);
|
start_thread = !SDL_WasInit(SDL_INIT_GAMECONTROLLER);
|
||||||
if (start_thread && SDL_Init(SDL_INIT_GAMECONTROLLER) < 0) {
|
if (start_thread && SDL_Init(SDL_INIT_GAMECONTROLLER) < 0) {
|
||||||
@ -874,7 +936,7 @@ SDLState::~SDLState() {
|
|||||||
UnregisterFactory<ButtonDevice>("sdl");
|
UnregisterFactory<ButtonDevice>("sdl");
|
||||||
UnregisterFactory<AnalogDevice>("sdl");
|
UnregisterFactory<AnalogDevice>("sdl");
|
||||||
UnregisterFactory<MotionDevice>("sdl");
|
UnregisterFactory<MotionDevice>("sdl");
|
||||||
|
UnregisterFactory<TouchDevice>("sdl");
|
||||||
CloseJoysticks();
|
CloseJoysticks();
|
||||||
SDL_DelEventWatch(&SDLEventWatcher, this);
|
SDL_DelEventWatch(&SDLEventWatcher, this);
|
||||||
|
|
||||||
@ -956,6 +1018,30 @@ protected:
|
|||||||
SDLState& state;
|
SDLState& state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SDLTouchpadPoller final : public SDLPoller {
|
||||||
|
public:
|
||||||
|
explicit SDLTouchpadPoller(SDLState& state_) : SDLPoller(state_) {}
|
||||||
|
|
||||||
|
Common::ParamPackage GetNextInput() override {
|
||||||
|
SDL_Event event;
|
||||||
|
Common::ParamPackage params;
|
||||||
|
while (state.event_queue.Pop(event)) {
|
||||||
|
if (event.type != SDL_CONTROLLERTOUCHPADDOWN) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (event.type) {
|
||||||
|
case SDL_CONTROLLERTOUCHPADDOWN:
|
||||||
|
auto joystick = state.GetSDLJoystickBySDLID(event.ctouchpad.which);
|
||||||
|
params.Set("engine", "sdl");
|
||||||
|
params.Set("touchpad", event.ctouchpad.touchpad);
|
||||||
|
params.Set("port", joystick->GetPort());
|
||||||
|
params.Set("guid", joystick->GetGUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class SDLButtonPoller final : public SDLPoller {
|
class SDLButtonPoller final : public SDLPoller {
|
||||||
public:
|
public:
|
||||||
explicit SDLButtonPoller(SDLState& state_) : SDLPoller(state_) {}
|
explicit SDLButtonPoller(SDLState& state_) : SDLPoller(state_) {}
|
||||||
@ -1083,6 +1169,9 @@ SDLState::Pollers SDLState::GetPollers(InputCommon::Polling::DeviceType type) {
|
|||||||
case InputCommon::Polling::DeviceType::Button:
|
case InputCommon::Polling::DeviceType::Button:
|
||||||
pollers.emplace_back(std::make_unique<Polling::SDLButtonPoller>(*this));
|
pollers.emplace_back(std::make_unique<Polling::SDLButtonPoller>(*this));
|
||||||
break;
|
break;
|
||||||
|
case InputCommon::Polling::DeviceType::Touchpad:
|
||||||
|
pollers.emplace_back(std::make_unique<Polling::SDLTouchpadPoller>(*this));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return pollers;
|
return pollers;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2018 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ class SDLGameController;
|
|||||||
class SDLButtonFactory;
|
class SDLButtonFactory;
|
||||||
class SDLAnalogFactory;
|
class SDLAnalogFactory;
|
||||||
class SDLMotionFactory;
|
class SDLMotionFactory;
|
||||||
|
class SDLTouchFactory;
|
||||||
|
|
||||||
class SDLState : public State {
|
class SDLState : public State {
|
||||||
public:
|
public:
|
||||||
@ -62,6 +63,7 @@ private:
|
|||||||
std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
|
std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
|
||||||
std::mutex joystick_map_mutex;
|
std::mutex joystick_map_mutex;
|
||||||
|
|
||||||
|
std::shared_ptr<SDLTouchFactory> touch_factory;
|
||||||
std::shared_ptr<SDLButtonFactory> button_factory;
|
std::shared_ptr<SDLButtonFactory> button_factory;
|
||||||
std::shared_ptr<SDLAnalogFactory> analog_factory;
|
std::shared_ptr<SDLAnalogFactory> analog_factory;
|
||||||
std::shared_ptr<SDLMotionFactory> motion_factory;
|
std::shared_ptr<SDLMotionFactory> motion_factory;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user