From 59eb7a864d7b98e7aac42e342ca49704cfab67f5 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 6 Jun 2015 14:52:09 +0200 Subject: [PATCH 1/4] Revert "Join the emu thread in Core::Stop. Get rid of Core::Shutdown which did that before." This reverts commit ba664b3293e88ddee94a4b922ced192f3270b569. Added documentation to Core::Shutdown() to prevent breaking changes. --- Source/Core/Core/Core.cpp | 14 ++++++++++++-- Source/Core/Core/Core.h | 1 + Source/Core/DolphinWX/Main.cpp | 1 + Source/Core/DolphinWX/MainAndroid.cpp | 1 + Source/Core/DolphinWX/MainNoGUI.cpp | 1 + 5 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 604de6f170..c37a5df922 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -277,8 +277,6 @@ void Stop() // - Hammertime! g_video_backend->Video_ExitLoop(); } - if (s_emu_thread.joinable()) - s_emu_thread.join(); } static void DeclareAsCPUThread() @@ -813,6 +811,18 @@ void UpdateTitle() Host_UpdateTitle(SMessage); } +void Shutdown() +{ + // During shutdown DXGI expects us to handle some messages on the UI thread. + // Therefore we can't immediately block and wait for the emu thread to shut + // down, so we join the emu thread as late as possible when the UI has already + // shut down. + // For more info read "DirectX Graphics Infrastructure (DXGI): Best Practices" + // on MSDN. + if (s_emu_thread.joinable()) + s_emu_thread.join(); +} + void SetOnStoppedCallback(StoppedCallbackFunc callback) { s_on_stopped_callback = callback; diff --git a/Source/Core/Core/Core.h b/Source/Core/Core/Core.h index 1eea2be226..9fd256c388 100644 --- a/Source/Core/Core/Core.h +++ b/Source/Core/Core/Core.h @@ -39,6 +39,7 @@ enum EState bool Init(); void Stop(); +void Shutdown(); std::string StopMessage(bool, const std::string&); diff --git a/Source/Core/DolphinWX/Main.cpp b/Source/Core/DolphinWX/Main.cpp index c89e0d8307..19a53332f4 100644 --- a/Source/Core/DolphinWX/Main.cpp +++ b/Source/Core/DolphinWX/Main.cpp @@ -364,6 +364,7 @@ void DolphinApp::OnEndSession(wxCloseEvent& event) int DolphinApp::OnExit() { + Core::Shutdown(); UICommon::Shutdown(); delete m_locale; diff --git a/Source/Core/DolphinWX/MainAndroid.cpp b/Source/Core/DolphinWX/MainAndroid.cpp index 1389abdcee..604e75216a 100644 --- a/Source/Core/DolphinWX/MainAndroid.cpp +++ b/Source/Core/DolphinWX/MainAndroid.cpp @@ -622,6 +622,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv * updateMainFrameEvent.Wait(); } + Core::Shutdown(); UICommon::Shutdown(); ANativeWindow_release(surf); } diff --git a/Source/Core/DolphinWX/MainNoGUI.cpp b/Source/Core/DolphinWX/MainNoGUI.cpp index 9186742d46..60c7c7a0ee 100644 --- a/Source/Core/DolphinWX/MainNoGUI.cpp +++ b/Source/Core/DolphinWX/MainNoGUI.cpp @@ -359,6 +359,7 @@ int main(int argc, char* argv[]) while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) updateMainFrameEvent.Wait(); + Core::Shutdown(); platform->Shutdown(); UICommon::Shutdown(); From 0092f5207ba873e54d4793b19bd4c4c13b21d24c Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Wed, 22 Jul 2015 09:44:39 +0200 Subject: [PATCH 2/4] Core: Don't return true on IsRunning() when stopping emulation. --- Source/Core/Core/Core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index c37a5df922..ade5554b6c 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -163,7 +163,7 @@ void DisplayMessage(const std::string& message, int time_in_ms) bool IsRunning() { - return (GetState() != CORE_UNINITIALIZED) || s_hardware_initialized; + return (GetState() != CORE_UNINITIALIZED || s_hardware_initialized) && !s_is_stopping; } bool IsRunningAndStarted() From 75fc2133592018ceb6b6a3e3bccbd66087492703 Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Thu, 23 Jul 2015 09:09:01 +0200 Subject: [PATCH 3/4] FrameTools: Disable hotkeys while a modal dialog is shown. --- Source/Core/DolphinWX/FrameTools.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Source/Core/DolphinWX/FrameTools.cpp b/Source/Core/DolphinWX/FrameTools.cpp index a54677423d..8addacc7f7 100644 --- a/Source/Core/DolphinWX/FrameTools.cpp +++ b/Source/Core/DolphinWX/FrameTools.cpp @@ -1153,7 +1153,9 @@ void CFrame::DoStop() wxYES_NO | wxSTAY_ON_TOP | wxICON_EXCLAMATION, wxDefaultPosition); + HotkeyManagerEmu::Enable(false); int Ret = m_StopDlg.ShowModal(); + HotkeyManagerEmu::Enable(true); if (Ret != wxID_YES) { Core::SetState(state); @@ -1297,29 +1299,37 @@ void CFrame::OnReset(wxCommandEvent& WXUNUSED (event)) void CFrame::OnConfigMain(wxCommandEvent& WXUNUSED (event)) { CConfigMain ConfigMain(this); + HotkeyManagerEmu::Enable(false); if (ConfigMain.ShowModal() == wxID_OK) m_GameListCtrl->Update(); + HotkeyManagerEmu::Enable(true); UpdateGUI(); } void CFrame::OnConfigGFX(wxCommandEvent& WXUNUSED (event)) { + HotkeyManagerEmu::Enable(false); if (g_video_backend) g_video_backend->ShowConfig(this); + HotkeyManagerEmu::Enable(true); } void CFrame::OnConfigAudio(wxCommandEvent& WXUNUSED (event)) { CConfigMain ConfigMain(this); ConfigMain.SetSelectedTab(CConfigMain::ID_AUDIOPAGE); + HotkeyManagerEmu::Enable(false); if (ConfigMain.ShowModal() == wxID_OK) m_GameListCtrl->Update(); + HotkeyManagerEmu::Enable(true); } void CFrame::OnConfigControllers(wxCommandEvent& WXUNUSED (event)) { ControllerConfigDiag config_dlg(this); + HotkeyManagerEmu::Enable(false); config_dlg.ShowModal(); + HotkeyManagerEmu::Enable(true); } void CFrame::OnConfigHotkey(wxCommandEvent& WXUNUSED (event)) @@ -1364,7 +1374,9 @@ void CFrame::OnHelp(wxCommandEvent& event) case wxID_ABOUT: { AboutDolphin frame(this); + HotkeyManagerEmu::Enable(false); frame.ShowModal(); + HotkeyManagerEmu::Enable(true); } break; case IDM_HELP_WEBSITE: @@ -1424,7 +1436,9 @@ void CFrame::OnNetPlay(wxCommandEvent& WXUNUSED (event)) void CFrame::OnMemcard(wxCommandEvent& WXUNUSED (event)) { CMemcardManager MemcardManager(this); + HotkeyManagerEmu::Enable(false); MemcardManager.ShowModal(); + HotkeyManagerEmu::Enable(true); } void CFrame::OnExportAllSaves(wxCommandEvent& WXUNUSED (event)) From 3814b5b7024e03fbb2a9be2784842b586d96d17a Mon Sep 17 00:00:00 2001 From: Jules Blok Date: Sat, 25 Jul 2015 13:53:27 +0200 Subject: [PATCH 4/4] HotkeyManager: Activate hotkey when key is pressed. As opposed to activating the hotkey when it is released. --- Source/Core/Core/HotkeyManager.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/HotkeyManager.cpp b/Source/Core/Core/HotkeyManager.cpp index 64ffb097f7..2e53ad1ac0 100644 --- a/Source/Core/Core/HotkeyManager.cpp +++ b/Source/Core/Core/HotkeyManager.cpp @@ -159,16 +159,14 @@ bool IsPressed(int Id, bool held) unsigned int setKey = Id % 32; if (s_hotkey.button[set] & (1 << setKey)) { + bool pressed = !!(s_hotkeyDown[set] & (1 << setKey)); s_hotkeyDown[set] |= (1 << setKey); - if (held) + if (!pressed || held) return true; } else { - bool pressed = !!(s_hotkeyDown[set] & (1 << setKey)); s_hotkeyDown[set] &= ~(1 << setKey); - if (pressed) - return true; } return false;