diff options
| -rw-r--r-- | src/common/hex_util.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/filesystem/fsp/fsp_srv.cpp | 9 | ||||
| -rw-r--r-- | src/hid_core/resource_manager.cpp | 88 | ||||
| -rw-r--r-- | src/hid_core/resource_manager.h | 9 | ||||
| -rw-r--r-- | src/hid_core/resources/digitizer/digitizer.cpp | 4 | ||||
| -rw-r--r-- | src/hid_core/resources/digitizer/digitizer.h | 3 | ||||
| -rw-r--r-- | src/hid_core/resources/npad/npad.cpp | 18 | ||||
| -rw-r--r-- | src/hid_core/resources/npad/npad.h | 1 | ||||
| -rw-r--r-- | src/hid_core/resources/unique_pad/unique_pad.cpp | 4 | ||||
| -rw-r--r-- | src/hid_core/resources/unique_pad/unique_pad.h | 3 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 7 | ||||
| -rw-r--r-- | src/yuzu/multiplayer/lobby.cpp | 13 | ||||
| -rw-r--r-- | src/yuzu/multiplayer/lobby_p.h | 25 | ||||
| -rw-r--r-- | src/yuzu/uisettings.h | 14 |
14 files changed, 129 insertions, 72 deletions
diff --git a/src/common/hex_util.h b/src/common/hex_util.h index a00904939..618f53152 100644 --- a/src/common/hex_util.h +++ b/src/common/hex_util.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <vector> | 10 | #include <vector> |
| 11 | #include <fmt/format.h> | 11 | #include <fmt/format.h> |
| 12 | #include "common/assert.h" | ||
| 12 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 13 | 14 | ||
| 14 | namespace Common { | 15 | namespace Common { |
| @@ -29,6 +30,8 @@ namespace Common { | |||
| 29 | 30 | ||
| 30 | template <std::size_t Size, bool le = false> | 31 | template <std::size_t Size, bool le = false> |
| 31 | [[nodiscard]] constexpr std::array<u8, Size> HexStringToArray(std::string_view str) { | 32 | [[nodiscard]] constexpr std::array<u8, Size> HexStringToArray(std::string_view str) { |
| 33 | ASSERT_MSG(Size * 2 <= str.size(), "Invalid string size"); | ||
| 34 | |||
| 32 | std::array<u8, Size> out{}; | 35 | std::array<u8, Size> out{}; |
| 33 | if constexpr (le) { | 36 | if constexpr (le) { |
| 34 | for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) { | 37 | for (std::size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) { |
diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp index 5fe534c73..63c2d3a58 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp | |||
| @@ -115,6 +115,11 @@ private: | |||
| 115 | if (type->GetName() == "save") { | 115 | if (type->GetName() == "save") { |
| 116 | for (const auto& save_id : type->GetSubdirectories()) { | 116 | for (const auto& save_id : type->GetSubdirectories()) { |
| 117 | for (const auto& user_id : save_id->GetSubdirectories()) { | 117 | for (const auto& user_id : save_id->GetSubdirectories()) { |
| 118 | // Skip non user id subdirectories | ||
| 119 | if (user_id->GetName().size() != 0x20) { | ||
| 120 | continue; | ||
| 121 | } | ||
| 122 | |||
| 118 | const auto save_id_numeric = stoull_be(save_id->GetName()); | 123 | const auto save_id_numeric = stoull_be(save_id->GetName()); |
| 119 | auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName()); | 124 | auto user_id_numeric = Common::HexStringToArray<0x10>(user_id->GetName()); |
| 120 | std::reverse(user_id_numeric.begin(), user_id_numeric.end()); | 125 | std::reverse(user_id_numeric.begin(), user_id_numeric.end()); |
| @@ -160,6 +165,10 @@ private: | |||
| 160 | } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) { | 165 | } else if (space == FileSys::SaveDataSpaceId::TemporaryStorage) { |
| 161 | // Temporary Storage | 166 | // Temporary Storage |
| 162 | for (const auto& user_id : type->GetSubdirectories()) { | 167 | for (const auto& user_id : type->GetSubdirectories()) { |
| 168 | // Skip non user id subdirectories | ||
| 169 | if (user_id->GetName().size() != 0x20) { | ||
| 170 | continue; | ||
| 171 | } | ||
| 163 | for (const auto& title_id : user_id->GetSubdirectories()) { | 172 | for (const auto& title_id : user_id->GetSubdirectories()) { |
| 164 | if (!title_id->GetFiles().empty() || | 173 | if (!title_id->GetFiles().empty() || |
| 165 | !title_id->GetSubdirectories().empty()) { | 174 | !title_id->GetSubdirectories().empty()) { |
diff --git a/src/hid_core/resource_manager.cpp b/src/hid_core/resource_manager.cpp index 68ce2c7ae..245da582e 100644 --- a/src/hid_core/resource_manager.cpp +++ b/src/hid_core/resource_manager.cpp | |||
| @@ -52,9 +52,42 @@ ResourceManager::ResourceManager(Core::System& system_, | |||
| 52 | std::shared_ptr<HidFirmwareSettings> settings) | 52 | std::shared_ptr<HidFirmwareSettings> settings) |
| 53 | : firmware_settings{settings}, system{system_}, service_context{system_, "hid"} { | 53 | : firmware_settings{settings}, system{system_}, service_context{system_, "hid"} { |
| 54 | applet_resource = std::make_shared<AppletResource>(system); | 54 | applet_resource = std::make_shared<AppletResource>(system); |
| 55 | |||
| 56 | // Register update callbacks | ||
| 57 | npad_update_event = Core::Timing::CreateEvent("HID::UpdatePadCallback", | ||
| 58 | [this](s64 time, std::chrono::nanoseconds ns_late) | ||
| 59 | -> std::optional<std::chrono::nanoseconds> { | ||
| 60 | UpdateNpad(ns_late); | ||
| 61 | return std::nullopt; | ||
| 62 | }); | ||
| 63 | default_update_event = Core::Timing::CreateEvent( | ||
| 64 | "HID::UpdateDefaultCallback", | ||
| 65 | [this](s64 time, | ||
| 66 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 67 | UpdateControllers(ns_late); | ||
| 68 | return std::nullopt; | ||
| 69 | }); | ||
| 70 | mouse_keyboard_update_event = Core::Timing::CreateEvent( | ||
| 71 | "HID::UpdateMouseKeyboardCallback", | ||
| 72 | [this](s64 time, | ||
| 73 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 74 | UpdateMouseKeyboard(ns_late); | ||
| 75 | return std::nullopt; | ||
| 76 | }); | ||
| 77 | motion_update_event = Core::Timing::CreateEvent( | ||
| 78 | "HID::UpdateMotionCallback", | ||
| 79 | [this](s64 time, | ||
| 80 | std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 81 | UpdateMotion(ns_late); | ||
| 82 | return std::nullopt; | ||
| 83 | }); | ||
| 55 | } | 84 | } |
| 56 | 85 | ||
| 57 | ResourceManager::~ResourceManager() { | 86 | ResourceManager::~ResourceManager() { |
| 87 | system.CoreTiming().UnscheduleEvent(npad_update_event); | ||
| 88 | system.CoreTiming().UnscheduleEvent(default_update_event); | ||
| 89 | system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event); | ||
| 90 | system.CoreTiming().UnscheduleEvent(motion_update_event); | ||
| 58 | system.CoreTiming().UnscheduleEvent(touch_update_event); | 91 | system.CoreTiming().UnscheduleEvent(touch_update_event); |
| 59 | input_event->Finalize(); | 92 | input_event->Finalize(); |
| 60 | }; | 93 | }; |
| @@ -201,6 +234,7 @@ void ResourceManager::InitializeHidCommonSampler() { | |||
| 201 | 234 | ||
| 202 | debug_pad->SetAppletResource(applet_resource, &shared_mutex); | 235 | debug_pad->SetAppletResource(applet_resource, &shared_mutex); |
| 203 | digitizer->SetAppletResource(applet_resource, &shared_mutex); | 236 | digitizer->SetAppletResource(applet_resource, &shared_mutex); |
| 237 | unique_pad->SetAppletResource(applet_resource, &shared_mutex); | ||
| 204 | keyboard->SetAppletResource(applet_resource, &shared_mutex); | 238 | keyboard->SetAppletResource(applet_resource, &shared_mutex); |
| 205 | 239 | ||
| 206 | const auto settings = | 240 | const auto settings = |
| @@ -214,6 +248,14 @@ void ResourceManager::InitializeHidCommonSampler() { | |||
| 214 | home_button->SetAppletResource(applet_resource, &shared_mutex); | 248 | home_button->SetAppletResource(applet_resource, &shared_mutex); |
| 215 | sleep_button->SetAppletResource(applet_resource, &shared_mutex); | 249 | sleep_button->SetAppletResource(applet_resource, &shared_mutex); |
| 216 | capture_button->SetAppletResource(applet_resource, &shared_mutex); | 250 | capture_button->SetAppletResource(applet_resource, &shared_mutex); |
| 251 | |||
| 252 | system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event); | ||
| 253 | system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns, | ||
| 254 | default_update_event); | ||
| 255 | system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, | ||
| 256 | mouse_keyboard_update_event); | ||
| 257 | system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, | ||
| 258 | motion_update_event); | ||
| 217 | } | 259 | } |
| 218 | 260 | ||
| 219 | void ResourceManager::InitializeTouchScreenSampler() { | 261 | void ResourceManager::InitializeTouchScreenSampler() { |
| @@ -465,55 +507,9 @@ IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<Resource | |||
| 465 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, | 507 | {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, |
| 466 | }; | 508 | }; |
| 467 | RegisterHandlers(functions); | 509 | RegisterHandlers(functions); |
| 468 | |||
| 469 | // Register update callbacks | ||
| 470 | npad_update_event = Core::Timing::CreateEvent( | ||
| 471 | "HID::UpdatePadCallback", | ||
| 472 | [this, resource]( | ||
| 473 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 474 | const auto guard = LockService(); | ||
| 475 | resource->UpdateNpad(ns_late); | ||
| 476 | return std::nullopt; | ||
| 477 | }); | ||
| 478 | default_update_event = Core::Timing::CreateEvent( | ||
| 479 | "HID::UpdateDefaultCallback", | ||
| 480 | [this, resource]( | ||
| 481 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 482 | const auto guard = LockService(); | ||
| 483 | resource->UpdateControllers(ns_late); | ||
| 484 | return std::nullopt; | ||
| 485 | }); | ||
| 486 | mouse_keyboard_update_event = Core::Timing::CreateEvent( | ||
| 487 | "HID::UpdateMouseKeyboardCallback", | ||
| 488 | [this, resource]( | ||
| 489 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 490 | const auto guard = LockService(); | ||
| 491 | resource->UpdateMouseKeyboard(ns_late); | ||
| 492 | return std::nullopt; | ||
| 493 | }); | ||
| 494 | motion_update_event = Core::Timing::CreateEvent( | ||
| 495 | "HID::UpdateMotionCallback", | ||
| 496 | [this, resource]( | ||
| 497 | s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> { | ||
| 498 | const auto guard = LockService(); | ||
| 499 | resource->UpdateMotion(ns_late); | ||
| 500 | return std::nullopt; | ||
| 501 | }); | ||
| 502 | |||
| 503 | system.CoreTiming().ScheduleLoopingEvent(npad_update_ns, npad_update_ns, npad_update_event); | ||
| 504 | system.CoreTiming().ScheduleLoopingEvent(default_update_ns, default_update_ns, | ||
| 505 | default_update_event); | ||
| 506 | system.CoreTiming().ScheduleLoopingEvent(mouse_keyboard_update_ns, mouse_keyboard_update_ns, | ||
| 507 | mouse_keyboard_update_event); | ||
| 508 | system.CoreTiming().ScheduleLoopingEvent(motion_update_ns, motion_update_ns, | ||
| 509 | motion_update_event); | ||
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | IAppletResource::~IAppletResource() { | 512 | IAppletResource::~IAppletResource() { |
| 513 | system.CoreTiming().UnscheduleEvent(npad_update_event); | ||
| 514 | system.CoreTiming().UnscheduleEvent(default_update_event); | ||
| 515 | system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event); | ||
| 516 | system.CoreTiming().UnscheduleEvent(motion_update_event); | ||
| 517 | resource_manager->FreeAppletResourceId(aruid); | 513 | resource_manager->FreeAppletResourceId(aruid); |
| 518 | } | 514 | } |
| 519 | 515 | ||
diff --git a/src/hid_core/resource_manager.h b/src/hid_core/resource_manager.h index 0bfe09511..dc3ff01f8 100644 --- a/src/hid_core/resource_manager.h +++ b/src/hid_core/resource_manager.h | |||
| @@ -147,6 +147,10 @@ private: | |||
| 147 | std::shared_ptr<SixAxis> six_axis{nullptr}; | 147 | std::shared_ptr<SixAxis> six_axis{nullptr}; |
| 148 | std::shared_ptr<SleepButton> sleep_button{nullptr}; | 148 | std::shared_ptr<SleepButton> sleep_button{nullptr}; |
| 149 | std::shared_ptr<UniquePad> unique_pad{nullptr}; | 149 | std::shared_ptr<UniquePad> unique_pad{nullptr}; |
| 150 | std::shared_ptr<Core::Timing::EventType> npad_update_event; | ||
| 151 | std::shared_ptr<Core::Timing::EventType> default_update_event; | ||
| 152 | std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; | ||
| 153 | std::shared_ptr<Core::Timing::EventType> motion_update_event; | ||
| 150 | 154 | ||
| 151 | // TODO: Create these resources | 155 | // TODO: Create these resources |
| 152 | // std::shared_ptr<AudioControl> audio_control{nullptr}; | 156 | // std::shared_ptr<AudioControl> audio_control{nullptr}; |
| @@ -179,11 +183,6 @@ public: | |||
| 179 | private: | 183 | private: |
| 180 | void GetSharedMemoryHandle(HLERequestContext& ctx); | 184 | void GetSharedMemoryHandle(HLERequestContext& ctx); |
| 181 | 185 | ||
| 182 | std::shared_ptr<Core::Timing::EventType> npad_update_event{nullptr}; | ||
| 183 | std::shared_ptr<Core::Timing::EventType> default_update_event{nullptr}; | ||
| 184 | std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event{nullptr}; | ||
| 185 | std::shared_ptr<Core::Timing::EventType> motion_update_event{nullptr}; | ||
| 186 | |||
| 187 | u64 aruid{}; | 186 | u64 aruid{}; |
| 188 | std::shared_ptr<ResourceManager> resource_manager; | 187 | std::shared_ptr<ResourceManager> resource_manager; |
| 189 | }; | 188 | }; |
diff --git a/src/hid_core/resources/digitizer/digitizer.cpp b/src/hid_core/resources/digitizer/digitizer.cpp index cd72fd6e5..5d7dcadfe 100644 --- a/src/hid_core/resources/digitizer/digitizer.cpp +++ b/src/hid_core/resources/digitizer/digitizer.cpp | |||
| @@ -17,10 +17,6 @@ void Digitizer::OnInit() {} | |||
| 17 | void Digitizer::OnRelease() {} | 17 | void Digitizer::OnRelease() {} |
| 18 | 18 | ||
| 19 | void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 19 | void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 20 | if (!smart_update) { | ||
| 21 | return; | ||
| 22 | } | ||
| 23 | |||
| 24 | std::scoped_lock shared_lock{*shared_mutex}; | 20 | std::scoped_lock shared_lock{*shared_mutex}; |
| 25 | const u64 aruid = applet_resource->GetActiveAruid(); | 21 | const u64 aruid = applet_resource->GetActiveAruid(); |
| 26 | auto* data = applet_resource->GetAruidData(aruid); | 22 | auto* data = applet_resource->GetAruidData(aruid); |
diff --git a/src/hid_core/resources/digitizer/digitizer.h b/src/hid_core/resources/digitizer/digitizer.h index e031a16b0..68b03111c 100644 --- a/src/hid_core/resources/digitizer/digitizer.h +++ b/src/hid_core/resources/digitizer/digitizer.h | |||
| @@ -20,8 +20,5 @@ public: | |||
| 20 | 20 | ||
| 21 | // When the controller is requesting an update for the shared memory | 21 | // When the controller is requesting an update for the shared memory |
| 22 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 22 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 23 | |||
| 24 | private: | ||
| 25 | bool smart_update{}; | ||
| 26 | }; | 23 | }; |
| 27 | } // namespace Service::HID | 24 | } // namespace Service::HID |
diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp index 1a58eff4a..fe3fdc5cd 100644 --- a/src/hid_core/resources/npad/npad.cpp +++ b/src/hid_core/resources/npad/npad.cpp | |||
| @@ -102,6 +102,8 @@ Result NPad::Activate(u64 aruid) { | |||
| 102 | for (std::size_t i = 0; i < 19; ++i) { | 102 | for (std::size_t i = 0; i < 19; ++i) { |
| 103 | WriteEmptyEntry(npad); | 103 | WriteEmptyEntry(npad); |
| 104 | } | 104 | } |
| 105 | |||
| 106 | controller.is_active = true; | ||
| 105 | } | 107 | } |
| 106 | 108 | ||
| 107 | return ResultSuccess; | 109 | return ResultSuccess; |
| @@ -467,6 +469,13 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 467 | continue; | 469 | continue; |
| 468 | } | 470 | } |
| 469 | 471 | ||
| 472 | bool is_set{}; | ||
| 473 | npad_resource.IsSupportedNpadStyleSet(is_set, aruid); | ||
| 474 | // Wait until style is defined | ||
| 475 | if (!is_set) { | ||
| 476 | continue; | ||
| 477 | } | ||
| 478 | |||
| 470 | for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { | 479 | for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { |
| 471 | auto& controller = controller_data[aruid_index][i]; | 480 | auto& controller = controller_data[aruid_index][i]; |
| 472 | controller.shared_memory = | 481 | controller.shared_memory = |
| @@ -484,6 +493,10 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 484 | continue; | 493 | continue; |
| 485 | } | 494 | } |
| 486 | 495 | ||
| 496 | if (!controller.is_active) { | ||
| 497 | continue; | ||
| 498 | } | ||
| 499 | |||
| 487 | RequestPadStateUpdate(aruid, controller.device->GetNpadIdType()); | 500 | RequestPadStateUpdate(aruid, controller.device->GetNpadIdType()); |
| 488 | auto& pad_state = controller.npad_pad_state; | 501 | auto& pad_state = controller.npad_pad_state; |
| 489 | auto& libnx_state = controller.npad_libnx_state; | 502 | auto& libnx_state = controller.npad_libnx_state; |
| @@ -592,7 +605,9 @@ void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | |||
| 592 | libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw; | 605 | libnx_state.npad_buttons.raw = pad_state.npad_buttons.raw; |
| 593 | libnx_state.l_stick = pad_state.l_stick; | 606 | libnx_state.l_stick = pad_state.l_stick; |
| 594 | libnx_state.r_stick = pad_state.r_stick; | 607 | libnx_state.r_stick = pad_state.r_stick; |
| 595 | npad->system_ext_lifo.WriteNextEntry(pad_state); | 608 | libnx_state.sampling_number = |
| 609 | npad->system_ext_lifo.ReadCurrentEntry().state.sampling_number + 1; | ||
| 610 | npad->system_ext_lifo.WriteNextEntry(libnx_state); | ||
| 596 | 611 | ||
| 597 | press_state |= static_cast<u64>(pad_state.npad_buttons.raw); | 612 | press_state |= static_cast<u64>(pad_state.npad_buttons.raw); |
| 598 | } | 613 | } |
| @@ -1060,6 +1075,7 @@ void NPad::UnregisterAppletResourceUserId(u64 aruid) { | |||
| 1060 | // TODO: Remove this once abstract pad is emulated properly | 1075 | // TODO: Remove this once abstract pad is emulated properly |
| 1061 | const auto aruid_index = npad_resource.GetIndexFromAruid(aruid); | 1076 | const auto aruid_index = npad_resource.GetIndexFromAruid(aruid); |
| 1062 | for (auto& controller : controller_data[aruid_index]) { | 1077 | for (auto& controller : controller_data[aruid_index]) { |
| 1078 | controller.is_active = false; | ||
| 1063 | controller.is_connected = false; | 1079 | controller.is_connected = false; |
| 1064 | controller.shared_memory = nullptr; | 1080 | controller.shared_memory = nullptr; |
| 1065 | } | 1081 | } |
diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h index 4e26ed2e8..c63488346 100644 --- a/src/hid_core/resources/npad/npad.h +++ b/src/hid_core/resources/npad/npad.h | |||
| @@ -164,6 +164,7 @@ private: | |||
| 164 | NpadInternalState* shared_memory = nullptr; | 164 | NpadInternalState* shared_memory = nullptr; |
| 165 | Core::HID::EmulatedController* device = nullptr; | 165 | Core::HID::EmulatedController* device = nullptr; |
| 166 | 166 | ||
| 167 | bool is_active{}; | ||
| 167 | bool is_connected{}; | 168 | bool is_connected{}; |
| 168 | 169 | ||
| 169 | // Dual joycons can have only one side connected | 170 | // Dual joycons can have only one side connected |
diff --git a/src/hid_core/resources/unique_pad/unique_pad.cpp b/src/hid_core/resources/unique_pad/unique_pad.cpp index 89fc57269..b2db55c5a 100644 --- a/src/hid_core/resources/unique_pad/unique_pad.cpp +++ b/src/hid_core/resources/unique_pad/unique_pad.cpp | |||
| @@ -17,10 +17,6 @@ void UniquePad::OnInit() {} | |||
| 17 | void UniquePad::OnRelease() {} | 17 | void UniquePad::OnRelease() {} |
| 18 | 18 | ||
| 19 | void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { | 19 | void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
| 20 | if (!smart_update) { | ||
| 21 | return; | ||
| 22 | } | ||
| 23 | |||
| 24 | const u64 aruid = applet_resource->GetActiveAruid(); | 20 | const u64 aruid = applet_resource->GetActiveAruid(); |
| 25 | auto* data = applet_resource->GetAruidData(aruid); | 21 | auto* data = applet_resource->GetAruidData(aruid); |
| 26 | 22 | ||
diff --git a/src/hid_core/resources/unique_pad/unique_pad.h b/src/hid_core/resources/unique_pad/unique_pad.h index 674ad1691..4873b7f7e 100644 --- a/src/hid_core/resources/unique_pad/unique_pad.h +++ b/src/hid_core/resources/unique_pad/unique_pad.h | |||
| @@ -20,8 +20,5 @@ public: | |||
| 20 | 20 | ||
| 21 | // When the controller is requesting an update for the shared memory | 21 | // When the controller is requesting an update for the shared memory |
| 22 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; | 22 | void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
| 23 | |||
| 24 | private: | ||
| 25 | bool smart_update{}; | ||
| 26 | }; | 23 | }; |
| 27 | } // namespace Service::HID | 24 | } // namespace Service::HID |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 303d84a1f..13381fea8 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1353,6 +1353,13 @@ void GMainWindow::InitializeHotkeys() { | |||
| 1353 | LinkActionShortcut(ui->action_TAS_Start, QStringLiteral("TAS Start/Stop"), true); | 1353 | LinkActionShortcut(ui->action_TAS_Start, QStringLiteral("TAS Start/Stop"), true); |
| 1354 | LinkActionShortcut(ui->action_TAS_Record, QStringLiteral("TAS Record"), true); | 1354 | LinkActionShortcut(ui->action_TAS_Record, QStringLiteral("TAS Record"), true); |
| 1355 | LinkActionShortcut(ui->action_TAS_Reset, QStringLiteral("TAS Reset"), true); | 1355 | LinkActionShortcut(ui->action_TAS_Reset, QStringLiteral("TAS Reset"), true); |
| 1356 | LinkActionShortcut(ui->action_View_Lobby, | ||
| 1357 | QStringLiteral("Multiplayer Browse Public Game Lobby")); | ||
| 1358 | LinkActionShortcut(ui->action_Start_Room, QStringLiteral("Multiplayer Create Room")); | ||
| 1359 | LinkActionShortcut(ui->action_Connect_To_Room, | ||
| 1360 | QStringLiteral("Multiplayer Direct Connect to Room")); | ||
| 1361 | LinkActionShortcut(ui->action_Show_Room, QStringLiteral("Multiplayer Show Current Room")); | ||
| 1362 | LinkActionShortcut(ui->action_Leave_Room, QStringLiteral("Multiplayer Leave Room")); | ||
| 1356 | 1363 | ||
| 1357 | static const QString main_window = QStringLiteral("Main Window"); | 1364 | static const QString main_window = QStringLiteral("Main Window"); |
| 1358 | const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) { | 1365 | const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) { |
diff --git a/src/yuzu/multiplayer/lobby.cpp b/src/yuzu/multiplayer/lobby.cpp index 41692c05b..77ac84295 100644 --- a/src/yuzu/multiplayer/lobby.cpp +++ b/src/yuzu/multiplayer/lobby.cpp | |||
| @@ -77,16 +77,23 @@ Lobby::Lobby(QWidget* parent, QStandardItemModel* list, | |||
| 77 | 77 | ||
| 78 | // UI Buttons | 78 | // UI Buttons |
| 79 | connect(ui->refresh_list, &QPushButton::clicked, this, &Lobby::RefreshLobby); | 79 | connect(ui->refresh_list, &QPushButton::clicked, this, &Lobby::RefreshLobby); |
| 80 | connect(ui->search, &QLineEdit::textChanged, proxy, &LobbyFilterProxyModel::SetFilterSearch); | ||
| 80 | connect(ui->games_owned, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterOwned); | 81 | connect(ui->games_owned, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterOwned); |
| 81 | connect(ui->hide_empty, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterEmpty); | 82 | connect(ui->hide_empty, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterEmpty); |
| 82 | connect(ui->hide_full, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterFull); | 83 | connect(ui->hide_full, &QCheckBox::toggled, proxy, &LobbyFilterProxyModel::SetFilterFull); |
| 83 | connect(ui->search, &QLineEdit::textChanged, proxy, &LobbyFilterProxyModel::SetFilterSearch); | ||
| 84 | connect(ui->room_list, &QTreeView::doubleClicked, this, &Lobby::OnJoinRoom); | 84 | connect(ui->room_list, &QTreeView::doubleClicked, this, &Lobby::OnJoinRoom); |
| 85 | connect(ui->room_list, &QTreeView::clicked, this, &Lobby::OnExpandRoom); | 85 | connect(ui->room_list, &QTreeView::clicked, this, &Lobby::OnExpandRoom); |
| 86 | 86 | ||
| 87 | // Actions | 87 | // Actions |
| 88 | connect(&room_list_watcher, &QFutureWatcher<AnnounceMultiplayerRoom::RoomList>::finished, this, | 88 | connect(&room_list_watcher, &QFutureWatcher<AnnounceMultiplayerRoom::RoomList>::finished, this, |
| 89 | &Lobby::OnRefreshLobby); | 89 | &Lobby::OnRefreshLobby); |
| 90 | |||
| 91 | // Load persistent filters after events are connected to make sure they apply | ||
| 92 | ui->search->setText( | ||
| 93 | QString::fromStdString(UISettings::values.multiplayer_filter_text.GetValue())); | ||
| 94 | ui->games_owned->setChecked(UISettings::values.multiplayer_filter_games_owned.GetValue()); | ||
| 95 | ui->hide_empty->setChecked(UISettings::values.multiplayer_filter_hide_empty.GetValue()); | ||
| 96 | ui->hide_full->setChecked(UISettings::values.multiplayer_filter_hide_full.GetValue()); | ||
| 90 | } | 97 | } |
| 91 | 98 | ||
| 92 | Lobby::~Lobby() = default; | 99 | Lobby::~Lobby() = default; |
| @@ -204,6 +211,10 @@ void Lobby::OnJoinRoom(const QModelIndex& source) { | |||
| 204 | 211 | ||
| 205 | // Save settings | 212 | // Save settings |
| 206 | UISettings::values.multiplayer_nickname = ui->nickname->text().toStdString(); | 213 | UISettings::values.multiplayer_nickname = ui->nickname->text().toStdString(); |
| 214 | UISettings::values.multiplayer_filter_text = ui->search->text().toStdString(); | ||
| 215 | UISettings::values.multiplayer_filter_games_owned = ui->games_owned->isChecked(); | ||
| 216 | UISettings::values.multiplayer_filter_hide_empty = ui->hide_empty->isChecked(); | ||
| 217 | UISettings::values.multiplayer_filter_hide_full = ui->hide_full->isChecked(); | ||
| 207 | UISettings::values.multiplayer_ip = | 218 | UISettings::values.multiplayer_ip = |
| 208 | proxy->data(connection_index, LobbyItemHost::HostIPRole).value<QString>().toStdString(); | 219 | proxy->data(connection_index, LobbyItemHost::HostIPRole).value<QString>().toStdString(); |
| 209 | UISettings::values.multiplayer_port = | 220 | UISettings::values.multiplayer_port = |
diff --git a/src/yuzu/multiplayer/lobby_p.h b/src/yuzu/multiplayer/lobby_p.h index 068c95aca..398833e7a 100644 --- a/src/yuzu/multiplayer/lobby_p.h +++ b/src/yuzu/multiplayer/lobby_p.h | |||
| @@ -193,12 +193,29 @@ public: | |||
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | QVariant data(int role) const override { | 195 | QVariant data(int role) const override { |
| 196 | if (role != Qt::DisplayRole) { | 196 | switch (role) { |
| 197 | case Qt::DisplayRole: { | ||
| 198 | auto members = data(MemberListRole).toList(); | ||
| 199 | return QStringLiteral("%1 / %2 ") | ||
| 200 | .arg(QString::number(members.size()), data(MaxPlayerRole).toString()); | ||
| 201 | } | ||
| 202 | case Qt::ForegroundRole: { | ||
| 203 | auto members = data(MemberListRole).toList(); | ||
| 204 | auto max_players = data(MaxPlayerRole).toInt(); | ||
| 205 | if (members.size() >= max_players) { | ||
| 206 | return QBrush(QColor(255, 48, 32)); | ||
| 207 | } else if (members.size() == (max_players - 1)) { | ||
| 208 | return QBrush(QColor(255, 140, 32)); | ||
| 209 | } else if (members.size() == 0) { | ||
| 210 | return QBrush(QColor(128, 128, 128)); | ||
| 211 | } | ||
| 212 | // FIXME: How to return a value that tells Qt not to modify the | ||
| 213 | // text color from the default (as if Qt::ForegroundRole wasn't overridden)? | ||
| 214 | return QBrush(nullptr); | ||
| 215 | } | ||
| 216 | default: | ||
| 197 | return LobbyItem::data(role); | 217 | return LobbyItem::data(role); |
| 198 | } | 218 | } |
| 199 | auto members = data(MemberListRole).toList(); | ||
| 200 | return QStringLiteral("%1 / %2 ") | ||
| 201 | .arg(QString::number(members.size()), data(MaxPlayerRole).toString()); | ||
| 202 | } | 219 | } |
| 203 | 220 | ||
| 204 | bool operator<(const QStandardItem& other) const override { | 221 | bool operator<(const QStandardItem& other) const override { |
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index f9906be33..03e42b930 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h | |||
| @@ -169,6 +169,13 @@ struct Values { | |||
| 169 | 169 | ||
| 170 | // multiplayer settings | 170 | // multiplayer settings |
| 171 | Setting<std::string> multiplayer_nickname{linkage, {}, "nickname", Category::Multiplayer}; | 171 | Setting<std::string> multiplayer_nickname{linkage, {}, "nickname", Category::Multiplayer}; |
| 172 | Setting<std::string> multiplayer_filter_text{linkage, {}, "filter_text", Category::Multiplayer}; | ||
| 173 | Setting<bool> multiplayer_filter_games_owned{linkage, false, "filter_games_owned", | ||
| 174 | Category::Multiplayer}; | ||
| 175 | Setting<bool> multiplayer_filter_hide_empty{linkage, false, "filter_games_hide_empty", | ||
| 176 | Category::Multiplayer}; | ||
| 177 | Setting<bool> multiplayer_filter_hide_full{linkage, false, "filter_games_hide_full", | ||
| 178 | Category::Multiplayer}; | ||
| 172 | Setting<std::string> multiplayer_ip{linkage, {}, "ip", Category::Multiplayer}; | 179 | Setting<std::string> multiplayer_ip{linkage, {}, "ip", Category::Multiplayer}; |
| 173 | Setting<u16, true> multiplayer_port{linkage, 24872, 0, | 180 | Setting<u16, true> multiplayer_port{linkage, 24872, 0, |
| 174 | UINT16_MAX, "port", Category::Multiplayer}; | 181 | UINT16_MAX, "port", Category::Multiplayer}; |
| @@ -222,7 +229,7 @@ void RestoreWindowState(std::unique_ptr<QtConfig>& qtConfig); | |||
| 222 | // This must be in alphabetical order according to action name as it must have the same order as | 229 | // This must be in alphabetical order according to action name as it must have the same order as |
| 223 | // UISetting::values.shortcuts, which is alphabetically ordered. | 230 | // UISetting::values.shortcuts, which is alphabetically ordered. |
| 224 | // clang-format off | 231 | // clang-format off |
| 225 | const std::array<Shortcut, 23> default_hotkeys{{ | 232 | const std::array<Shortcut, 28> default_hotkeys{{ |
| 226 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+M"), std::string("Home+Dpad_Right"), Qt::WindowShortcut, false}}, | 233 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+M"), std::string("Home+Dpad_Right"), Qt::WindowShortcut, false}}, |
| 227 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("-"), std::string("Home+Dpad_Down"), Qt::ApplicationShortcut, true}}, | 234 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("-"), std::string("Home+Dpad_Down"), Qt::ApplicationShortcut, true}}, |
| 228 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("="), std::string("Home+Dpad_Up"), Qt::ApplicationShortcut, true}}, | 235 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("="), std::string("Home+Dpad_Up"), Qt::ApplicationShortcut, true}}, |
| @@ -236,6 +243,11 @@ const std::array<Shortcut, 23> default_hotkeys{{ | |||
| 236 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F11"), std::string("Home+B"), Qt::WindowShortcut, false}}, | 243 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F11"), std::string("Home+B"), Qt::WindowShortcut, false}}, |
| 237 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+O"), std::string(""), Qt::WidgetWithChildrenShortcut, false}}, | 244 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+O"), std::string(""), Qt::WidgetWithChildrenShortcut, false}}, |
| 238 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F2"), std::string("Home+A"), Qt::WidgetWithChildrenShortcut, false}}, | 245 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F2"), std::string("Home+A"), Qt::WidgetWithChildrenShortcut, false}}, |
| 246 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Multiplayer Browse Public Game Lobby")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+B"), std::string(""), Qt::ApplicationShortcut, false}}, | ||
| 247 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Multiplayer Create Room")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+N"), std::string(""), Qt::ApplicationShortcut, false}}, | ||
| 248 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Multiplayer Direct Connect to Room")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+C"), std::string(""), Qt::ApplicationShortcut, false}}, | ||
| 249 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Multiplayer Leave Room")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+L"), std::string(""), Qt::ApplicationShortcut, false}}, | ||
| 250 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Multiplayer Show Current Room")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+R"), std::string(""), Qt::ApplicationShortcut, false}}, | ||
| 239 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F6"), std::string("R+Plus+Minus"), Qt::WindowShortcut, false}}, | 251 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F6"), std::string("R+Plus+Minus"), Qt::WindowShortcut, false}}, |
| 240 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F5"), std::string("L+Plus+Minus"), Qt::WindowShortcut, false}}, | 252 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F5"), std::string("L+Plus+Minus"), Qt::WindowShortcut, false}}, |
| 241 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F7"), std::string(""), Qt::ApplicationShortcut, false}}, | 253 | {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F7"), std::string(""), Qt::ApplicationShortcut, false}}, |