forked from suyu/suyu
Merge pull request #8374 from german77/asnycvibrations
input_common: Make vibration request async
This commit is contained in:
commit
d879741ec6
4 changed files with 63 additions and 7 deletions
|
@ -72,6 +72,7 @@ enum class PollingError {
|
|||
enum class VibrationAmplificationType {
|
||||
Linear,
|
||||
Exponential,
|
||||
Test,
|
||||
};
|
||||
|
||||
// Analog properties for calibration
|
||||
|
|
|
@ -884,18 +884,42 @@ bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue v
|
|||
}
|
||||
|
||||
bool EmulatedController::TestVibration(std::size_t device_index) {
|
||||
static constexpr VibrationValue test_vibration = {
|
||||
if (device_index >= output_devices.size()) {
|
||||
return false;
|
||||
}
|
||||
if (!output_devices[device_index]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto player_index = NpadIdTypeToIndex(npad_id_type);
|
||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||
|
||||
if (!player.vibration_enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Common::Input::VibrationStatus test_vibration = {
|
||||
.low_amplitude = 0.001f,
|
||||
.low_frequency = 160.0f,
|
||||
.low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
|
||||
.high_amplitude = 0.001f,
|
||||
.high_frequency = 320.0f,
|
||||
.high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
|
||||
.type = Common::Input::VibrationAmplificationType::Test,
|
||||
};
|
||||
|
||||
const Common::Input::VibrationStatus zero_vibration = {
|
||||
.low_amplitude = DEFAULT_VIBRATION_VALUE.low_amplitude,
|
||||
.low_frequency = DEFAULT_VIBRATION_VALUE.low_frequency,
|
||||
.high_amplitude = DEFAULT_VIBRATION_VALUE.high_amplitude,
|
||||
.high_frequency = DEFAULT_VIBRATION_VALUE.high_frequency,
|
||||
.type = Common::Input::VibrationAmplificationType::Test,
|
||||
};
|
||||
|
||||
// Send a slight vibration to test for rumble support
|
||||
SetVibration(device_index, test_vibration);
|
||||
output_devices[device_index]->SetVibration(test_vibration);
|
||||
|
||||
// Stop any vibration and return the result
|
||||
return SetVibration(device_index, DEFAULT_VIBRATION_VALUE);
|
||||
return output_devices[device_index]->SetVibration(zero_vibration) ==
|
||||
Common::Input::VibrationError::None;
|
||||
}
|
||||
|
||||
bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) {
|
||||
|
|
|
@ -434,6 +434,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
|
|||
using namespace std::chrono_literals;
|
||||
while (initialized) {
|
||||
SDL_PumpEvents();
|
||||
SendVibrations();
|
||||
std::this_thread::sleep_for(1ms);
|
||||
}
|
||||
});
|
||||
|
@ -531,13 +532,31 @@ Common::Input::VibrationError SDLDriver::SetRumble(
|
|||
.type = Common::Input::VibrationAmplificationType::Exponential,
|
||||
};
|
||||
|
||||
if (vibration.type == Common::Input::VibrationAmplificationType::Test) {
|
||||
if (!joystick->RumblePlay(new_vibration)) {
|
||||
return Common::Input::VibrationError::Unknown;
|
||||
}
|
||||
return Common::Input::VibrationError::None;
|
||||
}
|
||||
|
||||
vibration_queue.Push(VibrationRequest{
|
||||
.identifier = identifier,
|
||||
.vibration = new_vibration,
|
||||
});
|
||||
|
||||
return Common::Input::VibrationError::None;
|
||||
}
|
||||
|
||||
void SDLDriver::SendVibrations() {
|
||||
while (!vibration_queue.Empty()) {
|
||||
VibrationRequest request;
|
||||
vibration_queue.Pop(request);
|
||||
const auto joystick = GetSDLJoystickByGUID(request.identifier.guid.RawString(),
|
||||
static_cast<int>(request.identifier.port));
|
||||
joystick->RumblePlay(request.vibration);
|
||||
}
|
||||
}
|
||||
|
||||
Common::ParamPackage SDLDriver::BuildAnalogParamPackageForButton(int port, std::string guid,
|
||||
s32 axis, float value) const {
|
||||
Common::ParamPackage params{};
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <SDL.h>
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "common/threadsafe_queue.h"
|
||||
#include "input_common/input_engine.h"
|
||||
|
||||
union SDL_Event;
|
||||
|
@ -64,12 +65,20 @@ public:
|
|||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
||||
|
||||
private:
|
||||
struct VibrationRequest {
|
||||
PadIdentifier identifier;
|
||||
Common::Input::VibrationStatus vibration;
|
||||
};
|
||||
|
||||
void InitJoystick(int joystick_index);
|
||||
void CloseJoystick(SDL_Joystick* sdl_joystick);
|
||||
|
||||
/// Needs to be called before SDL_QuitSubSystem.
|
||||
void CloseJoysticks();
|
||||
|
||||
/// Takes all vibrations from the queue and sends the command to the controller
|
||||
void SendVibrations();
|
||||
|
||||
Common::ParamPackage BuildAnalogParamPackageForButton(int port, std::string guid, s32 axis,
|
||||
float value = 0.1f) const;
|
||||
Common::ParamPackage BuildButtonParamPackageForButton(int port, std::string guid,
|
||||
|
@ -107,6 +116,9 @@ private:
|
|||
/// Returns true if the button is on the left joycon
|
||||
bool IsButtonOnLeftSide(Settings::NativeButton::Values button) const;
|
||||
|
||||
/// Queue of vibration request to controllers
|
||||
Common::SPSCQueue<VibrationRequest> vibration_queue;
|
||||
|
||||
/// Map of GUID of a list of corresponding virtual Joysticks
|
||||
std::unordered_map<std::string, std::vector<std::shared_ptr<SDLJoystick>>> joystick_map;
|
||||
std::mutex joystick_map_mutex;
|
||||
|
|
Loading…
Reference in a new issue