early-access version 2733
This commit is contained in:
parent
9ebf8edc43
commit
a94e5f58e3
16 changed files with 289 additions and 179 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 2732.
|
This is the source code for early-access 2733.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ enum class PollingError {
|
||||||
enum class VibrationAmplificationType {
|
enum class VibrationAmplificationType {
|
||||||
Linear,
|
Linear,
|
||||||
Exponential,
|
Exponential,
|
||||||
|
Test,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Analog properties for calibration
|
// Analog properties for calibration
|
||||||
|
|
|
@ -27,12 +27,19 @@ void EmulatedConsole::SetTouchParams() {
|
||||||
// We can't use mouse as touch if native mouse is enabled
|
// We can't use mouse as touch if native mouse is enabled
|
||||||
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
|
touch_params[index++] = Common::ParamPackage{"engine:mouse,axis_x:10,axis_y:11,button:0"};
|
||||||
}
|
}
|
||||||
touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0"};
|
|
||||||
touch_params[index++] = Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1"};
|
|
||||||
touch_params[index++] =
|
touch_params[index++] =
|
||||||
Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536"};
|
Common::ParamPackage{"engine:touch,axis_x:0,axis_y:1,button:0,touch_id:0"};
|
||||||
touch_params[index++] =
|
touch_params[index++] =
|
||||||
Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072"};
|
Common::ParamPackage{"engine:touch,axis_x:2,axis_y:3,button:1,touch_id:1"};
|
||||||
|
touch_params[index++] =
|
||||||
|
Common::ParamPackage{"engine:touch,axis_x:4,axis_y:5,button:2,touch_id:2"};
|
||||||
|
touch_params[index++] =
|
||||||
|
Common::ParamPackage{"engine:touch,axis_x:6,axis_y:7,button:3,touch_id:3"};
|
||||||
|
touch_params[index++] =
|
||||||
|
Common::ParamPackage{"engine:cemuhookudp,axis_x:17,axis_y:18,button:65536,touch_id:0"};
|
||||||
|
touch_params[index++] =
|
||||||
|
Common::ParamPackage{"engine:cemuhookudp,axis_x:19,axis_y:20,button:131072,touch_id:1"};
|
||||||
|
|
||||||
const auto button_index =
|
const auto button_index =
|
||||||
static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
|
static_cast<u64>(Settings::values.touch_from_button_map_index.GetValue());
|
||||||
|
|
|
@ -884,18 +884,42 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::TestVibration(std::size_t device_index) {
|
bool EmulatedController::TestVibration(std::size_t device_index) {
|
||||||
static constexpr VibrationValue test_vibration = {
|
if (device_index >= output_devices.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!output_devices[device_index]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||||
|
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||||
|
|
||||||
|
if (!player.vibration_enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Common::Input::VibrationStatus test_vibration = {
|
||||||
.low_amplitude = 0.001f,
|
.low_amplitude = 0.001f,
|
||||||
.low_frequency = 160.0f,
|
.low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
|
||||||
.high_amplitude = 0.001f,
|
.high_amplitude = 0.001f,
|
||||||
.high_frequency = 320.0f,
|
.high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
|
||||||
|
.type = Common::Input::VibrationAmplificationType::Test,
|
||||||
|
};
|
||||||
|
|
||||||
|
const Common::Input::VibrationStatus zero_vibration = {
|
||||||
|
.low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
|
||||||
|
.low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
|
||||||
|
.high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude,
|
||||||
|
.high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
|
||||||
|
.type = Common::Input::VibrationAmplificationType::Test,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Send a slight vibration to test for rumble support
|
// Send a slight vibration to test for rumble support
|
||||||
SetVibration(device_index, test_vibration);
|
output_devices[device_index]->SetVibration(test_vibration);
|
||||||
|
|
||||||
// Stop any vibration and return the result
|
// Stop any vibration and return the result
|
||||||
return SetVibration(device_index, DEFAULT_VIBRATION_VALUE);
|
return output_devices[device_index]->SetVibration(zero_vibration) ==
|
||||||
|
Common::Input::VibrationError::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
|
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
#include "common/input.h"
|
#include "common/input.h"
|
||||||
|
@ -196,6 +197,9 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus&
|
||||||
x = std::clamp(x, 0.0f, 1.0f);
|
x = std::clamp(x, 0.0f, 1.0f);
|
||||||
y = std::clamp(y, 0.0f, 1.0f);
|
y = std::clamp(y, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
// Limit id to maximum number of fingers
|
||||||
|
status.id = std::clamp(status.id, 0, 16);
|
||||||
|
|
||||||
if (status.pressed.inverted) {
|
if (status.pressed.inverted) {
|
||||||
status.pressed.value = !status.pressed.value;
|
status.pressed.value = !status.pressed.value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,6 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
|
||||||
for (std::size_t id = 0; id < MAX_FINGERS; id++) {
|
for (std::size_t id = 0; id < MAX_FINGERS; id++) {
|
||||||
const auto& current_touch = touch_status[id];
|
const auto& current_touch = touch_status[id];
|
||||||
auto& finger = fingers[id];
|
auto& finger = fingers[id];
|
||||||
finger.position = current_touch.position;
|
|
||||||
finger.id = current_touch.id;
|
finger.id = current_touch.id;
|
||||||
|
|
||||||
if (finger.attribute.start_touch) {
|
if (finger.attribute.start_touch) {
|
||||||
|
@ -61,13 +60,18 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
|
||||||
if (!finger.pressed && current_touch.pressed) {
|
if (!finger.pressed && current_touch.pressed) {
|
||||||
finger.attribute.start_touch.Assign(1);
|
finger.attribute.start_touch.Assign(1);
|
||||||
finger.pressed = true;
|
finger.pressed = true;
|
||||||
|
finger.position = current_touch.position;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finger.pressed && !current_touch.pressed) {
|
if (finger.pressed && !current_touch.pressed) {
|
||||||
finger.attribute.raw = 0;
|
finger.attribute.raw = 0;
|
||||||
finger.attribute.end_touch.Assign(1);
|
finger.attribute.end_touch.Assign(1);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only update position if touch is not on a special frame
|
||||||
|
finger.position = current_touch.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<Core::HID::TouchFinger, MAX_FINGERS> active_fingers;
|
std::array<Core::HID::TouchFinger, MAX_FINGERS> active_fingers;
|
||||||
|
|
|
@ -113,7 +113,7 @@ IAppletResource::~IAppletResource() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
|
void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_INFO(Service_HID, "called");
|
LOG_DEBUG(Service_HID, "called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 1};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -197,7 +197,7 @@ private:
|
||||||
.InitializeVibrationDevice(vibration_device_handle);
|
.InitializeVibrationDevice(vibration_device_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
|
LOG_DEBUG(Service_HID, "called, npad_type={}, npad_id={}, device_index={}",
|
||||||
vibration_device_handle.npad_type, vibration_device_handle.npad_id,
|
vibration_device_handle.npad_type, vibration_device_handle.npad_id,
|
||||||
vibration_device_handle.device_index);
|
vibration_device_handle.device_index);
|
||||||
|
|
||||||
|
@ -370,7 +370,7 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
if (applet_resource == nullptr) {
|
if (applet_resource == nullptr) {
|
||||||
applet_resource = std::make_shared<IAppletResource>(system, service_context);
|
applet_resource = std::make_shared<IAppletResource>(system, service_context);
|
||||||
|
@ -387,7 +387,7 @@ void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->ActivateController(HidController::DebugPad);
|
applet_resource->ActivateController(HidController::DebugPad);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -399,7 +399,7 @@ void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->ActivateController(HidController::Touchscreen);
|
applet_resource->ActivateController(HidController::Touchscreen);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -411,7 +411,7 @@ void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->ActivateController(HidController::Mouse);
|
applet_resource->ActivateController(HidController::Mouse);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -423,7 +423,7 @@ void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->ActivateController(HidController::Keyboard);
|
applet_resource->ActivateController(HidController::Keyboard);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -452,7 +452,7 @@ void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->ActivateController(HidController::XPad);
|
applet_resource->ActivateController(HidController::XPad);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
|
LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}",
|
||||||
parameters.basic_xpad_id, parameters.applet_resource_user_id);
|
parameters.basic_xpad_id, parameters.applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -463,7 +463,7 @@ void Hid::GetXpadIDs(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto applet_resource_user_id{rp.Pop<u64>()};
|
const auto applet_resource_user_id{rp.Pop<u64>()};
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "(STUBBED) called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -524,7 +524,7 @@ void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||||
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
||||||
const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true);
|
const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true);
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
||||||
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
||||||
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
||||||
|
@ -547,7 +547,7 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||||
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
||||||
const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false);
|
const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false);
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
||||||
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
||||||
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
||||||
|
@ -598,7 +598,7 @@ void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) {
|
||||||
const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle,
|
const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle,
|
||||||
parameters.enable_sixaxis_sensor_fusion);
|
parameters.enable_sixaxis_sensor_fusion);
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
|
"called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, "
|
||||||
"device_index={}, applet_resource_user_id={}",
|
"device_index={}, applet_resource_user_id={}",
|
||||||
parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type,
|
parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type,
|
||||||
|
@ -625,7 +625,7 @@ void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
|
||||||
const auto result =
|
const auto result =
|
||||||
controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
|
controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion);
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
|
"called, npad_type={}, npad_id={}, device_index={}, parameter1={}, "
|
||||||
"parameter2={}, applet_resource_user_id={}",
|
"parameter2={}, applet_resource_user_id={}",
|
||||||
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
||||||
|
@ -684,7 +684,7 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) {
|
||||||
controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
|
controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters);
|
||||||
const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
|
const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true);
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
||||||
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
||||||
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
||||||
|
@ -710,7 +710,7 @@ void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
|
||||||
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
||||||
const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
|
const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode);
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
|
"called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, "
|
||||||
"applet_resource_user_id={}",
|
"applet_resource_user_id={}",
|
||||||
sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index,
|
sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index,
|
||||||
|
@ -760,7 +760,7 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
|
||||||
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
auto& controller = GetAppletResource()->GetController<Controller_NPad>(HidController::NPad);
|
||||||
const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
|
const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode);
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
||||||
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
||||||
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
||||||
|
@ -855,7 +855,7 @@ void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.SetSupportedStyleSet({parameters.supported_styleset});
|
.SetSupportedStyleSet({parameters.supported_styleset});
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
|
LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}",
|
||||||
parameters.supported_styleset, parameters.applet_resource_user_id);
|
parameters.supported_styleset, parameters.applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -882,7 +882,7 @@ void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.SetSupportedNpadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
|
.SetSupportedNpadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -894,7 +894,7 @@ void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->ActivateController(HidController::NPad);
|
applet_resource->ActivateController(HidController::NPad);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -906,7 +906,7 @@ void Hid::DeactivateNpad(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->DeactivateController(HidController::NPad);
|
applet_resource->DeactivateController(HidController::NPad);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -924,7 +924,7 @@ void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
const auto parameters{rp.PopRaw<Parameters>()};
|
const auto parameters{rp.PopRaw<Parameters>()};
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
|
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}",
|
||||||
parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
|
parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown);
|
||||||
|
|
||||||
// Games expect this event to be signaled after calling this function
|
// Games expect this event to be signaled after calling this function
|
||||||
|
@ -951,7 +951,7 @@ void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.DisconnectNpad(parameters.npad_id);
|
.DisconnectNpad(parameters.npad_id);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
|
LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id,
|
||||||
parameters.applet_resource_user_id);
|
parameters.applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -985,7 +985,7 @@ void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->ActivateController(HidController::NPad);
|
applet_resource->ActivateController(HidController::NPad);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
|
LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
|
||||||
parameters.applet_resource_user_id);
|
parameters.applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -999,7 +999,7 @@ void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type);
|
applet_resource->GetController<Controller_NPad>(HidController::NPad).SetHoldType(hold_type);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
|
||||||
applet_resource_user_id, hold_type);
|
applet_resource_user_id, hold_type);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -1093,7 +1093,7 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
|
.MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
|
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
|
||||||
npad_id_1, npad_id_2, applet_resource_user_id);
|
npad_id_1, npad_id_2, applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -1106,7 +1106,7 @@ void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad).StartLRAssignmentMode();
|
applet_resource->GetController<Controller_NPad>(HidController::NPad).StartLRAssignmentMode();
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -1118,7 +1118,7 @@ void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad).StopLRAssignmentMode();
|
applet_resource->GetController<Controller_NPad>(HidController::NPad).StopLRAssignmentMode();
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -1132,7 +1132,7 @@ void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.SetNpadHandheldActivationMode(activation_mode);
|
.SetNpadHandheldActivationMode(activation_mode);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}",
|
||||||
applet_resource_user_id, activation_mode);
|
applet_resource_user_id, activation_mode);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -1160,7 +1160,7 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) {
|
||||||
const bool res = applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
const bool res = applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.SwapNpadAssignment(npad_id_1, npad_id_2);
|
.SwapNpadAssignment(npad_id_1, npad_id_2);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
|
LOG_DEBUG(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}",
|
||||||
npad_id_1, npad_id_2, applet_resource_user_id);
|
npad_id_1, npad_id_2, applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
@ -1309,7 +1309,7 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
|
LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}",
|
||||||
vibration_device_info.type, vibration_device_info.position);
|
vibration_device_info.type, vibration_device_info.position);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 4};
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
@ -1366,7 +1366,7 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
|
void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_INFO(Service_HID, "called");
|
LOG_DEBUG(Service_HID, "called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -1379,7 +1379,7 @@ void Hid::PermitVibration(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
Settings::values.vibration_enabled.SetValue(can_vibrate);
|
Settings::values.vibration_enabled.SetValue(can_vibrate);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, can_vibrate={}", can_vibrate);
|
LOG_DEBUG(Service_HID, "called, can_vibrate={}", can_vibrate);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -1527,7 +1527,7 @@ void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.SetPermitVibrationSession(true);
|
.SetPermitVibrationSession(true);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -1537,7 +1537,7 @@ void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
|
||||||
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
applet_resource->GetController<Controller_NPad>(HidController::NPad)
|
||||||
.SetPermitVibrationSession(false);
|
.SetPermitVibrationSession(false);
|
||||||
|
|
||||||
LOG_INFO(Service_HID, "called");
|
LOG_DEBUG(Service_HID, "called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
|
@ -1554,7 +1554,7 @@ void Hid::IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
const auto parameters{rp.PopRaw<Parameters>()};
|
const auto parameters{rp.PopRaw<Parameters>()};
|
||||||
|
|
||||||
LOG_INFO(Service_HID,
|
LOG_DEBUG(Service_HID,
|
||||||
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
||||||
parameters.vibration_device_handle.npad_type,
|
parameters.vibration_device_handle.npad_type,
|
||||||
parameters.vibration_device_handle.npad_id,
|
parameters.vibration_device_handle.npad_id,
|
||||||
|
|
|
@ -434,6 +434,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
while (initialized) {
|
while (initialized) {
|
||||||
SDL_PumpEvents();
|
SDL_PumpEvents();
|
||||||
|
SendVibrations();
|
||||||
std::this_thread::sleep_for(1ms);
|
std::this_thread::sleep_for(1ms);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -531,13 +532,31 @@ Common::Input::VibrationError SDLDriver::SetRumble(
|
||||||
.type = Common::Input::VibrationAmplificationType::Exponential,
|
.type = Common::Input::VibrationAmplificationType::Exponential,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (vibration.type == Common::Input::VibrationAmplificationType::Test) {
|
||||||
if (!joystick->RumblePlay(new_vibration)) {
|
if (!joystick->RumblePlay(new_vibration)) {
|
||||||
return Common::Input::VibrationError::Unknown;
|
return Common::Input::VibrationError::Unknown;
|
||||||
}
|
}
|
||||||
|
return Common::Input::VibrationError::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
vibration_queue.Push(VibrationRequest{
|
||||||
|
.identifier = identifier,
|
||||||
|
.vibration = new_vibration,
|
||||||
|
});
|
||||||
|
|
||||||
return Common::Input::VibrationError::None;
|
return Common::Input::VibrationError::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SDLDriver::SendVibrations() {
|
||||||
|
while (!vibration_queue.Empty()) {
|
||||||
|
VibrationRequest request;
|
||||||
|
vibration_queue.Pop(request);
|
||||||
|
const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(),
|
||||||
|
static_cast<int>(request.identifier.port));
|
||||||
|
joystick->RumblePlay(request.vibration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid,
|
Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid,
|
||||||
s32 axis, float value) const {
|
s32 axis, float value) const {
|
||||||
Common::ParamPackage params{};
|
Common::ParamPackage params{};
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/threadsafe_queue.h"
|
||||||
#include "input_common/input_engine.h"
|
#include "input_common/input_engine.h"
|
||||||
|
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
|
@ -64,12 +65,20 @@ public:
|
||||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct VibrationRequest {
|
||||||
|
PadIdentifier identifier;
|
||||||
|
Common::Input::VibrationStatus vibration;
|
||||||
|
};
|
||||||
|
|
||||||
void InitJoystick(int joystick_index);
|
void InitJoystick(int joystick_index);
|
||||||
void CloseJoystick(SDL_Joystick* sdl_joystick);
|
void CloseJoystick(SDL_Joystick* sdl_joystick);
|
||||||
|
|
||||||
/// Needs to be called before SDL_QuitSubSystem.
|
/// Needs to be called before SDL_QuitSubSystem.
|
||||||
void CloseJoysticks();
|
void CloseJoysticks();
|
||||||
|
|
||||||
|
/// Takes all vibrations from the queue and sends the command to the controller
|
||||||
|
void SendVibrations();
|
||||||
|
|
||||||
Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis,
|
Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis,
|
||||||
float value = 0.1f) const;
|
float value = 0.1f) const;
|
||||||
Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid,
|
Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid,
|
||||||
|
@ -107,6 +116,9 @@ private:
|
||||||
/// Returns true if the button is on the left joycon
|
/// Returns true if the button is on the left joycon
|
||||||
bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const;
|
bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const;
|
||||||
|
|
||||||
|
/// Queue of vibration request to controllers
|
||||||
|
Common::SPSCQueue<VibrationRequest> vibration_queue;
|
||||||
|
|
||||||
/// Map of GUID of a list of corresponding virtual Joysticks
|
/// Map of GUID of a list of corresponding virtual Joysticks
|
||||||
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;
|
||||||
|
|
|
@ -14,38 +14,93 @@ constexpr PadIdentifier identifier = {
|
||||||
|
|
||||||
TouchScreen::TouchScreen(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
|
TouchScreen::TouchScreen(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
|
||||||
PreSetController(identifier);
|
PreSetController(identifier);
|
||||||
|
ReleaseAllTouch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreen::TouchMoved(float x, float y, std::size_t finger) {
|
void TouchScreen::TouchMoved(float x, float y, std::size_t finger_id) {
|
||||||
if (finger >= 16) {
|
const auto index = GetIndexFromFingerId(finger_id);
|
||||||
|
if (!index) {
|
||||||
|
// Touch doesn't exist handle it as a new one
|
||||||
|
TouchPressed(x, y, finger_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TouchPressed(x, y, finger);
|
const auto i = index.value();
|
||||||
|
fingers[i].is_active = true;
|
||||||
|
SetButton(identifier, static_cast<int>(i), true);
|
||||||
|
SetAxis(identifier, static_cast<int>(i * 2), x);
|
||||||
|
SetAxis(identifier, static_cast<int>(i * 2 + 1), y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreen::TouchPressed(float x, float y, std::size_t finger) {
|
void TouchScreen::TouchPressed(float x, float y, std::size_t finger_id) {
|
||||||
if (finger >= 16) {
|
if (GetIndexFromFingerId(finger_id)) {
|
||||||
|
// Touch already exist. Just update the data
|
||||||
|
TouchMoved(x, y, finger_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetButton(identifier, static_cast<int>(finger), true);
|
const auto index = GetNextFreeIndex();
|
||||||
SetAxis(identifier, static_cast<int>(finger * 2), x);
|
if (!index) {
|
||||||
SetAxis(identifier, static_cast<int>(finger * 2 + 1), y);
|
// No free entries. Ignore input
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto i = index.value();
|
||||||
|
fingers[i].is_enabled = true;
|
||||||
|
fingers[i].finger_id = finger_id;
|
||||||
|
TouchMoved(x, y, finger_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreen::TouchReleased(std::size_t finger) {
|
void TouchScreen::TouchReleased(std::size_t finger_id) {
|
||||||
if (finger >= 16) {
|
const auto index = GetIndexFromFingerId(finger_id);
|
||||||
|
if (!index) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SetButton(identifier, static_cast<int>(finger), false);
|
const auto i = index.value();
|
||||||
SetAxis(identifier, static_cast<int>(finger * 2), 0.0f);
|
fingers[i].is_enabled = false;
|
||||||
SetAxis(identifier, static_cast<int>(finger * 2 + 1), 0.0f);
|
SetButton(identifier, static_cast<int>(i), false);
|
||||||
|
SetAxis(identifier, static_cast<int>(i * 2), 0.0f);
|
||||||
|
SetAxis(identifier, static_cast<int>(i * 2 + 1), 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::size_t> TouchScreen::GetIndexFromFingerId(std::size_t finger_id) const {
|
||||||
|
for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) {
|
||||||
|
const auto& finger = fingers[index];
|
||||||
|
if (!finger.is_enabled) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (finger.finger_id == finger_id) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::size_t> TouchScreen::GetNextFreeIndex() const {
|
||||||
|
for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) {
|
||||||
|
if (!fingers[index].is_enabled) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TouchScreen::ClearActiveFlag() {
|
||||||
|
for (auto& finger : fingers) {
|
||||||
|
finger.is_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TouchScreen::ReleaseInactiveTouch() {
|
||||||
|
for (const auto& finger : fingers) {
|
||||||
|
if (!finger.is_active) {
|
||||||
|
TouchReleased(finger.finger_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TouchScreen::ReleaseAllTouch() {
|
void TouchScreen::ReleaseAllTouch() {
|
||||||
for (int index = 0; index < 16; ++index) {
|
for (const auto& finger : fingers) {
|
||||||
SetButton(identifier, index, false);
|
if (finger.is_enabled) {
|
||||||
SetAxis(identifier, index * 2, 0.0f);
|
TouchReleased(finger.finger_id);
|
||||||
SetAxis(identifier, index * 2 + 1, 0.0f);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,41 +3,65 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
#include "input_common/input_engine.h"
|
#include "input_common/input_engine.h"
|
||||||
|
|
||||||
namespace InputCommon {
|
namespace InputCommon {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A button device factory representing a keyboard. It receives keyboard events and forward them
|
* A touch device factory representing a touch screen. It receives touch events and forward them
|
||||||
* to all button devices it created.
|
* to all touch devices it created.
|
||||||
*/
|
*/
|
||||||
class TouchScreen final : public InputEngine {
|
class TouchScreen final : public InputEngine {
|
||||||
public:
|
public:
|
||||||
explicit TouchScreen(std::string input_engine_);
|
explicit TouchScreen(std::string input_engine_);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that mouse has moved.
|
* Signals that touch has moved and marks this touch point as active
|
||||||
* @param x the x-coordinate of the cursor
|
* @param x new horizontal position
|
||||||
* @param y the y-coordinate of the cursor
|
* @param y new vertical position
|
||||||
* @param center_x the x-coordinate of the middle of the screen
|
* @param finger_id of the touch point to be updated
|
||||||
* @param center_y the y-coordinate of the middle of the screen
|
|
||||||
*/
|
*/
|
||||||
void TouchMoved(float x, float y, std::size_t finger);
|
void TouchMoved(float x, float y, std::size_t finger_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the status of all buttons bound with the key to pressed
|
* Signals and creates a new touch point with this finger id
|
||||||
* @param key_code the code of the key to press
|
* @param x starting horizontal position
|
||||||
|
* @param y starting vertical position
|
||||||
|
* @param finger_id to be assigned to the new touch point
|
||||||
*/
|
*/
|
||||||
void TouchPressed(float x, float y, std::size_t finger);
|
void TouchPressed(float x, float y, std::size_t finger_id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the status of all buttons bound with the key to released
|
* Signals and resets the touch point related to the this finger id
|
||||||
* @param key_code the code of the key to release
|
* @param finger_id to be released
|
||||||
*/
|
*/
|
||||||
void TouchReleased(std::size_t finger);
|
void TouchReleased(std::size_t finger_id);
|
||||||
|
|
||||||
|
/// Resets the active flag for each touch point
|
||||||
|
void ClearActiveFlag();
|
||||||
|
|
||||||
|
/// Releases all touch that haven't been marked as active
|
||||||
|
void ReleaseInactiveTouch();
|
||||||
|
|
||||||
/// Resets all inputs to their initial value
|
/// Resets all inputs to their initial value
|
||||||
void ReleaseAllTouch();
|
void ReleaseAllTouch();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static constexpr std::size_t MAX_FINGER_COUNT = 16;
|
||||||
|
|
||||||
|
struct TouchStatus {
|
||||||
|
std::size_t finger_id{};
|
||||||
|
bool is_enabled{};
|
||||||
|
bool is_active{};
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<std::size_t> GetIndexFromFingerId(std::size_t finger_id) const;
|
||||||
|
|
||||||
|
std::optional<std::size_t> GetNextFreeIndex() const;
|
||||||
|
|
||||||
|
std::array<TouchStatus, MAX_FINGER_COUNT> fingers{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace InputCommon
|
} // namespace InputCommon
|
||||||
|
|
|
@ -1777,7 +1777,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||||
}
|
}
|
||||||
attachments.push_back(color_buffer->RenderTarget());
|
attachments.push_back(color_buffer->RenderTarget());
|
||||||
renderpass_key.color_formats[index] = color_buffer->format;
|
renderpass_key.color_formats[index] = color_buffer->format;
|
||||||
num_layers = std::max(num_layers, color_buffer->range.extent.layers);
|
num_layers = std::min(num_layers, color_buffer->range.extent.layers);
|
||||||
images[num_images] = color_buffer->ImageHandle();
|
images[num_images] = color_buffer->ImageHandle();
|
||||||
image_ranges[num_images] = MakeSubresourceRange(color_buffer);
|
image_ranges[num_images] = MakeSubresourceRange(color_buffer);
|
||||||
samples = color_buffer->Samples();
|
samples = color_buffer->Samples();
|
||||||
|
@ -1787,7 +1787,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime,
|
||||||
if (depth_buffer) {
|
if (depth_buffer) {
|
||||||
attachments.push_back(depth_buffer->RenderTarget());
|
attachments.push_back(depth_buffer->RenderTarget());
|
||||||
renderpass_key.depth_format = depth_buffer->format;
|
renderpass_key.depth_format = depth_buffer->format;
|
||||||
num_layers = std::max(num_layers, depth_buffer->range.extent.layers);
|
num_layers = std::min(num_layers, depth_buffer->range.extent.layers);
|
||||||
images[num_images] = depth_buffer->ImageHandle();
|
images[num_images] = depth_buffer->ImageHandle();
|
||||||
const VkImageSubresourceRange subresource_range = MakeSubresourceRange(depth_buffer);
|
const VkImageSubresourceRange subresource_range = MakeSubresourceRange(depth_buffer);
|
||||||
image_ranges[num_images] = subresource_range;
|
image_ranges[num_images] = subresource_range;
|
||||||
|
|
|
@ -683,6 +683,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||||
ext_sampler_filter_minmax = false;
|
ext_sampler_filter_minmax = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (khr_workgroup_memory_explicit_layout && !is_shader_int16_supported) {
|
||||||
|
// TODO(lat9nq): Find a proper fix for this
|
||||||
|
LOG_WARNING(Render_Vulkan, "Disabling VK_KHR_workgroup_memory_explicit_layout due to a "
|
||||||
|
"yuzu bug when host driver does not support 16-bit integers");
|
||||||
|
khr_workgroup_memory_explicit_layout = false;
|
||||||
|
}
|
||||||
|
|
||||||
const bool is_intel_windows = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS;
|
const bool is_intel_windows = driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS;
|
||||||
const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA;
|
const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA;
|
||||||
|
|
|
@ -772,65 +772,25 @@ void GRenderWindow::wheelEvent(QWheelEvent* event) {
|
||||||
void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) {
|
void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) {
|
||||||
QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
|
QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
|
||||||
for (const auto& touch_point : touch_points) {
|
for (const auto& touch_point : touch_points) {
|
||||||
if (!TouchUpdate(touch_point)) {
|
const auto [x, y] = ScaleTouch(touch_point.pos());
|
||||||
TouchStart(touch_point);
|
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
||||||
}
|
input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, touch_point.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) {
|
void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) {
|
||||||
QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
|
QList<QTouchEvent::TouchPoint> touch_points = event->touchPoints();
|
||||||
|
input_subsystem->GetTouchScreen()->ClearActiveFlag();
|
||||||
for (const auto& touch_point : touch_points) {
|
for (const auto& touch_point : touch_points) {
|
||||||
if (!TouchUpdate(touch_point)) {
|
const auto [x, y] = ScaleTouch(touch_point.pos());
|
||||||
TouchStart(touch_point);
|
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
||||||
}
|
input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, touch_point.id());
|
||||||
}
|
|
||||||
// Release all inactive points
|
|
||||||
for (std::size_t id = 0; id < touch_ids.size(); ++id) {
|
|
||||||
if (!TouchExist(touch_ids[id], touch_points)) {
|
|
||||||
touch_ids[id] = 0;
|
|
||||||
input_subsystem->GetTouchScreen()->TouchReleased(id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
input_subsystem->GetTouchScreen()->ReleaseInactiveTouch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GRenderWindow::TouchEndEvent() {
|
void GRenderWindow::TouchEndEvent() {
|
||||||
for (std::size_t id = 0; id < touch_ids.size(); ++id) {
|
input_subsystem->GetTouchScreen()->ReleaseAllTouch();
|
||||||
if (touch_ids[id] != 0) {
|
|
||||||
touch_ids[id] = 0;
|
|
||||||
input_subsystem->GetTouchScreen()->TouchReleased(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GRenderWindow::TouchStart(const QTouchEvent::TouchPoint& touch_point) {
|
|
||||||
for (std::size_t id = 0; id < touch_ids.size(); ++id) {
|
|
||||||
if (touch_ids[id] == 0) {
|
|
||||||
touch_ids[id] = touch_point.id() + 1;
|
|
||||||
const auto [x, y] = ScaleTouch(touch_point.pos());
|
|
||||||
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
|
||||||
input_subsystem->GetTouchScreen()->TouchPressed(touch_x, touch_y, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GRenderWindow::TouchUpdate(const QTouchEvent::TouchPoint& touch_point) {
|
|
||||||
for (std::size_t id = 0; id < touch_ids.size(); ++id) {
|
|
||||||
if (touch_ids[id] == static_cast<std::size_t>(touch_point.id() + 1)) {
|
|
||||||
const auto [x, y] = ScaleTouch(touch_point.pos());
|
|
||||||
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
|
||||||
input_subsystem->GetTouchScreen()->TouchMoved(touch_x, touch_y, id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GRenderWindow::TouchExist(std::size_t id,
|
|
||||||
const QList<QTouchEvent::TouchPoint>& touch_points) const {
|
|
||||||
return std::any_of(touch_points.begin(), touch_points.end(), [id](const auto& point) {
|
|
||||||
return id == static_cast<std::size_t>(point.id() + 1);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GRenderWindow::event(QEvent* event) {
|
bool GRenderWindow::event(QEvent* event) {
|
||||||
|
|
|
@ -217,10 +217,6 @@ private:
|
||||||
void TouchUpdateEvent(const QTouchEvent* event);
|
void TouchUpdateEvent(const QTouchEvent* event);
|
||||||
void TouchEndEvent();
|
void TouchEndEvent();
|
||||||
|
|
||||||
void TouchStart(const QTouchEvent::TouchPoint& touch_point);
|
|
||||||
bool TouchUpdate(const QTouchEvent::TouchPoint& touch_point);
|
|
||||||
bool TouchExist(std::size_t id, const QList<QTouchEvent::TouchPoint>& touch_points) const;
|
|
||||||
|
|
||||||
void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
|
void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override;
|
||||||
|
|
||||||
bool InitializeOpenGL();
|
bool InitializeOpenGL();
|
||||||
|
@ -246,8 +242,6 @@ private:
|
||||||
bool first_frame = false;
|
bool first_frame = false;
|
||||||
InputCommon::TasInput::TasState last_tas_state;
|
InputCommon::TasInput::TasState last_tas_state;
|
||||||
|
|
||||||
std::array<std::size_t, 16> touch_ids{};
|
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -93,7 +93,7 @@ void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnFingerUp() {
|
void EmuWindow_SDL2::OnFingerUp() {
|
||||||
input_subsystem->GetTouchScreen()->TouchReleased(0);
|
input_subsystem->GetTouchScreen()->ReleaseAllTouch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
|
void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
|
||||||
|
|
Loading…
Reference in a new issue