summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hid/emulated_controller.cpp34
-rw-r--r--src/core/hid/emulated_controller.h6
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp3
-rw-r--r--src/video_core/gpu.cpp19
-rw-r--r--src/video_core/gpu.h3
-rw-r--r--src/yuzu/applets/qt_controller.cpp68
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp53
-rw-r--r--src/yuzu/main.cpp4
8 files changed, 116 insertions, 74 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index 2d3fce276..71fc05807 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -879,10 +879,36 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles)
879 if (!is_connected) { 879 if (!is_connected) {
880 return; 880 return;
881 } 881 }
882 if (!IsControllerSupported()) { 882 if (IsControllerSupported()) {
883 LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller", 883 return;
884 npad_type); 884 }
885 Disconnect(); 885
886 Disconnect();
887
888 // Fallback fullkey controllers to Pro controllers
889 if (IsControllerFullkey() && supported_style_tag.fullkey) {
890 LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type);
891 SetNpadStyleIndex(NpadStyleIndex::ProController);
892 Connect();
893 return;
894 }
895
896 LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller",
897 npad_type);
898}
899
900bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const {
901 const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
902 switch (type) {
903 case NpadStyleIndex::ProController:
904 case NpadStyleIndex::GameCube:
905 case NpadStyleIndex::NES:
906 case NpadStyleIndex::SNES:
907 case NpadStyleIndex::N64:
908 case NpadStyleIndex::SegaGenesis:
909 return true;
910 default:
911 return false;
886 } 912 }
887} 913}
888 914
diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h
index d887eca87..c0994ab4d 100644
--- a/src/core/hid/emulated_controller.h
+++ b/src/core/hid/emulated_controller.h
@@ -321,6 +321,12 @@ private:
321 void LoadTASParams(); 321 void LoadTASParams();
322 322
323 /** 323 /**
324 * @param use_temporary_value If true tmp_npad_type will be used
325 * @return true if the controller style is fullkey
326 */
327 bool IsControllerFullkey(bool use_temporary_value = false) const;
328
329 /**
324 * Checks the current controller type against the supported_style_tag 330 * Checks the current controller type against the supported_style_tag
325 * @param use_temporary_value If true tmp_npad_type will be used 331 * @param use_temporary_value If true tmp_npad_type will be used
326 * @return true if the controller is supported 332 * @return true if the controller is supported
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index a22811ec1..396cc5afa 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -266,10 +266,11 @@ void NVFlinger::Compose() {
266 266
267 auto& gpu = system.GPU(); 267 auto& gpu = system.GPU();
268 const auto& multi_fence = buffer->get().multi_fence; 268 const auto& multi_fence = buffer->get().multi_fence;
269 const auto stop_token = vsync_thread.get_stop_token();
269 guard->unlock(); 270 guard->unlock();
270 for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { 271 for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) {
271 const auto& fence = multi_fence.fences[fence_id]; 272 const auto& fence = multi_fence.fences[fence_id];
272 gpu.WaitFence(fence.id, fence.value); 273 gpu.WaitFence(fence.id, fence.value, stop_token);
273 } 274 }
274 guard->lock(); 275 guard->lock();
275 276
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 8788f5148..d98874150 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -206,7 +206,7 @@ struct GPU::Impl {
206 } 206 }
207 207
208 /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. 208 /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame.
209 void WaitFence(u32 syncpoint_id, u32 value) { 209 void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {}) {
210 // Synced GPU, is always in sync 210 // Synced GPU, is always in sync
211 if (!is_async) { 211 if (!is_async) {
212 return; 212 return;
@@ -218,13 +218,8 @@ struct GPU::Impl {
218 } 218 }
219 MICROPROFILE_SCOPE(GPU_wait); 219 MICROPROFILE_SCOPE(GPU_wait);
220 std::unique_lock lock{sync_mutex}; 220 std::unique_lock lock{sync_mutex};
221 sync_cv.wait(lock, [=, this] { 221 sync_cv.wait(lock, stop_token,
222 if (shutting_down.load(std::memory_order_relaxed)) { 222 [=, this] { return syncpoints.at(syncpoint_id).load() >= value; });
223 // We're shutting down, ensure no threads continue to wait for the next syncpoint
224 return true;
225 }
226 return syncpoints.at(syncpoint_id).load() >= value;
227 });
228 } 223 }
229 224
230 void IncrementSyncPoint(u32 syncpoint_id) { 225 void IncrementSyncPoint(u32 syncpoint_id) {
@@ -670,8 +665,6 @@ struct GPU::Impl {
670 std::unique_ptr<Engines::KeplerMemory> kepler_memory; 665 std::unique_ptr<Engines::KeplerMemory> kepler_memory;
671 /// Shader build notifier 666 /// Shader build notifier
672 std::unique_ptr<VideoCore::ShaderNotify> shader_notify; 667 std::unique_ptr<VideoCore::ShaderNotify> shader_notify;
673 /// When true, we are about to shut down emulation session, so terminate outstanding tasks
674 std::atomic_bool shutting_down{};
675 668
676 std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; 669 std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{};
677 670
@@ -680,7 +673,7 @@ struct GPU::Impl {
680 std::mutex sync_mutex; 673 std::mutex sync_mutex;
681 std::mutex device_mutex; 674 std::mutex device_mutex;
682 675
683 std::condition_variable sync_cv; 676 std::condition_variable_any sync_cv;
684 677
685 struct FlushRequest { 678 struct FlushRequest {
686 explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) 679 explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_)
@@ -819,8 +812,8 @@ const VideoCore::ShaderNotify& GPU::ShaderNotify() const {
819 return impl->ShaderNotify(); 812 return impl->ShaderNotify();
820} 813}
821 814
822void GPU::WaitFence(u32 syncpoint_id, u32 value) { 815void GPU::WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token) {
823 impl->WaitFence(syncpoint_id, value); 816 impl->WaitFence(syncpoint_id, value, stop_token);
824} 817}
825 818
826void GPU::IncrementSyncPoint(u32 syncpoint_id) { 819void GPU::IncrementSyncPoint(u32 syncpoint_id) {
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index 500411176..cc65a7870 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include <memory> 7#include <memory>
8#include <stop_token>
8 9
9#include "common/bit_field.h" 10#include "common/bit_field.h"
10#include "common/common_types.h" 11#include "common/common_types.h"
@@ -209,7 +210,7 @@ public:
209 [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const; 210 [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const;
210 211
211 /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. 212 /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame.
212 void WaitFence(u32 syncpoint_id, u32 value); 213 void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {});
213 214
214 void IncrementSyncPoint(u32 syncpoint_id); 215 void IncrementSyncPoint(u32 syncpoint_id);
215 216
diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp
index d63193131..4239c17f5 100644
--- a/src/yuzu/applets/qt_controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -400,36 +400,66 @@ void QtControllerSelectorDialog::SetSupportedControllers() {
400} 400}
401 401
402void QtControllerSelectorDialog::SetEmulatedControllers(std::size_t player_index) { 402void QtControllerSelectorDialog::SetEmulatedControllers(std::size_t player_index) {
403 const auto npad_style_set = system.HIDCore().GetSupportedStyleTag();
403 auto& pairs = index_controller_type_pairs[player_index]; 404 auto& pairs = index_controller_type_pairs[player_index];
404 405
405 pairs.clear(); 406 pairs.clear();
406 emulated_controllers[player_index]->clear(); 407 emulated_controllers[player_index]->clear();
407 408
408 pairs.emplace_back(emulated_controllers[player_index]->count(), 409 const auto add_item = [&](Core::HID::NpadStyleIndex controller_type,
409 Core::HID::NpadStyleIndex::ProController); 410 const QString& controller_name) {
410 emulated_controllers[player_index]->addItem(tr("Pro Controller")); 411 pairs.emplace_back(emulated_controllers[player_index]->count(), controller_type);
412 emulated_controllers[player_index]->addItem(controller_name);
413 };
411 414
412 pairs.emplace_back(emulated_controllers[player_index]->count(), 415 if (npad_style_set.fullkey == 1) {
413 Core::HID::NpadStyleIndex::JoyconDual); 416 add_item(Core::HID::NpadStyleIndex::ProController, tr("Pro Controller"));
414 emulated_controllers[player_index]->addItem(tr("Dual Joycons")); 417 }
415 418
416 pairs.emplace_back(emulated_controllers[player_index]->count(), 419 if (npad_style_set.joycon_dual == 1) {
417 Core::HID::NpadStyleIndex::JoyconLeft); 420 add_item(Core::HID::NpadStyleIndex::JoyconDual, tr("Dual Joycons"));
418 emulated_controllers[player_index]->addItem(tr("Left Joycon")); 421 }
419 422
420 pairs.emplace_back(emulated_controllers[player_index]->count(), 423 if (npad_style_set.joycon_left == 1) {
421 Core::HID::NpadStyleIndex::JoyconRight); 424 add_item(Core::HID::NpadStyleIndex::JoyconLeft, tr("Left Joycon"));
422 emulated_controllers[player_index]->addItem(tr("Right Joycon")); 425 }
423 426
424 if (player_index == 0) { 427 if (npad_style_set.joycon_right == 1) {
425 pairs.emplace_back(emulated_controllers[player_index]->count(), 428 add_item(Core::HID::NpadStyleIndex::JoyconRight, tr("Right Joycon"));
426 Core::HID::NpadStyleIndex::Handheld);
427 emulated_controllers[player_index]->addItem(tr("Handheld"));
428 } 429 }
429 430
430 pairs.emplace_back(emulated_controllers[player_index]->count(), 431 if (player_index == 0 && npad_style_set.handheld == 1) {
431 Core::HID::NpadStyleIndex::GameCube); 432 add_item(Core::HID::NpadStyleIndex::Handheld, tr("Handheld"));
432 emulated_controllers[player_index]->addItem(tr("GameCube Controller")); 433 }
434
435 if (npad_style_set.gamecube == 1) {
436 add_item(Core::HID::NpadStyleIndex::GameCube, tr("GameCube Controller"));
437 }
438
439 // Disable all unsupported controllers
440 if (!Settings::values.enable_all_controllers) {
441 return;
442 }
443
444 if (npad_style_set.palma == 1) {
445 add_item(Core::HID::NpadStyleIndex::Pokeball, tr("Poke Ball Plus"));
446 }
447
448 if (npad_style_set.lark == 1) {
449 add_item(Core::HID::NpadStyleIndex::NES, tr("NES Controller"));
450 }
451
452 if (npad_style_set.lucia == 1) {
453 add_item(Core::HID::NpadStyleIndex::SNES, tr("SNES Controller"));
454 }
455
456 if (npad_style_set.lagoon == 1) {
457 add_item(Core::HID::NpadStyleIndex::N64, tr("N64 Controller"));
458 }
459
460 if (npad_style_set.lager == 1) {
461 add_item(Core::HID::NpadStyleIndex::SegaGenesis, tr("Sega Genesis"));
462 }
433} 463}
434 464
435Core::HID::NpadStyleIndex QtControllerSelectorDialog::GetControllerTypeFromIndex( 465Core::HID::NpadStyleIndex QtControllerSelectorDialog::GetControllerTypeFromIndex(
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index cb6163702..8c6249fc2 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -907,78 +907,63 @@ void ConfigureInputPlayer::UpdateUI() {
907} 907}
908 908
909void ConfigureInputPlayer::SetConnectableControllers() { 909void ConfigureInputPlayer::SetConnectableControllers() {
910 Core::HID::NpadStyleTag npad_style_set = hid_core.GetSupportedStyleTag(); 910 const auto npad_style_set = hid_core.GetSupportedStyleTag();
911 index_controller_type_pairs.clear(); 911 index_controller_type_pairs.clear();
912 ui->comboControllerType->clear(); 912 ui->comboControllerType->clear();
913 913
914 const auto add_item = [&](Core::HID::NpadStyleIndex controller_type,
915 const QString& controller_name) {
916 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), controller_type);
917 ui->comboControllerType->addItem(controller_name);
918 };
919
914 if (npad_style_set.fullkey == 1) { 920 if (npad_style_set.fullkey == 1) {
915 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 921 add_item(Core::HID::NpadStyleIndex::ProController, tr("Pro Controller"));
916 Core::HID::NpadStyleIndex::ProController);
917 ui->comboControllerType->addItem(tr("Pro Controller"));
918 } 922 }
919 923
920 if (npad_style_set.joycon_dual == 1) { 924 if (npad_style_set.joycon_dual == 1) {
921 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 925 add_item(Core::HID::NpadStyleIndex::JoyconDual, tr("Dual Joycons"));
922 Core::HID::NpadStyleIndex::JoyconDual);
923 ui->comboControllerType->addItem(tr("Dual Joycons"));
924 } 926 }
925 927
926 if (npad_style_set.joycon_left == 1) { 928 if (npad_style_set.joycon_left == 1) {
927 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 929 add_item(Core::HID::NpadStyleIndex::JoyconLeft, tr("Left Joycon"));
928 Core::HID::NpadStyleIndex::JoyconLeft);
929 ui->comboControllerType->addItem(tr("Left Joycon"));
930 } 930 }
931 931
932 if (npad_style_set.joycon_right == 1) { 932 if (npad_style_set.joycon_right == 1) {
933 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 933 add_item(Core::HID::NpadStyleIndex::JoyconRight, tr("Right Joycon"));
934 Core::HID::NpadStyleIndex::JoyconRight);
935 ui->comboControllerType->addItem(tr("Right Joycon"));
936 } 934 }
937 935
938 if (player_index == 0 && npad_style_set.handheld == 1) { 936 if (player_index == 0 && npad_style_set.handheld == 1) {
939 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 937 add_item(Core::HID::NpadStyleIndex::Handheld, tr("Handheld"));
940 Core::HID::NpadStyleIndex::Handheld);
941 ui->comboControllerType->addItem(tr("Handheld"));
942 } 938 }
943 939
944 if (npad_style_set.gamecube == 1) { 940 if (npad_style_set.gamecube == 1) {
945 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 941 add_item(Core::HID::NpadStyleIndex::GameCube, tr("GameCube Controller"));
946 Core::HID::NpadStyleIndex::GameCube);
947 ui->comboControllerType->addItem(tr("GameCube Controller"));
948 } 942 }
949 943
950 // Disable all unsupported controllers 944 // Disable all unsupported controllers
951 if (!Settings::values.enable_all_controllers) { 945 if (!Settings::values.enable_all_controllers) {
952 return; 946 return;
953 } 947 }
948
954 if (npad_style_set.palma == 1) { 949 if (npad_style_set.palma == 1) {
955 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 950 add_item(Core::HID::NpadStyleIndex::Pokeball, tr("Poke Ball Plus"));
956 Core::HID::NpadStyleIndex::Pokeball);
957 ui->comboControllerType->addItem(tr("Poke Ball Plus"));
958 } 951 }
959 952
960 if (npad_style_set.lark == 1) { 953 if (npad_style_set.lark == 1) {
961 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 954 add_item(Core::HID::NpadStyleIndex::NES, tr("NES Controller"));
962 Core::HID::NpadStyleIndex::NES);
963 ui->comboControllerType->addItem(tr("NES Controller"));
964 } 955 }
965 956
966 if (npad_style_set.lucia == 1) { 957 if (npad_style_set.lucia == 1) {
967 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 958 add_item(Core::HID::NpadStyleIndex::SNES, tr("SNES Controller"));
968 Core::HID::NpadStyleIndex::SNES);
969 ui->comboControllerType->addItem(tr("SNES Controller"));
970 } 959 }
971 960
972 if (npad_style_set.lagoon == 1) { 961 if (npad_style_set.lagoon == 1) {
973 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 962 add_item(Core::HID::NpadStyleIndex::N64, tr("N64 Controller"));
974 Core::HID::NpadStyleIndex::N64);
975 ui->comboControllerType->addItem(tr("N64 Controller"));
976 } 963 }
977 964
978 if (npad_style_set.lager == 1) { 965 if (npad_style_set.lager == 1) {
979 index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), 966 add_item(Core::HID::NpadStyleIndex::SegaGenesis, tr("Sega Genesis"));
980 Core::HID::NpadStyleIndex::SegaGenesis);
981 ui->comboControllerType->addItem(tr("Sega Genesis"));
982 } 967 }
983} 968}
984 969
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 1e02d715b..53f11a9ac 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1547,6 +1547,8 @@ void GMainWindow::ShutdownGame() {
1547 emu_thread->wait(); 1547 emu_thread->wait();
1548 emu_thread = nullptr; 1548 emu_thread = nullptr;
1549 1549
1550 emulation_running = false;
1551
1550 discord_rpc->Update(); 1552 discord_rpc->Update();
1551 1553
1552 // The emulation is stopped, so closing the window or not does not matter anymore 1554 // The emulation is stopped, so closing the window or not does not matter anymore
@@ -1585,8 +1587,6 @@ void GMainWindow::ShutdownGame() {
1585 emu_frametime_label->setVisible(false); 1587 emu_frametime_label->setVisible(false);
1586 renderer_status_button->setEnabled(true); 1588 renderer_status_button->setEnabled(true);
1587 1589
1588 emulation_running = false;
1589
1590 game_path.clear(); 1590 game_path.clear();
1591 1591
1592 // When closing the game, destroy the GLWindow to clear the context after the game is closed 1592 // When closing the game, destroy the GLWindow to clear the context after the game is closed