diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 844801a0ca..4712b1e4ee 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -45,6 +45,9 @@ #include "Core/HW/HW.h" #include "Core/HW/Memmap.h" #include "Core/HW/ProcessorInterface.h" +#if defined(__LIBUSB__) || defined(_WIN32) +#include "Core/HW/SI_GCAdapter.h" +#endif #include "Core/HW/SystemTimers.h" #include "Core/HW/VideoInterface.h" #include "Core/HW/Wiimote.h" @@ -274,6 +277,9 @@ void Stop() // - Hammertime! g_video_backend->Video_ExitLoop(); } +#if defined(__LIBUSB__) || defined(_WIN32) + SI_GCAdapter::ResetRumble(); +#endif } void DeclareAsCPUThread() @@ -608,6 +614,9 @@ void SetState(EState _State) case CORE_PAUSE: CPU::EnableStepping(true); // Break Wiimote::Pause(); +#if defined(__LIBUSB__) || defined(_WIN32) + SI_GCAdapter::ResetRumble(); +#endif break; case CORE_RUN: CPU::EnableStepping(false); @@ -716,6 +725,9 @@ bool PauseAndLock(bool doLock, bool unpauseOnUnlock) // video has to come after CPU, because CPU thread can wait for video thread (s_efbAccessRequested). g_video_backend->PauseAndLock(doLock, unpauseOnUnlock); +#if defined(__LIBUSB__) || defined(_WIN32) + SI_GCAdapter::ResetRumble(); +#endif return wasUnpaused; } diff --git a/Source/Core/Core/HW/SI_GCAdapter.cpp b/Source/Core/Core/HW/SI_GCAdapter.cpp index f018423d26..655b9965e0 100644 --- a/Source/Core/Core/HW/SI_GCAdapter.cpp +++ b/Source/Core/Core/HW/SI_GCAdapter.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. +#include #include #include @@ -295,6 +296,7 @@ static void AddGCAdapter(libusb_device* device) s_detected = true; if (s_detect_callback != nullptr) s_detect_callback(); + ResetRumble(); } void Shutdown() @@ -398,6 +400,23 @@ void Input(int chan, GCPadStatus* pad) } } +void ResetRumble() +{ + if (!SConfig::GetInstance().m_GameCubeAdapter) + return; + if (s_handle == nullptr || !s_detected) + return; + + std::fill(std::begin(s_controller_rumble), std::end(s_controller_rumble), 0); + + unsigned char rumble[5] = {0x11, s_controller_rumble[0], s_controller_rumble[1], s_controller_rumble[2], s_controller_rumble[3]}; + + int size = 0; + libusb_interrupt_transfer(s_handle, s_endpoint_out, rumble, sizeof(rumble), &size, 16); + + DEBUG_LOG(SERIALINTERFACE, "Rumble state reset"); +} + void Output(int chan, u8 rumble_command) { if (s_handle == nullptr || !SConfig::GetInstance().m_GameCubeAdapter || !SConfig::GetInstance().m_AdapterRumble) diff --git a/Source/Core/Core/HW/SI_GCAdapter.h b/Source/Core/Core/HW/SI_GCAdapter.h index bfef21bdf6..13deb8b536 100644 --- a/Source/Core/Core/HW/SI_GCAdapter.h +++ b/Source/Core/Core/HW/SI_GCAdapter.h @@ -13,6 +13,7 @@ namespace SI_GCAdapter void Init(); void Reset(); +void ResetRumble(); void Setup(); void Shutdown(); void SetAdapterCallback(std::function func);