// Copyright 2014 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include "Common/Event.h" #include "Common/Flag.h" #include "InputCommon/ControllerInterface/CoreDevice.h" #include "InputCommon/ControllerInterface/DInput/DInput8.h" namespace ciface::ForceFeedback { class ForceFeedbackDevice : public Core::Device { public: bool InitForceFeedback(const LPDIRECTINPUTDEVICE8, int axis_count); void DeInitForceFeedback(); private: void ThreadFunc(); class Force : public Output { public: Force(ForceFeedbackDevice* parent, const char* name, LPDIRECTINPUTEFFECT effect); void UpdateOutput(); void Release(); void SetState(ControlState state) override; std::string GetName() const override; protected: const LPDIRECTINPUTEFFECT m_effect; private: virtual void UpdateEffect(int magnitude) = 0; ForceFeedbackDevice& m_parent; const char* const m_name; std::atomic m_desired_magnitude; }; template class TypedForce : public Force { public: TypedForce(ForceFeedbackDevice* parent, const char* name, LPDIRECTINPUTEFFECT effect, const P& params); private: void UpdateEffect(int magnitude) override; // Returns true if parameters changed. bool UpdateParameters(int magnitude); void PlayEffect(); void StopEffect(); P m_params = {}; }; void SignalUpdateThread(); typedef TypedForce ForceConstant; typedef TypedForce ForceRamp; typedef TypedForce ForcePeriodic; std::thread m_update_thread; Common::Event m_update_event; Common::Flag m_run_thread; }; } // namespace ciface::ForceFeedback