diff --git a/Core/SNES/Input/SnesRumbleController.cpp b/Core/SNES/Input/SnesRumbleController.cpp index f2ee18e05..74d0d2a0b 100644 --- a/Core/SNES/Input/SnesRumbleController.cpp +++ b/Core/SNES/Input/SnesRumbleController.cpp @@ -21,6 +21,24 @@ void SnesRumbleController::Serialize(Serializer& s) { SnesController::Serialize(s); SV(_rumbleData); + SV(_rumbleActive); + SV(_lastRumbleFrame); +} + +void SnesRumbleController::RefreshStateBuffer() +{ + _rumbleData = 0; + + //The LRG rumble controller stops rumbling shortly after the last rumble command. + //Not accurate, assumes the game regularly latches the controller. + if(_rumbleActive) { + if(_emu->GetFrameCount() - _lastRumbleFrame > 2) { + KeyManager::SetForceFeedback(0, 0); + _rumbleActive = false; + } + } + + SnesController::RefreshStateBuffer(); } uint8_t SnesRumbleController::ReadRam(uint16_t addr) @@ -44,7 +62,8 @@ uint8_t SnesRumbleController::ReadRam(uint16_t addr) KeyManager::SetForceFeedback(rightRumble, leftRumble); - _rumbleData = 0; + _rumbleActive = true; + _lastRumbleFrame = _emu->GetFrameCount(); } } diff --git a/Core/SNES/Input/SnesRumbleController.h b/Core/SNES/Input/SnesRumbleController.h index b9f2dcd5e..19223a2f7 100644 --- a/Core/SNES/Input/SnesRumbleController.h +++ b/Core/SNES/Input/SnesRumbleController.h @@ -12,9 +12,12 @@ class SnesRumbleController : public SnesController private: SnesConsole* _console = nullptr; uint16_t _rumbleData = 0; + bool _rumbleActive = false; + uint32_t _lastRumbleFrame = 0; protected: void Serialize(Serializer& s) override; + void RefreshStateBuffer() override; public: SnesRumbleController(Emulator* emu, SnesConsole* console, uint8_t port, KeyMappingSet keyMappings);