diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/hid/emulated_controller.cpp | 34 | ||||
-rw-r--r-- | src/core/hid/emulated_controller.h | 6 | ||||
-rw-r--r-- | src/core/hle/service/nvflinger/nvflinger.cpp | 3 | ||||
-rw-r--r-- | src/video_core/gpu.cpp | 19 | ||||
-rw-r--r-- | src/video_core/gpu.h | 3 | ||||
-rw-r--r-- | src/yuzu/applets/qt_controller.cpp | 68 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 53 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 4 |
8 files changed, 116 insertions, 74 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index 2d3fce2761..71fc058074 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) if (!is_connected) { return; } - if (!IsControllerSupported()) { - LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller", - npad_type); - Disconnect(); + if (IsControllerSupported()) { + return; + } + + Disconnect(); + + // Fallback fullkey controllers to Pro controllers + if (IsControllerFullkey() && supported_style_tag.fullkey) { + LOG_WARNING(Service_HID, "Reconnecting controller type {} as Pro controller", npad_type); + SetNpadStyleIndex(NpadStyleIndex::ProController); + Connect(); + return; + } + + LOG_ERROR(Service_HID, "Controller type {} is not supported. Disconnecting controller", + npad_type); +} + +bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const { + const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type; + switch (type) { + case NpadStyleIndex::ProController: + case NpadStyleIndex::GameCube: + case NpadStyleIndex::NES: + case NpadStyleIndex::SNES: + case NpadStyleIndex::N64: + case NpadStyleIndex::SegaGenesis: + return true; + default: + return false; } } diff --git a/src/core/hid/emulated_controller.h b/src/core/hid/emulated_controller.h index d887eca870..c0994ab4d0 100644 --- a/src/core/hid/emulated_controller.h +++ b/src/core/hid/emulated_controller.h @@ -321,6 +321,12 @@ private: void LoadTASParams(); /** + * @param use_temporary_value If true tmp_npad_type will be used + * @return true if the controller style is fullkey + */ + bool IsControllerFullkey(bool use_temporary_value = false) const; + + /** * Checks the current controller type against the supported_style_tag * @param use_temporary_value If true tmp_npad_type will be used * @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 a22811ec12..396cc5afa4 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -266,10 +266,11 @@ void NVFlinger::Compose() { auto& gpu = system.GPU(); const auto& multi_fence = buffer->get().multi_fence; + const auto stop_token = vsync_thread.get_stop_token(); guard->unlock(); for (u32 fence_id = 0; fence_id < multi_fence.num_fences; fence_id++) { const auto& fence = multi_fence.fences[fence_id]; - gpu.WaitFence(fence.id, fence.value); + gpu.WaitFence(fence.id, fence.value, stop_token); } guard->lock(); diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 8788f5148f..d988741503 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -206,7 +206,7 @@ struct GPU::Impl { } /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. - void WaitFence(u32 syncpoint_id, u32 value) { + void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {}) { // Synced GPU, is always in sync if (!is_async) { return; @@ -218,13 +218,8 @@ struct GPU::Impl { } MICROPROFILE_SCOPE(GPU_wait); std::unique_lock lock{sync_mutex}; - sync_cv.wait(lock, [=, this] { - if (shutting_down.load(std::memory_order_relaxed)) { - // We're shutting down, ensure no threads continue to wait for the next syncpoint - return true; - } - return syncpoints.at(syncpoint_id).load() >= value; - }); + sync_cv.wait(lock, stop_token, + [=, this] { return syncpoints.at(syncpoint_id).load() >= value; }); } void IncrementSyncPoint(u32 syncpoint_id) { @@ -670,8 +665,6 @@ struct GPU::Impl { std::unique_ptr<Engines::KeplerMemory> kepler_memory; /// Shader build notifier std::unique_ptr<VideoCore::ShaderNotify> shader_notify; - /// When true, we are about to shut down emulation session, so terminate outstanding tasks - std::atomic_bool shutting_down{}; std::array<std::atomic<u32>, Service::Nvidia::MaxSyncPoints> syncpoints{}; @@ -680,7 +673,7 @@ struct GPU::Impl { std::mutex sync_mutex; std::mutex device_mutex; - std::condition_variable sync_cv; + std::condition_variable_any sync_cv; struct FlushRequest { explicit FlushRequest(u64 fence_, VAddr addr_, std::size_t size_) @@ -819,8 +812,8 @@ const VideoCore::ShaderNotify& GPU::ShaderNotify() const { return impl->ShaderNotify(); } -void GPU::WaitFence(u32 syncpoint_id, u32 value) { - impl->WaitFence(syncpoint_id, value); +void GPU::WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token) { + impl->WaitFence(syncpoint_id, value, stop_token); } void GPU::IncrementSyncPoint(u32 syncpoint_id) { diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 500411176f..cc65a78704 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -5,6 +5,7 @@ #pragma once #include <memory> +#include <stop_token> #include "common/bit_field.h" #include "common/common_types.h" @@ -209,7 +210,7 @@ public: [[nodiscard]] const VideoCore::ShaderNotify& ShaderNotify() const; /// Allows the CPU/NvFlinger to wait on the GPU before presenting a frame. - void WaitFence(u32 syncpoint_id, u32 value); + void WaitFence(u32 syncpoint_id, u32 value, std::stop_token stop_token = {}); void IncrementSyncPoint(u32 syncpoint_id); diff --git a/src/yuzu/applets/qt_controller.cpp b/src/yuzu/applets/qt_controller.cpp index d63193131d..4239c17f57 100644 --- a/src/yuzu/applets/qt_controller.cpp +++ b/src/yuzu/applets/qt_controller.cpp @@ -400,36 +400,66 @@ void QtControllerSelectorDialog::SetSupportedControllers() { } void QtControllerSelectorDialog::SetEmulatedControllers(std::size_t player_index) { + const auto npad_style_set = system.HIDCore().GetSupportedStyleTag(); auto& pairs = index_controller_type_pairs[player_index]; pairs.clear(); emulated_controllers[player_index]->clear(); - pairs.emplace_back(emulated_controllers[player_index]->count(), - Core::HID::NpadStyleIndex::ProController); - emulated_controllers[player_index]->addItem(tr("Pro Controller")); + const auto add_item = [&](Core::HID::NpadStyleIndex controller_type, + const QString& controller_name) { + pairs.emplace_back(emulated_controllers[player_index]->count(), controller_type); + emulated_controllers[player_index]->addItem(controller_name); + }; - pairs.emplace_back(emulated_controllers[player_index]->count(), - Core::HID::NpadStyleIndex::JoyconDual); - emulated_controllers[player_index]->addItem(tr("Dual Joycons")); + if (npad_style_set.fullkey == 1) { + add_item(Core::HID::NpadStyleIndex::ProController, tr("Pro Controller")); + } - pairs.emplace_back(emulated_controllers[player_index]->count(), - Core::HID::NpadStyleIndex::JoyconLeft); - emulated_controllers[player_index]->addItem(tr("Left Joycon")); + if (npad_style_set.joycon_dual == 1) { + add_item(Core::HID::NpadStyleIndex::JoyconDual, tr("Dual Joycons")); + } - pairs.emplace_back(emulated_controllers[player_index]->count(), - Core::HID::NpadStyleIndex::JoyconRight); - emulated_controllers[player_index]->addItem(tr("Right Joycon")); + if (npad_style_set.joycon_left == 1) { + add_item(Core::HID::NpadStyleIndex::JoyconLeft, tr("Left Joycon")); + } - if (player_index == 0) { - pairs.emplace_back(emulated_controllers[player_index]->count(), - Core::HID::NpadStyleIndex::Handheld); - emulated_controllers[player_index]->addItem(tr("Handheld")); + if (npad_style_set.joycon_right == 1) { + add_item(Core::HID::NpadStyleIndex::JoyconRight, tr("Right Joycon")); } - pairs.emplace_back(emulated_controllers[player_index]->count(), - Core::HID::NpadStyleIndex::GameCube); - emulated_controllers[player_index]->addItem(tr("GameCube Controller")); + if (player_index == 0 && npad_style_set.handheld == 1) { + add_item(Core::HID::NpadStyleIndex::Handheld, tr("Handheld")); + } + + if (npad_style_set.gamecube == 1) { + add_item(Core::HID::NpadStyleIndex::GameCube, tr("GameCube Controller")); + } + + // Disable all unsupported controllers + if (!Settings::values.enable_all_controllers) { + return; + } + + if (npad_style_set.palma == 1) { + add_item(Core::HID::NpadStyleIndex::Pokeball, tr("Poke Ball Plus")); + } + + if (npad_style_set.lark == 1) { + add_item(Core::HID::NpadStyleIndex::NES, tr("NES Controller")); + } + + if (npad_style_set.lucia == 1) { + add_item(Core::HID::NpadStyleIndex::SNES, tr("SNES Controller")); + } + + if (npad_style_set.lagoon == 1) { + add_item(Core::HID::NpadStyleIndex::N64, tr("N64 Controller")); + } + + if (npad_style_set.lager == 1) { + add_item(Core::HID::NpadStyleIndex::SegaGenesis, tr("Sega Genesis")); + } } Core::HID::NpadStyleIndex QtControllerSelectorDialog::GetControllerTypeFromIndex( diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index cb61637020..8c6249fc21 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -907,78 +907,63 @@ void ConfigureInputPlayer::UpdateUI() { } void ConfigureInputPlayer::SetConnectableControllers() { - Core::HID::NpadStyleTag npad_style_set = hid_core.GetSupportedStyleTag(); + const auto npad_style_set = hid_core.GetSupportedStyleTag(); index_controller_type_pairs.clear(); ui->comboControllerType->clear(); + const auto add_item = [&](Core::HID::NpadStyleIndex controller_type, + const QString& controller_name) { + index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), controller_type); + ui->comboControllerType->addItem(controller_name); + }; + if (npad_style_set.fullkey == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::ProController); - ui->comboControllerType->addItem(tr("Pro Controller")); + add_item(Core::HID::NpadStyleIndex::ProController, tr("Pro Controller")); } if (npad_style_set.joycon_dual == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::JoyconDual); - ui->comboControllerType->addItem(tr("Dual Joycons")); + add_item(Core::HID::NpadStyleIndex::JoyconDual, tr("Dual Joycons")); } if (npad_style_set.joycon_left == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::JoyconLeft); - ui->comboControllerType->addItem(tr("Left Joycon")); + add_item(Core::HID::NpadStyleIndex::JoyconLeft, tr("Left Joycon")); } if (npad_style_set.joycon_right == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::JoyconRight); - ui->comboControllerType->addItem(tr("Right Joycon")); + add_item(Core::HID::NpadStyleIndex::JoyconRight, tr("Right Joycon")); } if (player_index == 0 && npad_style_set.handheld == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::Handheld); - ui->comboControllerType->addItem(tr("Handheld")); + add_item(Core::HID::NpadStyleIndex::Handheld, tr("Handheld")); } if (npad_style_set.gamecube == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::GameCube); - ui->comboControllerType->addItem(tr("GameCube Controller")); + add_item(Core::HID::NpadStyleIndex::GameCube, tr("GameCube Controller")); } // Disable all unsupported controllers if (!Settings::values.enable_all_controllers) { return; } + if (npad_style_set.palma == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::Pokeball); - ui->comboControllerType->addItem(tr("Poke Ball Plus")); + add_item(Core::HID::NpadStyleIndex::Pokeball, tr("Poke Ball Plus")); } if (npad_style_set.lark == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::NES); - ui->comboControllerType->addItem(tr("NES Controller")); + add_item(Core::HID::NpadStyleIndex::NES, tr("NES Controller")); } if (npad_style_set.lucia == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::SNES); - ui->comboControllerType->addItem(tr("SNES Controller")); + add_item(Core::HID::NpadStyleIndex::SNES, tr("SNES Controller")); } if (npad_style_set.lagoon == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::N64); - ui->comboControllerType->addItem(tr("N64 Controller")); + add_item(Core::HID::NpadStyleIndex::N64, tr("N64 Controller")); } if (npad_style_set.lager == 1) { - index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), - Core::HID::NpadStyleIndex::SegaGenesis); - ui->comboControllerType->addItem(tr("Sega Genesis")); + add_item(Core::HID::NpadStyleIndex::SegaGenesis, tr("Sega Genesis")); } } diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 1e02d715b9..53f11a9ac6 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1547,6 +1547,8 @@ void GMainWindow::ShutdownGame() { emu_thread->wait(); emu_thread = nullptr; + emulation_running = false; + discord_rpc->Update(); // The emulation is stopped, so closing the window or not does not matter anymore @@ -1585,8 +1587,6 @@ void GMainWindow::ShutdownGame() { emu_frametime_label->setVisible(false); renderer_status_button->setEnabled(true); - emulation_running = false; - game_path.clear(); // When closing the game, destroy the GLWindow to clear the context after the game is closed |