From a94e5f58e3fbd0fecf2dcf8ad20e1f1582b15c11 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Wed, 25 May 2022 04:31:11 +0200 Subject: [PATCH] early-access version 2733 --- README.md | 2 +- src/common/input.h | 1 + src/core/hid/emulated_console.cpp | 15 +- src/core/hid/emulated_controller.cpp | 34 +++- src/core/hid/input_converter.cpp | 4 + .../service/hid/controllers/touchscreen.cpp | 6 +- src/core/hle/service/hid/hid.cpp | 154 +++++++++--------- src/input_common/drivers/sdl_driver.cpp | 23 ++- src/input_common/drivers/sdl_driver.h | 12 ++ src/input_common/drivers/touch_screen.cpp | 89 ++++++++-- src/input_common/drivers/touch_screen.h | 52 ++++-- .../renderer_vulkan/vk_texture_cache.cpp | 4 +- .../vulkan_common/vulkan_device.cpp | 6 + src/yuzu/bootmanager.cpp | 58 +------ src/yuzu/bootmanager.h | 6 - src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 2 +- 16 files changed, 289 insertions(+), 179 deletions(-) diff --git a/README.md b/README.md index 375f4916a..7861617ba 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2732. +This is the source code for early-access 2733. ## Legal Notice diff --git a/src/common/input.h b/src/common/input.h index 54fcb24b0..bb42aaacc 100755 --- a/src/common/input.h +++ b/src/common/input.h @@ -72,6 +72,7 @@ enum class PollingError { enum class VibrationAmplificationType { Linear, Exponential, + Test, }; // Analog properties for calibration diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp index fd220ccb5..aac45907d 100755 --- a/src/core/hid/emulated_console.cpp +++ b/src/core/hid/emulated_console.cpp @@ -27,12 +27,19 @@ void EmulatedConsole::SetTouchParams() { // 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: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++] = - 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++] = - 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 = static_cast(Settings::values.touch_from_button_map_index.GetValue()); diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index ba1dcd171..bd2384515 100755 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -884,18 +884,42 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v } 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_frequency = 160.0f, + .low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency, .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 - SetVibration(device_index, test_vibration); + output_devices[device_index]->SetVibration(test_vibration); // 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) { diff --git a/src/core/hid/input_converter.cpp b/src/core/hid/input_converter.cpp index 3c26260f3..18d9f042d 100755 --- a/src/core/hid/input_converter.cpp +++ b/src/core/hid/input_converter.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include "common/input.h" @@ -196,6 +197,9 @@ Common::Input::TouchStatus TransformToTouch(const Common::Input::CallbackStatus& x = std::clamp(x, 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) { status.pressed.value = !status.pressed.value; } diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index 108ce5a41..1da8d3eb0 100755 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -44,7 +44,6 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin for (std::size_t id = 0; id < MAX_FINGERS; id++) { const auto& current_touch = touch_status[id]; auto& finger = fingers[id]; - finger.position = current_touch.position; finger.id = current_touch.id; 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) { finger.attribute.start_touch.Assign(1); finger.pressed = true; + finger.position = current_touch.position; continue; } if (finger.pressed && !current_touch.pressed) { finger.attribute.raw = 0; 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 active_fingers; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index eabf11b16..44f892da9 100755 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -113,7 +113,7 @@ IAppletResource::~IAppletResource() { } void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { - LOG_INFO(Service_HID, "called"); + LOG_DEBUG(Service_HID, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(ResultSuccess); @@ -197,9 +197,9 @@ private: .InitializeVibrationDevice(vibration_device_handle); } - LOG_INFO(Service_HID, "called, npad_type={}, npad_id={}, device_index={}", - vibration_device_handle.npad_type, vibration_device_handle.npad_id, - vibration_device_handle.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.device_index); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -370,7 +370,7 @@ void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop()}; - 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) { applet_resource = std::make_shared(system, service_context); @@ -387,7 +387,7 @@ void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) { 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}; rb.Push(ResultSuccess); @@ -399,7 +399,7 @@ void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) { 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}; rb.Push(ResultSuccess); @@ -411,7 +411,7 @@ void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) { 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}; rb.Push(ResultSuccess); @@ -423,7 +423,7 @@ void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) { 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}; rb.Push(ResultSuccess); @@ -452,8 +452,8 @@ void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) { applet_resource->ActivateController(HidController::XPad); - LOG_INFO(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", - parameters.basic_xpad_id, parameters.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); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -463,7 +463,7 @@ void Hid::GetXpadIDs(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop()}; - 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}; rb.Push(ResultSuccess); @@ -524,10 +524,10 @@ void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) { auto& controller = GetAppletResource()->GetController(HidController::NPad); const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, true); - LOG_INFO(Service_HID, - "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", - parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, - parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -547,10 +547,10 @@ void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) { auto& controller = GetAppletResource()->GetController(HidController::NPad); const auto result = controller.SetSixAxisEnabled(parameters.sixaxis_handle, false); - LOG_INFO(Service_HID, - "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", - parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, - parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -598,12 +598,12 @@ void Hid::EnableSixAxisSensorFusion(Kernel::HLERequestContext& ctx) { const auto result = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, parameters.enable_sixaxis_sensor_fusion); - LOG_INFO(Service_HID, - "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, " - "device_index={}, applet_resource_user_id={}", - parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type, - parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, - parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, enable_sixaxis_sensor_fusion={}, npad_type={}, npad_id={}, " + "device_index={}, applet_resource_user_id={}", + parameters.enable_sixaxis_sensor_fusion, parameters.sixaxis_handle.npad_type, + parameters.sixaxis_handle.npad_id, parameters.sixaxis_handle.device_index, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -625,12 +625,12 @@ void Hid::SetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { const auto result = controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, parameters.sixaxis_fusion); - LOG_INFO(Service_HID, - "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, " - "parameter2={}, applet_resource_user_id={}", - parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, - parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1, - parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, parameter1={}, " + "parameter2={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.sixaxis_fusion.parameter1, + parameters.sixaxis_fusion.parameter2, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -684,10 +684,10 @@ void Hid::ResetSixAxisSensorFusionParameters(Kernel::HLERequestContext& ctx) { controller.SetSixAxisFusionParameters(parameters.sixaxis_handle, fusion_parameters); const auto result2 = controller.SetSixAxisFusionEnabled(parameters.sixaxis_handle, true); - LOG_INFO(Service_HID, - "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", - parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, - parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; if (result1.IsError()) { @@ -710,11 +710,11 @@ void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { auto& controller = GetAppletResource()->GetController(HidController::NPad); const auto result = controller.SetGyroscopeZeroDriftMode(sixaxis_handle, drift_mode); - LOG_INFO(Service_HID, - "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, " - "applet_resource_user_id={}", - sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index, - drift_mode, applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, drift_mode={}, " + "applet_resource_user_id={}", + sixaxis_handle.npad_type, sixaxis_handle.npad_id, sixaxis_handle.device_index, + drift_mode, applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -760,10 +760,10 @@ void Hid::ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { auto& controller = GetAppletResource()->GetController(HidController::NPad); const auto result = controller.SetGyroscopeZeroDriftMode(parameters.sixaxis_handle, drift_mode); - LOG_INFO(Service_HID, - "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", - parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, - parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id, + parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); @@ -855,8 +855,8 @@ void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad) .SetSupportedStyleSet({parameters.supported_styleset}); - LOG_INFO(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}", - parameters.supported_styleset, parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, "called, supported_styleset={}, applet_resource_user_id={}", + parameters.supported_styleset, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -882,7 +882,7 @@ void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad) .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}; rb.Push(ResultSuccess); @@ -894,7 +894,7 @@ void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) { 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}; rb.Push(ResultSuccess); @@ -906,7 +906,7 @@ void Hid::DeactivateNpad(Kernel::HLERequestContext& ctx) { 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}; rb.Push(ResultSuccess); @@ -924,8 +924,8 @@ void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { const auto parameters{rp.PopRaw()}; - LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", - parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown); + LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", + parameters.npad_id, parameters.applet_resource_user_id, parameters.unknown); // Games expect this event to be signaled after calling this function applet_resource->GetController(HidController::NPad) @@ -951,8 +951,8 @@ void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad) .DisconnectNpad(parameters.npad_id); - LOG_INFO(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, - parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", parameters.npad_id, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -985,8 +985,8 @@ void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { applet_resource->ActivateController(HidController::NPad); - LOG_INFO(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision, - parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision, + parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -999,8 +999,8 @@ void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad).SetHoldType(hold_type); - LOG_INFO(Service_HID, "called, applet_resource_user_id={}, hold_type={}", - applet_resource_user_id, hold_type); + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}", + applet_resource_user_id, hold_type); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -1093,8 +1093,8 @@ void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad) .MergeSingleJoyAsDualJoy(npad_id_1, npad_id_2); - LOG_INFO(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", - 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); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -1106,7 +1106,7 @@ void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { applet_resource->GetController(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}; rb.Push(ResultSuccess); @@ -1118,7 +1118,7 @@ void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { applet_resource->GetController(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}; rb.Push(ResultSuccess); @@ -1132,8 +1132,8 @@ void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad) .SetNpadHandheldActivationMode(activation_mode); - LOG_INFO(Service_HID, "called, applet_resource_user_id={}, activation_mode={}", - applet_resource_user_id, activation_mode); + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, activation_mode={}", + applet_resource_user_id, activation_mode); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -1160,8 +1160,8 @@ void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { const bool res = applet_resource->GetController(HidController::NPad) .SwapNpadAssignment(npad_id_1, npad_id_2); - LOG_INFO(Service_HID, "called, npad_id_1={}, npad_id_2={}, applet_resource_user_id={}", - 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); IPC::ResponseBuilder rb{ctx, 2}; if (res) { @@ -1309,8 +1309,8 @@ void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { break; } - LOG_INFO(Service_HID, "called, vibration_device_type={}, vibration_device_position={}", - vibration_device_info.type, vibration_device_info.position); + LOG_DEBUG(Service_HID, "called, vibration_device_type={}, vibration_device_position={}", + vibration_device_info.type, vibration_device_info.position); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); @@ -1366,7 +1366,7 @@ void Hid::GetActualVibrationValue(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}; rb.Push(ResultSuccess); @@ -1379,7 +1379,7 @@ void Hid::PermitVibration(Kernel::HLERequestContext& ctx) { 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}; rb.Push(ResultSuccess); @@ -1527,7 +1527,7 @@ void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad) .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}; rb.Push(ResultSuccess); @@ -1537,7 +1537,7 @@ void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) { applet_resource->GetController(HidController::NPad) .SetPermitVibrationSession(false); - LOG_INFO(Service_HID, "called"); + LOG_DEBUG(Service_HID, "called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -1554,11 +1554,11 @@ void Hid::IsVibrationDeviceMounted(Kernel::HLERequestContext& ctx) { const auto parameters{rp.PopRaw()}; - LOG_INFO(Service_HID, - "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", - parameters.vibration_device_handle.npad_type, - parameters.vibration_device_handle.npad_id, - parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); + LOG_DEBUG(Service_HID, + "called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}", + parameters.vibration_device_handle.npad_type, + parameters.vibration_device_handle.npad_id, + parameters.vibration_device_handle.device_index, parameters.applet_resource_user_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); diff --git a/src/input_common/drivers/sdl_driver.cpp b/src/input_common/drivers/sdl_driver.cpp index a5c63e74a..1a14ef10b 100755 --- a/src/input_common/drivers/sdl_driver.cpp +++ b/src/input_common/drivers/sdl_driver.cpp @@ -434,6 +434,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en using namespace std::chrono_literals; while (initialized) { SDL_PumpEvents(); + SendVibrations(); std::this_thread::sleep_for(1ms); } }); @@ -531,13 +532,31 @@ Common::Input::VibrationError SDLDriver::SetRumble( .type = Common::Input::VibrationAmplificationType::Exponential, }; - if (!joystick->RumblePlay(new_vibration)) { - return Common::Input::VibrationError::Unknown; + if (vibration.type == Common::Input::VibrationAmplificationType::Test) { + if (!joystick->RumblePlay(new_vibration)) { + return Common::Input::VibrationError::Unknown; + } + return Common::Input::VibrationError::None; } + vibration_queue.Push(VibrationRequest{ + .identifier = identifier, + .vibration = new_vibration, + }); + 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(request.identifier.port)); + joystick->RumblePlay(request.vibration); + } +} + Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis, float value) const { Common::ParamPackage params{}; diff --git a/src/input_common/drivers/sdl_driver.h b/src/input_common/drivers/sdl_driver.h index dcd0d1e64..c82632506 100755 --- a/src/input_common/drivers/sdl_driver.h +++ b/src/input_common/drivers/sdl_driver.h @@ -12,6 +12,7 @@ #include #include "common/common_types.h" +#include "common/threadsafe_queue.h" #include "input_common/input_engine.h" union SDL_Event; @@ -64,12 +65,20 @@ public: const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override; private: + struct VibrationRequest { + PadIdentifier identifier; + Common::Input::VibrationStatus vibration; + }; + void InitJoystick(int joystick_index); void CloseJoystick(SDL_Joystick* sdl_joystick); /// Needs to be called before SDL_QuitSubSystem. 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, float value = 0.1f) const; Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid, @@ -107,6 +116,9 @@ private: /// Returns true if the button is on the left joycon bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const; + /// Queue of vibration request to controllers + Common::SPSCQueue vibration_queue; + /// Map of GUID of a list of corresponding virtual Joysticks std::unordered_map>> joystick_map; std::mutex joystick_map_mutex; diff --git a/src/input_common/drivers/touch_screen.cpp b/src/input_common/drivers/touch_screen.cpp index 8acbe4584..1753e0893 100755 --- a/src/input_common/drivers/touch_screen.cpp +++ b/src/input_common/drivers/touch_screen.cpp @@ -14,38 +14,93 @@ constexpr PadIdentifier identifier = { TouchScreen::TouchScreen(std::string input_engine_) : InputEngine(std::move(input_engine_)) { PreSetController(identifier); + ReleaseAllTouch(); } -void TouchScreen::TouchMoved(float x, float y, std::size_t finger) { - if (finger >= 16) { +void TouchScreen::TouchMoved(float x, float y, std::size_t finger_id) { + const auto index = GetIndexFromFingerId(finger_id); + if (!index) { + // Touch doesn't exist handle it as a new one + TouchPressed(x, y, finger_id); return; } - TouchPressed(x, y, finger); + const auto i = index.value(); + fingers[i].is_active = true; + SetButton(identifier, static_cast(i), true); + SetAxis(identifier, static_cast(i * 2), x); + SetAxis(identifier, static_cast(i * 2 + 1), y); } -void TouchScreen::TouchPressed(float x, float y, std::size_t finger) { - if (finger >= 16) { +void TouchScreen::TouchPressed(float x, float y, std::size_t finger_id) { + if (GetIndexFromFingerId(finger_id)) { + // Touch already exist. Just update the data + TouchMoved(x, y, finger_id); return; } - SetButton(identifier, static_cast(finger), true); - SetAxis(identifier, static_cast(finger * 2), x); - SetAxis(identifier, static_cast(finger * 2 + 1), y); + const auto index = GetNextFreeIndex(); + if (!index) { + // 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) { - if (finger >= 16) { +void TouchScreen::TouchReleased(std::size_t finger_id) { + const auto index = GetIndexFromFingerId(finger_id); + if (!index) { return; } - SetButton(identifier, static_cast(finger), false); - SetAxis(identifier, static_cast(finger * 2), 0.0f); - SetAxis(identifier, static_cast(finger * 2 + 1), 0.0f); + const auto i = index.value(); + fingers[i].is_enabled = false; + SetButton(identifier, static_cast(i), false); + SetAxis(identifier, static_cast(i * 2), 0.0f); + SetAxis(identifier, static_cast(i * 2 + 1), 0.0f); +} + +std::optional 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 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() { - for (int index = 0; index < 16; ++index) { - SetButton(identifier, index, false); - SetAxis(identifier, index * 2, 0.0f); - SetAxis(identifier, index * 2 + 1, 0.0f); + for (const auto& finger : fingers) { + if (finger.is_enabled) { + TouchReleased(finger.finger_id); + } } } diff --git a/src/input_common/drivers/touch_screen.h b/src/input_common/drivers/touch_screen.h index 193478ead..f46036ffd 100755 --- a/src/input_common/drivers/touch_screen.h +++ b/src/input_common/drivers/touch_screen.h @@ -3,41 +3,65 @@ #pragma once +#include + #include "input_common/input_engine.h" namespace InputCommon { /** - * A button device factory representing a keyboard. It receives keyboard events and forward them - * to all button devices it created. + * A touch device factory representing a touch screen. It receives touch events and forward them + * to all touch devices it created. */ class TouchScreen final : public InputEngine { public: explicit TouchScreen(std::string input_engine_); /** - * Signals that mouse has moved. - * @param x the x-coordinate of the cursor - * @param y the y-coordinate of the cursor - * @param center_x the x-coordinate of the middle of the screen - * @param center_y the y-coordinate of the middle of the screen + * Signals that touch has moved and marks this touch point as active + * @param x new horizontal position + * @param y new vertical position + * @param finger_id of the touch point to be updated */ - 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 - * @param key_code the code of the key to press + * Signals and creates a new touch point with this finger id + * @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 - * @param key_code the code of the key to release + * Signals and resets the touch point related to the this finger id + * @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 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 GetIndexFromFingerId(std::size_t finger_id) const; + + std::optional GetNextFreeIndex() const; + + std::array fingers{}; }; } // namespace InputCommon diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 353594293..da88f02a8 100755 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -1777,7 +1777,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, } attachments.push_back(color_buffer->RenderTarget()); 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(); image_ranges[num_images] = MakeSubresourceRange(color_buffer); samples = color_buffer->Samples(); @@ -1787,7 +1787,7 @@ void Framebuffer::CreateFramebuffer(TextureCacheRuntime& runtime, if (depth_buffer) { attachments.push_back(depth_buffer->RenderTarget()); 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(); const VkImageSubresourceRange subresource_range = MakeSubresourceRange(depth_buffer); image_ranges[num_images] = subresource_range; diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 7b2ca8046..5b688576b 100755 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -683,6 +683,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR 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_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA; diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index a1b819ae0..8f0a6bbb8 100755 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -772,65 +772,25 @@ void GRenderWindow::wheelEvent(QWheelEvent* event) { void GRenderWindow::TouchBeginEvent(const QTouchEvent* event) { QList touch_points = event->touchPoints(); for (const auto& touch_point : touch_points) { - if (!TouchUpdate(touch_point)) { - TouchStart(touch_point); - } + 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, touch_point.id()); } } void GRenderWindow::TouchUpdateEvent(const QTouchEvent* event) { QList touch_points = event->touchPoints(); + input_subsystem->GetTouchScreen()->ClearActiveFlag(); for (const auto& touch_point : touch_points) { - if (!TouchUpdate(touch_point)) { - TouchStart(touch_point); - } - } - // 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); - } + 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, touch_point.id()); } + input_subsystem->GetTouchScreen()->ReleaseInactiveTouch(); } void GRenderWindow::TouchEndEvent() { - for (std::size_t id = 0; id < touch_ids.size(); ++id) { - 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(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& touch_points) const { - return std::any_of(touch_points.begin(), touch_points.end(), [id](const auto& point) { - return id == static_cast(point.id() + 1); - }); + input_subsystem->GetTouchScreen()->ReleaseAllTouch(); } bool GRenderWindow::event(QEvent* event) { diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 4b0ce0293..841816564 100755 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -217,10 +217,6 @@ private: void TouchUpdateEvent(const QTouchEvent* event); void TouchEndEvent(); - void TouchStart(const QTouchEvent::TouchPoint& touch_point); - bool TouchUpdate(const QTouchEvent::TouchPoint& touch_point); - bool TouchExist(std::size_t id, const QList& touch_points) const; - void OnMinimalClientAreaChangeRequest(std::pair minimal_size) override; bool InitializeOpenGL(); @@ -246,8 +242,6 @@ private: bool first_frame = false; InputCommon::TasInput::TasState last_tas_state; - std::array touch_ids{}; - Core::System& system; protected: diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp index ae2e62dc5..71c413e64 100755 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp @@ -93,7 +93,7 @@ void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) { } void EmuWindow_SDL2::OnFingerUp() { - input_subsystem->GetTouchScreen()->TouchReleased(0); + input_subsystem->GetTouchScreen()->ReleaseAllTouch(); } void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {