forked from eden-emu/eden
		
	Merge pull request #13142 from t895/vibration-queue
android: Play vibrations asynchronously
This commit is contained in:
		
						commit
						d1e0039bc8
					
				
					 4 changed files with 44 additions and 17 deletions
				
			
		|  | @ -3,6 +3,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <set> | #include <set> | ||||||
| #include <common/settings_input.h> | #include <common/settings_input.h> | ||||||
|  | #include <common/thread.h> | ||||||
| #include <jni.h> | #include <jni.h> | ||||||
| #include "common/android/android_common.h" | #include "common/android/android_common.h" | ||||||
| #include "common/android/id_cache.h" | #include "common/android/id_cache.h" | ||||||
|  | @ -10,7 +11,18 @@ | ||||||
| 
 | 
 | ||||||
| namespace InputCommon { | namespace InputCommon { | ||||||
| 
 | 
 | ||||||
| Android::Android(std::string input_engine_) : InputEngine(std::move(input_engine_)) {} | Android::Android(std::string input_engine_) : InputEngine(std::move(input_engine_)) { | ||||||
|  |     vibration_thread = std::jthread([this](std::stop_token token) { | ||||||
|  |         Common::SetCurrentThreadName("Android_Vibration"); | ||||||
|  |         auto env = Common::Android::GetEnvForThread(); | ||||||
|  |         using namespace std::chrono_literals; | ||||||
|  |         while (!token.stop_requested()) { | ||||||
|  |             SendVibrations(env, token); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | Android::~Android() = default; | ||||||
| 
 | 
 | ||||||
| void Android::RegisterController(jobject j_input_device) { | void Android::RegisterController(jobject j_input_device) { | ||||||
|     auto env = Common::Android::GetEnvForThread(); |     auto env = Common::Android::GetEnvForThread(); | ||||||
|  | @ -57,17 +69,11 @@ void Android::SetMotionState(std::string guid, size_t port, u64 delta_timestamp, | ||||||
| Common::Input::DriverResult Android::SetVibration( | Common::Input::DriverResult Android::SetVibration( | ||||||
|     [[maybe_unused]] const PadIdentifier& identifier, |     [[maybe_unused]] const PadIdentifier& identifier, | ||||||
|     [[maybe_unused]] const Common::Input::VibrationStatus& vibration) { |     [[maybe_unused]] const Common::Input::VibrationStatus& vibration) { | ||||||
|     auto device = input_devices.find(identifier); |     vibration_queue.Push(VibrationRequest{ | ||||||
|     if (device != input_devices.end()) { |         .identifier = identifier, | ||||||
|         Common::Android::RunJNIOnFiber<void>([&](JNIEnv* env) { |         .vibration = vibration, | ||||||
|             float average_intensity = |     }); | ||||||
|                 static_cast<float>((vibration.high_amplitude + vibration.low_amplitude) / 2.0); |     return Common::Input::DriverResult::Success; | ||||||
|             env->CallVoidMethod(device->second, Common::Android::GetYuzuDeviceVibrate(), |  | ||||||
|                                 average_intensity); |  | ||||||
|         }); |  | ||||||
|         return Common::Input::DriverResult::Success; |  | ||||||
|     } |  | ||||||
|     return Common::Input::DriverResult::NotSupported; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool Android::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) { | bool Android::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) { | ||||||
|  | @ -347,4 +353,15 @@ PadIdentifier Android::GetIdentifier(const std::string& guid, size_t port) const | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void Android::SendVibrations(JNIEnv* env, std::stop_token token) { | ||||||
|  |     VibrationRequest request = vibration_queue.PopWait(token); | ||||||
|  |     auto device = input_devices.find(request.identifier); | ||||||
|  |     if (device != input_devices.end()) { | ||||||
|  |         float average_intensity = static_cast<float>( | ||||||
|  |             (request.vibration.high_amplitude + request.vibration.low_amplitude) / 2.0); | ||||||
|  |         env->CallVoidMethod(device->second, Common::Android::GetYuzuDeviceVibrate(), | ||||||
|  |                             average_intensity); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } // namespace InputCommon
 | } // namespace InputCommon
 | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <set> | #include <set> | ||||||
|  | #include <common/threadsafe_queue.h> | ||||||
| #include <jni.h> | #include <jni.h> | ||||||
| #include "input_common/input_engine.h" | #include "input_common/input_engine.h" | ||||||
| 
 | 
 | ||||||
|  | @ -16,6 +17,8 @@ class Android final : public InputEngine { | ||||||
| public: | public: | ||||||
|     explicit Android(std::string input_engine_); |     explicit Android(std::string input_engine_); | ||||||
| 
 | 
 | ||||||
|  |     ~Android() override; | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * Registers controller number to accept new inputs. |      * Registers controller number to accept new inputs. | ||||||
|      * @param j_input_device YuzuInputDevice object from the Android frontend to register. |      * @param j_input_device YuzuInputDevice object from the Android frontend to register. | ||||||
|  | @ -89,6 +92,9 @@ private: | ||||||
|     /// Returns the correct identifier corresponding to the player index
 |     /// Returns the correct identifier corresponding to the player index
 | ||||||
|     PadIdentifier GetIdentifier(const std::string& guid, size_t port) const; |     PadIdentifier GetIdentifier(const std::string& guid, size_t port) const; | ||||||
| 
 | 
 | ||||||
|  |     /// Takes all vibrations from the queue and sends the command to the controller
 | ||||||
|  |     void SendVibrations(JNIEnv* env, std::stop_token token); | ||||||
|  | 
 | ||||||
|     static constexpr s32 AXIS_X = 0; |     static constexpr s32 AXIS_X = 0; | ||||||
|     static constexpr s32 AXIS_Y = 1; |     static constexpr s32 AXIS_Y = 1; | ||||||
|     static constexpr s32 AXIS_Z = 11; |     static constexpr s32 AXIS_Z = 11; | ||||||
|  | @ -133,6 +139,10 @@ private: | ||||||
|                                                    redmagic_vid, backbone_labs_vid, xbox_vid}; |                                                    redmagic_vid, backbone_labs_vid, xbox_vid}; | ||||||
|     const std::vector<std::string> flipped_xy_vids{sony_vid, razer_vid, redmagic_vid, |     const std::vector<std::string> flipped_xy_vids{sony_vid, razer_vid, redmagic_vid, | ||||||
|                                                    backbone_labs_vid, xbox_vid}; |                                                    backbone_labs_vid, xbox_vid}; | ||||||
|  | 
 | ||||||
|  |     /// Queue of vibration request to controllers
 | ||||||
|  |     Common::SPSCQueue<VibrationRequest> vibration_queue; | ||||||
|  |     std::jthread vibration_thread; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace InputCommon
 | } // namespace InputCommon
 | ||||||
|  |  | ||||||
|  | @ -69,11 +69,6 @@ public: | ||||||
|     bool IsVibrationEnabled(const PadIdentifier& identifier) override; |     bool IsVibrationEnabled(const PadIdentifier& identifier) override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     struct VibrationRequest { |  | ||||||
|         PadIdentifier identifier; |  | ||||||
|         Common::Input::VibrationStatus vibration; |  | ||||||
|     }; |  | ||||||
| 
 |  | ||||||
|     void InitJoystick(int joystick_index); |     void InitJoystick(int joystick_index); | ||||||
|     void CloseJoystick(SDL_Joystick* sdl_joystick); |     void CloseJoystick(SDL_Joystick* sdl_joystick); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -46,6 +46,11 @@ enum class EngineInputType { | ||||||
|     Nfc, |     Nfc, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct VibrationRequest { | ||||||
|  |     PadIdentifier identifier; | ||||||
|  |     Common::Input::VibrationStatus vibration; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| namespace std { | namespace std { | ||||||
| // Hash used to create lists from PadIdentifier data
 | // Hash used to create lists from PadIdentifier data
 | ||||||
| template <> | template <> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 liamwhite
						liamwhite