mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	android: Play vibrations asynchronously
This commit is contained in:
		@@ -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 <>
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user