diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp index 77c373a481..d41ebe4cc9 100644 --- a/Source/Android/jni/MainAndroid.cpp +++ b/Source/Android/jni/MainAndroid.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include #include #include #include @@ -56,13 +55,13 @@ #include "InputCommon/ControllerInterface/Touch/ButtonManager.h" #include "InputCommon/GCAdapter.h" +#include "UICommon/GameFile.h" #include "UICommon/UICommon.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoBackendBase.h" -#include "../../Core/Common/WindowSystemInfo.h" #include "jni/AndroidCommon/AndroidCommon.h" #include "jni/AndroidCommon/IDCache.h" @@ -521,7 +520,7 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Initialize(J Common::AndroidSetReportHandler(&ReportSend); DolphinAnalytics::AndroidSetGetValFunc(&GetAnalyticValue); UICommon::Init(); - GCAdapter::Init(); + UICommon::InitControllers(WindowSystemInfo(WindowSystemType::Android, nullptr, nullptr, nullptr)); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_ReportStartToAnalytics(JNIEnv*, diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index f2a9ec334d..e445749d8d 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -20,6 +20,7 @@ #include "AudioCommon/AudioCommon.h" +#include "Common/Assert.h" #include "Common/CPUDetect.h" #include "Common/CommonPaths.h" #include "Common/CommonTypes.h" @@ -470,26 +471,14 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi DeclareAsCPUThread(); s_frame_step = false; - // The frontend will likely have initialized the controller interface, as it needs - // it to provide the configuration dialogs. In this case, instead of re-initializing - // entirely, we switch the window used for inputs to the render window. This way, the - // cursor position is relative to the render window, instead of the main window. - bool init_controllers = false; - if (!g_controller_interface.IsInit()) - { - g_controller_interface.Initialize(wsi); - Pad::Initialize(); - Pad::InitializeGBA(); - Keyboard::Initialize(); - init_controllers = true; - } - else - { - g_controller_interface.ChangeWindow(wsi.render_window); - Pad::LoadConfig(); - Pad::LoadGBAConfig(); - Keyboard::LoadConfig(); - } + // Switch the window used for inputs to the render window. This way, the cursor position + // is relative to the render window, instead of the main window. + ASSERT(g_controller_interface.IsInit()); + g_controller_interface.ChangeWindow(wsi.render_window); + + Pad::LoadConfig(); + Pad::LoadGBAConfig(); + Keyboard::LoadConfig(); BootSessionData boot_session_data = std::move(boot->boot_session_data); const std::optional& savestate_path = boot_session_data.GetSavestatePath(); @@ -506,53 +495,16 @@ static void EmuThread(std::unique_ptr boot, WindowSystemInfo wsi Common::SyncSDImageToSDFolder(); }}; - // Load and Init Wiimotes - only if we are booting in Wii mode - bool init_wiimotes = false; + // Load Wiimotes - only if we are booting in Wii mode if (core_parameter.bWii && !Config::Get(Config::MAIN_BLUETOOTH_PASSTHROUGH_ENABLED)) { - if (init_controllers) - { - Wiimote::Initialize(savestate_path ? Wiimote::InitializeMode::DO_WAIT_FOR_WIIMOTES : - Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES); - init_wiimotes = true; - } - else - { - Wiimote::LoadConfig(); - } + Wiimote::LoadConfig(); if (NetPlay::IsNetPlayRunning()) NetPlay::SetupWiimotes(); } - if (init_controllers) - { - FreeLook::Initialize(); - } - else - { - FreeLook::LoadInputConfig(); - } - - Common::ScopeGuard controller_guard{[init_controllers, init_wiimotes] { - if (!init_controllers) - return; - - if (init_wiimotes) - { - Wiimote::ResetAllWiimotes(); - Wiimote::Shutdown(); - } - - FreeLook::Shutdown(); - - ResetRumble(); - - Keyboard::Shutdown(); - Pad::Shutdown(); - Pad::ShutdownGBA(); - g_controller_interface.Shutdown(); - }}; + FreeLook::LoadInputConfig(); Movie::Init(*boot); Common::ScopeGuard movie_guard{&Movie::Shutdown}; diff --git a/Source/Core/DolphinNoGUI/MainNoGUI.cpp b/Source/Core/DolphinNoGUI/MainNoGUI.cpp index cec4788f1c..03ea30ec17 100644 --- a/Source/Core/DolphinNoGUI/MainNoGUI.cpp +++ b/Source/Core/DolphinNoGUI/MainNoGUI.cpp @@ -17,6 +17,7 @@ #include #endif +#include "Common/ScopeGuard.h" #include "Common/StringUtil.h" #include "Core/Boot/Boot.h" #include "Core/BootManager.h" @@ -226,10 +227,6 @@ int main(int argc, char* argv[]) if (options.is_set("user")) user_directory = static_cast(options.get("user")); - UICommon::SetUserDirectory(user_directory); - UICommon::Init(); - GCAdapter::Init(); - s_platform = GetPlatform(options); if (!s_platform || !s_platform->Init()) { @@ -237,6 +234,17 @@ int main(int argc, char* argv[]) return 1; } + const WindowSystemInfo wsi = s_platform->GetWindowSystemInfo(); + + UICommon::SetUserDirectory(user_directory); + UICommon::Init(); + UICommon::InitControllers(wsi); + + Common::ScopeGuard ui_common_guard([] { + UICommon::ShutdownControllers(); + UICommon::Shutdown(); + }); + if (save_state_path && !game_specified) { fprintf(stderr, "A save state cannot be loaded without specifying a game to launch.\n"); @@ -263,7 +271,7 @@ int main(int argc, char* argv[]) DolphinAnalytics::Instance().ReportDolphinStart("nogui"); - if (!BootManager::BootCore(std::move(boot), s_platform->GetWindowSystemInfo())) + if (!BootManager::BootCore(std::move(boot), wsi)) { fprintf(stderr, "Could not boot the specified file\n"); return 1; @@ -278,7 +286,6 @@ int main(int argc, char* argv[]) Core::Shutdown(); s_platform.reset(); - UICommon::Shutdown(); return 0; } diff --git a/Source/Core/DolphinQt/HotkeyScheduler.cpp b/Source/Core/DolphinQt/HotkeyScheduler.cpp index c3d2aadcb7..52fd1ac00a 100644 --- a/Source/Core/DolphinQt/HotkeyScheduler.cpp +++ b/Source/Core/DolphinQt/HotkeyScheduler.cpp @@ -48,8 +48,6 @@ constexpr const char* DUBOIS_ALGORITHM_SHADER = "dubois"; HotkeyScheduler::HotkeyScheduler() : m_stop_requested(false) { - HotkeyManagerEmu::Initialize(); - HotkeyManagerEmu::LoadConfig(); HotkeyManagerEmu::Enable(true); } diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index dab8f45c24..281bbc78a8 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -321,24 +321,12 @@ void MainWindow::InitControllers() if (g_controller_interface.IsInit()) return; - g_controller_interface.Initialize(GetWindowSystemInfo(windowHandle())); - if (!g_controller_interface.HasDefaultDevice()) - { - // Note that the CI default device could be still temporarily removed at any time - WARN_LOG_FMT(CONTROLLERINTERFACE, - "No default device has been added in time. EmulatedController(s) defaulting adds" - " input mappings made for a specific default device depending on the platform"); - } - GCAdapter::Init(); - Pad::Initialize(); - Pad::InitializeGBA(); - Keyboard::Initialize(); - Wiimote::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES); - FreeLook::Initialize(); + UICommon::InitControllers(GetWindowSystemInfo(windowHandle())); + m_hotkey_scheduler = new HotkeyScheduler(); m_hotkey_scheduler->Start(); - // Defaults won't work reliabily without loading and saving the config first + // Defaults won't work reliably without loading and saving the config first Wiimote::LoadConfig(); Wiimote::GetConfig()->SaveConfig(); @@ -362,13 +350,7 @@ void MainWindow::ShutdownControllers() Settings::Instance().UnregisterDevicesChangedCallback(); - Pad::Shutdown(); - Pad::ShutdownGBA(); - Keyboard::Shutdown(); - Wiimote::Shutdown(); - HotkeyManagerEmu::Shutdown(); - FreeLook::Shutdown(); - g_controller_interface.Shutdown(); + UICommon::ShutdownControllers(); m_hotkey_scheduler->deleteLater(); } diff --git a/Source/Core/UICommon/UICommon.cpp b/Source/Core/UICommon/UICommon.cpp index 469c9b2c67..8d9dc2abb8 100644 --- a/Source/Core/UICommon/UICommon.cpp +++ b/Source/Core/UICommon/UICommon.cpp @@ -28,12 +28,18 @@ #include "Core/ConfigLoaders/BaseConfigLoader.h" #include "Core/ConfigManager.h" #include "Core/Core.h" +#include "Core/FreeLookManager.h" +#include "Core/HW/GBAPad.h" +#include "Core/HW/GCKeyboard.h" +#include "Core/HW/GCPad.h" #include "Core/HW/ProcessorInterface.h" #include "Core/HW/Wiimote.h" +#include "Core/HotkeyManager.h" #include "Core/IOS/IOS.h" #include "Core/IOS/STM/STM.h" #include "Core/WiiRoot.h" +#include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/GCAdapter.h" #include "UICommon/DiscordPresence.h" @@ -128,6 +134,41 @@ void Shutdown() Config::Shutdown(); } +void InitControllers(const WindowSystemInfo& wsi) +{ + if (g_controller_interface.IsInit()) + return; + + g_controller_interface.Initialize(wsi); + + if (!g_controller_interface.HasDefaultDevice()) + { + // Note that the CI default device could be still temporarily removed at any time + WARN_LOG_FMT(CONTROLLERINTERFACE, "No default device has been added in time. Premade control " + "mappings intended for the default device may not work."); + } + + GCAdapter::Init(); + Pad::Initialize(); + Pad::InitializeGBA(); + Keyboard::Initialize(); + Wiimote::Initialize(Wiimote::InitializeMode::DO_NOT_WAIT_FOR_WIIMOTES); + HotkeyManagerEmu::Initialize(); + FreeLook::Initialize(); +} + +void ShutdownControllers() +{ + Pad::Shutdown(); + Pad::ShutdownGBA(); + Keyboard::Shutdown(); + Wiimote::Shutdown(); + HotkeyManagerEmu::Shutdown(); + FreeLook::Shutdown(); + + g_controller_interface.Shutdown(); +} + void SetLocale(std::string locale_name) { auto set_locale = [](const std::string& locale) { diff --git a/Source/Core/UICommon/UICommon.h b/Source/Core/UICommon/UICommon.h index 6bdb11f541..f57518cf14 100644 --- a/Source/Core/UICommon/UICommon.h +++ b/Source/Core/UICommon/UICommon.h @@ -7,11 +7,16 @@ #include "Common/CommonTypes.h" +struct WindowSystemInfo; + namespace UICommon { void Init(); void Shutdown(); +void InitControllers(const WindowSystemInfo& wsi); +void ShutdownControllers(); + #ifdef HAVE_X11 void InhibitScreenSaver(unsigned long win, bool enable); #else