From ef89e4e70c256989ede03d33145ee05be141dc06 Mon Sep 17 00:00:00 2001 From: Techjar Date: Sat, 10 Nov 2018 22:37:49 -0500 Subject: [PATCH] NetPlay: Sync power button event This fixes the deadlock on shutdown when Wii Remotes are in use. --- Source/Core/Core/NetPlayClient.cpp | 19 +++++++++++++++++++ Source/Core/Core/NetPlayClient.h | 2 ++ Source/Core/Core/NetPlayProto.h | 2 ++ Source/Core/Core/NetPlayServer.cpp | 8 ++++++++ Source/Core/DolphinQt/MainWindow.cpp | 4 ++++ .../Core/DolphinQt/NetPlay/NetPlayDialog.cpp | 8 ++++++++ Source/Core/DolphinQt/NetPlay/NetPlayDialog.h | 1 + 7 files changed, 44 insertions(+) diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index 8762623414..2019848988 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -568,6 +568,12 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) } break; + case NP_MSG_POWER_BUTTON: + { + m_dialog->OnMsgPowerButton(); + } + break; + case NP_MSG_PING: { u32 ping_key = 0; @@ -1701,6 +1707,13 @@ void NetPlayClient::RequestStopGame() SendStopGamePacket(); } +void NetPlayClient::SendPowerButtonEvent() +{ + sf::Packet packet; + packet << static_cast(NP_MSG_POWER_BUTTON); + SendAsync(std::move(packet)); +} + // called from ---GUI--- thread bool NetPlayClient::LocalPlayerHasControllerMapped() const { @@ -1883,6 +1896,12 @@ void SetSIPollBatching(bool state) s_si_poll_batching = state; } +void SendPowerButtonEvent() +{ + ASSERT(IsNetPlayRunning()); + netplay_client->SendPowerButtonEvent(); +} + void NetPlay_Enable(NetPlayClient* const np) { std::lock_guard lk(crit_netplay_client); diff --git a/Source/Core/Core/NetPlayClient.h b/Source/Core/Core/NetPlayClient.h index 5287d95ef5..cce7abee2f 100644 --- a/Source/Core/Core/NetPlayClient.h +++ b/Source/Core/Core/NetPlayClient.h @@ -43,6 +43,7 @@ public: virtual void OnMsgChangeGame(const std::string& filename) = 0; virtual void OnMsgStartGame() = 0; virtual void OnMsgStopGame() = 0; + virtual void OnMsgPowerButton() = 0; virtual void OnPadBufferChanged(u32 buffer) = 0; virtual void OnHostInputAuthorityChanged(bool enabled) = 0; virtual void OnDesync(u32 frame, const std::string& player) = 0; @@ -102,6 +103,7 @@ public: bool ChangeGame(const std::string& game); void SendChatMessage(const std::string& msg); void RequestStopGame(); + void SendPowerButtonEvent(); // Send and receive pads values bool WiimoteUpdate(int _number, u8* data, const u8 size, u8 reporting_mode); diff --git a/Source/Core/Core/NetPlayProto.h b/Source/Core/Core/NetPlayProto.h index 8e175de807..f8449f36c0 100644 --- a/Source/Core/Core/NetPlayProto.h +++ b/Source/Core/Core/NetPlayProto.h @@ -124,6 +124,7 @@ enum NP_MSG_GAME_STATUS = 0xA4, NP_MSG_IPL_STATUS = 0xA5, NP_MSG_HOST_INPUT_AUTHORITY = 0xA6, + NP_MSG_POWER_BUTTON = 0xA7, NP_MSG_TIMEBASE = 0xB0, NP_MSG_DESYNC_DETECTED = 0xB1, @@ -180,4 +181,5 @@ IOS::HLE::FS::FileSystem* GetWiiSyncFS(); void SetWiiSyncFS(std::unique_ptr fs); void ClearWiiSyncFS(); void SetSIPollBatching(bool state); +void SendPowerButtonEvent(); } // namespace NetPlay diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 8c5fa6eb3d..bf1a44b930 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -743,6 +743,14 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player) } break; + case NP_MSG_POWER_BUTTON: + { + sf::Packet spac; + spac << static_cast(NP_MSG_POWER_BUTTON); + SendToClients(spac, player.pid); + } + break; + case NP_MSG_TIMEBASE: { u64 timebase = Common::PacketReadU64(packet); diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index e2b9e15791..6899508c17 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -744,6 +744,10 @@ bool MainWindow::RequestStop() if (Core::GetState() == Core::State::Paused) Core::SetState(Core::State::Running); + // Tell NetPlay about the power event + if (NetPlay::IsNetPlayRunning()) + NetPlay::SendPowerButtonEvent(); + return true; } diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp index 1e47f80bb6..30d6146e52 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.cpp @@ -54,6 +54,7 @@ #include "UICommon/DiscordPresence.h" #include "UICommon/GameFile.h" +#include "UICommon/UICommon.h" #include "VideoCommon/VideoConfig.h" @@ -796,6 +797,13 @@ void NetPlayDialog::OnMsgStopGame() QueueOnObject(this, [this] { UpdateDiscordPresence(); }); } +void NetPlayDialog::OnMsgPowerButton() +{ + if (!Core::IsRunning()) + return; + QueueOnObject(this, [] { UICommon::TriggerSTMPowerEvent(); }); +} + void NetPlayDialog::OnPadBufferChanged(u32 buffer) { QueueOnObject(this, [this, buffer] { diff --git a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h index 0f6537f4d5..6a933cd3eb 100644 --- a/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h +++ b/Source/Core/DolphinQt/NetPlay/NetPlayDialog.h @@ -46,6 +46,7 @@ public: void OnMsgChangeGame(const std::string& filename) override; void OnMsgStartGame() override; void OnMsgStopGame() override; + void OnMsgPowerButton() override; void OnPadBufferChanged(u32 buffer) override; void OnHostInputAuthorityChanged(bool enabled) override; void OnDesync(u32 frame, const std::string& player) override;