1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-25 04:02:42 +01:00

Input: refactor vibration

There's no need to deal with vibration levels outside of the handlers.
All we need to know is the 0-255 DS3 range which is given by the u8 type.
This commit is contained in:
Megamouse 2022-10-21 22:35:31 +02:00
parent a1f9ff0aaa
commit ddd261c943
18 changed files with 59 additions and 76 deletions

View File

@ -18,6 +18,8 @@ public:
virtual ~PadDevice() = default;
cfg_pad* config{ nullptr };
u8 player_id{0};
u8 large_motor{0};
u8 small_motor{0};
u64 trigger_code_left = 0;
u64 trigger_code_right = 0;
std::array<u64, 4> axis_code_left{};
@ -172,8 +174,6 @@ public:
s32 thumb_max = 255; // NOTE: Better keep this positive
s32 trigger_min = 0;
s32 trigger_max = 255;
s32 vibration_min = 0;
s32 vibration_max = 255;
u32 connected_devices = 0;
pad_handler m_type;
@ -197,7 +197,7 @@ public:
PadHandlerBase(pad_handler type = pad_handler::null);
virtual ~PadHandlerBase() = default;
// Sets window to config the controller(optional)
virtual void SetPadData(const std::string& /*padId*/, u8 /*player_id*/, u32 /*largeMotor*/, u32 /*smallMotor*/, s32 /*r*/, s32 /*g*/, s32 /*b*/, bool /*player_led*/, bool /*battery_led*/, u32 /*battery_led_brightness*/) {}
virtual void SetPadData(const std::string& /*padId*/, u8 /*player_id*/, u8 /*large_motor*/, u8 /*small_motor*/, s32 /*r*/, s32 /*g*/, s32 /*b*/, bool /*player_led*/, bool /*battery_led*/, u32 /*battery_led_brightness*/) {}
virtual u32 get_battery_level(const std::string& /*padId*/) { return 0; }
// Return list of devices for that handler
virtual std::vector<pad_list_entry> list_devices() = 0;

View File

@ -250,11 +250,11 @@ struct AnalogSensor
struct VibrateMotor
{
bool m_isLargeMotor = false;
u16 m_value = 0;
bool m_is_large_motor = false;
u8 m_value = 0;
VibrateMotor(bool largeMotor, u16 value)
: m_isLargeMotor(largeMotor)
VibrateMotor(bool is_large_motor, u8 value)
: m_is_large_motor(is_large_motor)
, m_value(value)
{}
};

View File

@ -239,7 +239,7 @@ namespace rsx
{
if (sinus_modifier >= 0)
{
static const f32 PI = 3.14159265f;
static constexpr f32 PI = 3.14159265f;
const f32 pulse_sinus_x = static_cast<f32>(get_system_time() / 1000) * pulse_speed_modifier;
pulse_sinus_offset = fmod(pulse_sinus_x + sinus_modifier * PI, 2.0f * PI);
}

View File

@ -120,15 +120,15 @@ u32 ds3_pad_handler::get_battery_level(const std::string& padId)
return std::clamp<u32>(device->battery_level, 0, 100);
}
void ds3_pad_handler::SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32/* r*/, s32/* g*/, s32 /* b*/, bool player_led, bool /*battery_led*/, u32 /*battery_led_brightness*/)
void ds3_pad_handler::SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32/* r*/, s32/* g*/, s32 /* b*/, bool player_led, bool /*battery_led*/, u32 /*battery_led_brightness*/)
{
std::shared_ptr<ds3_device> device = get_hid_device(padId);
if (device == nullptr || device->hidDevice == nullptr)
return;
// Set the device's motor speeds to our requested values 0-255
device->large_motor = largeMotor;
device->small_motor = smallMotor;
device->large_motor = large_motor;
device->small_motor = small_motor;
device->player_id = player_id;
int index = 0;
@ -585,8 +585,8 @@ void ds3_pad_handler::apply_pad_data(const pad_ensemble& binding)
const int idx_l = config->switch_vibration_motors ? 1 : 0;
const int idx_s = config->switch_vibration_motors ? 0 : 1;
const int speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : vibration_min;
const int speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : vibration_min;
const u8 speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0;
const u8 speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0;
const bool wireless = dev->cable_state == 0;
const bool low_battery = dev->battery_level < 25;

View File

@ -80,7 +80,7 @@ public:
ds3_pad_handler();
~ds3_pad_handler();
void SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
u32 get_battery_level(const std::string& padId) override;
void init_config(cfg_pad* cfg) override;

View File

@ -113,8 +113,6 @@ ds4_pad_handler::ds4_pad_handler()
thumb_max = 255;
trigger_min = 0;
trigger_max = 255;
vibration_min = 0;
vibration_max = 255;
// set capabilities
b_has_config = true;
@ -197,15 +195,15 @@ u32 ds4_pad_handler::get_battery_level(const std::string& padId)
return std::min<u32>(device->battery_level * 10, 100);
}
void ds4_pad_handler::SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32 r, s32 g, s32 b, bool /*player_led*/, bool battery_led, u32 battery_led_brightness)
void ds4_pad_handler::SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool /*player_led*/, bool battery_led, u32 battery_led_brightness)
{
std::shared_ptr<DS4Device> device = get_hid_device(padId);
if (!device || !device->hidDevice || !device->config)
return;
// Set the device's motor speeds to our requested values 0-255
device->large_motor = largeMotor;
device->small_motor = smallMotor;
device->large_motor = large_motor;
device->small_motor = small_motor;
device->player_id = player_id;
int index = 0;
@ -888,8 +886,8 @@ void ds4_pad_handler::apply_pad_data(const pad_ensemble& binding)
const int idx_l = config->switch_vibration_motors ? 1 : 0;
const int idx_s = config->switch_vibration_motors ? 0 : 1;
const int speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : vibration_min;
const int speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : vibration_min;
const u8 speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0;
const u8 speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0;
const bool wireless = ds4_dev->cable_state == 0;
const bool low_battery = ds4_dev->battery_level < 2;

View File

@ -56,7 +56,7 @@ public:
ds4_pad_handler();
~ds4_pad_handler();
void SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
u32 get_battery_level(const std::string& padId) override;
void init_config(cfg_pad* cfg) override;

View File

@ -131,8 +131,6 @@ dualsense_pad_handler::dualsense_pad_handler()
thumb_max = 255;
trigger_min = 0;
trigger_max = 255;
vibration_min = 0;
vibration_max = 255;
// Set capabilities
b_has_config = true;
@ -1040,8 +1038,8 @@ void dualsense_pad_handler::apply_pad_data(const pad_ensemble& binding)
const int idx_l = config->switch_vibration_motors ? 1 : 0;
const int idx_s = config->switch_vibration_motors ? 0 : 1;
const int speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : vibration_min;
const int speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : vibration_min;
const u8 speed_large = config->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0;
const u8 speed_small = config->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0;
const bool wireless = dualsense_dev->cable_state == 0;
const bool low_battery = dualsense_dev->battery_level <= 1;
@ -1118,15 +1116,15 @@ void dualsense_pad_handler::apply_pad_data(const pad_ensemble& binding)
}
}
void dualsense_pad_handler::SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness)
void dualsense_pad_handler::SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness)
{
std::shared_ptr<DualSenseDevice> device = get_hid_device(padId);
if (device == nullptr || device->hidDevice == nullptr)
return;
// Set the device's motor speeds to our requested values 0-255
device->large_motor = largeMotor;
device->small_motor = smallMotor;
device->large_motor = large_motor;
device->small_motor = small_motor;
device->player_id = player_id;
int index = 0;

View File

@ -69,7 +69,7 @@ public:
dualsense_pad_handler();
~dualsense_pad_handler();
void SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
u32 get_battery_level(const std::string& padId) override;
void init_config(cfg_pad* cfg) override;

View File

@ -28,8 +28,6 @@ evdev_joystick_handler::evdev_joystick_handler()
thumb_max = 255;
trigger_min = 0;
trigger_max = 255;
vibration_min = 0;
vibration_max = 65535;
// set capabilities
b_has_config = true;
@ -521,7 +519,7 @@ void evdev_joystick_handler::get_motion_sensors(const std::string& padId, const
// https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/InputCommon/ControllerInterface/evdev/evdev.cpp
// https://github.com/reicast/reicast-emulator/blob/master/core/linux-dist/evdev.cpp
// http://www.infradead.org/~mchehab/kernel_docs_pdf/linux-input.pdf
void evdev_joystick_handler::SetRumble(EvdevDevice* device, u16 large, u16 small)
void evdev_joystick_handler::SetRumble(EvdevDevice* device, u8 large, u8 small)
{
if (!device || !device->has_rumble || device->effect_id == -2)
return;
@ -530,7 +528,7 @@ void evdev_joystick_handler::SetRumble(EvdevDevice* device, u16 large, u16 small
if (fd < 0)
return;
if (large == device->force_large && small == device->force_small)
if (large == device->large_motor && small == device->small_motor)
return;
// XBox One Controller can't handle faster vibration updates than ~10ms. Elite is even worse.
@ -549,8 +547,8 @@ void evdev_joystick_handler::SetRumble(EvdevDevice* device, u16 large, u16 small
if (large == 0 && small == 0)
{
device->force_large = large;
device->force_small = small;
device->large_motor = large;
device->small_motor = small;
return;
}
@ -561,8 +559,8 @@ void evdev_joystick_handler::SetRumble(EvdevDevice* device, u16 large, u16 small
effect.type = FF_RUMBLE;
effect.id = device->effect_id;
effect.direction = 0;
effect.u.rumble.strong_magnitude = large;
effect.u.rumble.weak_magnitude = small;
effect.u.rumble.strong_magnitude = large * 257;
effect.u.rumble.weak_magnitude = small * 257;
effect.replay.length = 0;
effect.replay.delay = 0;
effect.trigger.button = 0;
@ -594,27 +592,27 @@ void evdev_joystick_handler::SetRumble(EvdevDevice* device, u16 large, u16 small
device->effect_id = -2;
}
device->force_large = large;
device->force_small = small;
device->large_motor = large;
device->small_motor = small;
}
void evdev_joystick_handler::SetPadData(const std::string& padId, u8 /*player_id*/, u32 largeMotor, u32 smallMotor, s32 /* r*/, s32 /* g*/, s32 /* b*/, bool /*player_led*/, bool /*battery_led*/, u32 /*battery_led_brightness*/)
void evdev_joystick_handler::SetPadData(const std::string& padId, u8 /*player_id*/, u8 large_motor, u8 small_motor, s32 /* r*/, s32 /* g*/, s32 /* b*/, bool /*player_led*/, bool /*battery_led*/, u32 /*battery_led_brightness*/)
{
// Get our evdev device
auto dev = get_evdev_device(padId);
if (!dev)
{
evdev_log.error("evdev TestVibration: Device [%s] not found! [largeMotor = %d] [smallMotor = %d]", padId, largeMotor, smallMotor);
evdev_log.error("evdev TestVibration: Device [%s] not found! [large_motor = %d] [small_motor = %d]", padId, large_motor, small_motor);
return;
}
if (!dev->has_rumble)
{
evdev_log.error("evdev TestVibration: Device [%s] does not support rumble features! [largeMotor = %d] [smallMotor = %d]", padId, largeMotor, smallMotor);
evdev_log.error("evdev TestVibration: Device [%s] does not support rumble features! [large_motor = %d] [small_motor = %d]", padId, large_motor, small_motor);
return;
}
SetRumble(static_cast<EvdevDevice*>(dev.get()), largeMotor, smallMotor);
SetRumble(static_cast<EvdevDevice*>(dev.get()), large_motor, small_motor);
}
u32 evdev_joystick_handler::GetButtonInfo(const input_event& evt, const std::shared_ptr<EvdevDevice>& device, int& value)
@ -1156,8 +1154,8 @@ void evdev_joystick_handler::apply_pad_data(const pad_ensemble& binding)
// Handle vibration
const int idx_l = cfg->switch_vibration_motors ? 1 : 0;
const int idx_s = cfg->switch_vibration_motors ? 0 : 1;
const u16 force_large = cfg->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value * 257 : vibration_min;
const u16 force_small = cfg->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value * 257 : vibration_min;
const u8 force_large = cfg->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value * 257 : 0;
const u8 force_small = cfg->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value * 257 : 0;
SetRumble(evdev_device, force_large, force_small);
}

View File

@ -370,8 +370,6 @@ class evdev_joystick_handler final : public PadHandlerBase
int effect_id = -1;
bool has_rumble = false;
bool has_motion = false;
u16 force_large = 0;
u16 force_small = 0;
clock_t last_vibration = 0;
};
@ -386,7 +384,7 @@ public:
void get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist = false, const std::vector<std::string>& buttons = {}) override;
void get_motion_sensors(const std::string& padId, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override;
std::unordered_map<u32, std::string> get_motion_axis_list() const override;
void SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
private:
void close_devices();
@ -397,7 +395,7 @@ private:
std::shared_ptr<evdev_joystick_handler::EvdevDevice> add_motion_device(const std::string& device, bool in_settings);
u32 GetButtonInfo(const input_event& evt, const std::shared_ptr<EvdevDevice>& device, int& button_code);
std::unordered_map<u64, std::pair<u16, bool>> GetButtonValues(const std::shared_ptr<EvdevDevice>& device);
void SetRumble(EvdevDevice* device, u16 large, u16 small);
void SetRumble(EvdevDevice* device, u8 large, u8 small);
// Search axis_orientations map for the direction by index, returns -1 if not found, 0 for positive and 1 for negative
int FindAxisDirection(const std::unordered_map<int, bool>& map, int index);

View File

@ -37,8 +37,6 @@ public:
std::array<u8, 64> padData{};
bool new_output_data{true};
bool enable_player_leds{false};
u8 large_motor{0};
u8 small_motor{0};
u8 led_delay_on{0};
u8 led_delay_off{0};
u8 battery_level{0};

View File

@ -12,12 +12,9 @@ mm_joystick_handler::mm_joystick_handler() : PadHandlerBase(pad_handler::mm)
thumb_max = 255;
trigger_min = 0;
trigger_max = 255;
vibration_min = 0;
vibration_max = 65535;
// set capabilities
b_has_config = true;
b_has_rumble = true;
b_has_deadzones = true;
m_name_string = "Joystick #";

View File

@ -197,15 +197,15 @@ void pad_thread::Init()
}
}
void pad_thread::SetRumble(const u32 pad, u8 largeMotor, bool smallMotor)
void pad_thread::SetRumble(const u32 pad, u8 large_motor, bool small_motor)
{
if (pad >= m_pads.size())
return;
if (m_pads[pad]->m_vibrateMotors.size() >= 2)
{
m_pads[pad]->m_vibrateMotors[0].m_value = largeMotor;
m_pads[pad]->m_vibrateMotors[1].m_value = smallMotor ? 255 : 0;
m_pads[pad]->m_vibrateMotors[0].m_value = large_motor;
m_pads[pad]->m_vibrateMotors[1].m_value = small_motor ? 255 : 0;
}
}

View File

@ -26,7 +26,7 @@ public:
PadInfo& GetInfo() { return m_info; }
auto& GetPads() { return m_pads; }
void SetRumble(const u32 pad, u8 largeMotor, bool smallMotor);
void SetRumble(const u32 pad, u8 large_motor, bool small_motor);
void SetIntercepted(bool intercepted);
s32 AddLddPad();

View File

@ -53,8 +53,6 @@ xinput_pad_handler::xinput_pad_handler() : PadHandlerBase(pad_handler::xinput)
thumb_max = 32767;
trigger_min = 0;
trigger_max = 255;
vibration_min = 0;
vibration_max = 65535;
// set capabilities
b_has_config = true;
@ -128,7 +126,7 @@ void xinput_pad_handler::init_config(cfg_pad* cfg)
cfg->from_default();
}
void xinput_pad_handler::SetPadData(const std::string& padId, u8 /*player_id*/, u32 largeMotor, u32 smallMotor, s32/* r*/, s32/* g*/, s32/* b*/, bool /*player_led*/, bool /*battery_led*/, u32 /*battery_led_brightness*/)
void xinput_pad_handler::SetPadData(const std::string& padId, u8 /*player_id*/, u8 large_motor, u8 small_motor, s32/* r*/, s32/* g*/, s32/* b*/, bool /*player_led*/, bool /*battery_led*/, u32 /*battery_led_brightness*/)
{
const int device_number = GetDeviceNumber(padId);
if (device_number < 0)
@ -138,8 +136,8 @@ void xinput_pad_handler::SetPadData(const std::string& padId, u8 /*player_id*/,
// The two motors are not the same, and they create different vibration effects.
XINPUT_VIBRATION vibrate;
vibrate.wLeftMotorSpeed = largeMotor; // between 0 to 65535
vibrate.wRightMotorSpeed = smallMotor; // between 0 to 65535
vibrate.wLeftMotorSpeed = large_motor * 257; // between 0 to 65535
vibrate.wRightMotorSpeed = small_motor * 257; // between 0 to 65535
(*xinputSetState)(static_cast<u32>(device_number), &vibrate);
}
@ -532,20 +530,20 @@ void xinput_pad_handler::apply_pad_data(const pad_ensemble& binding)
const usz idx_l = cfg->switch_vibration_motors ? 1 : 0;
const usz idx_s = cfg->switch_vibration_motors ? 0 : 1;
const u16 speed_large = cfg->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : static_cast<u16>(vibration_min);
const u16 speed_small = cfg->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : static_cast<u16>(vibration_min);
const u8 speed_large = cfg->enable_vibration_motor_large ? pad->m_vibrateMotors[idx_l].m_value : 0;
const u8 speed_small = cfg->enable_vibration_motor_small ? pad->m_vibrateMotors[idx_s].m_value : 0;
dev->newVibrateData |= dev->largeVibrate != speed_large || dev->smallVibrate != speed_small;
dev->newVibrateData |= dev->large_motor != speed_large || dev->small_motor != speed_small;
dev->largeVibrate = speed_large;
dev->smallVibrate = speed_small;
dev->large_motor = speed_large;
dev->small_motor = speed_small;
// XBox One Controller can't handle faster vibration updates than ~10ms. Elite is even worse. So I'll use 20ms to be on the safe side. No lag was noticable.
if (dev->newVibrateData && steady_clock::now() - dev->last_vibration > 20ms)
{
XINPUT_VIBRATION vibrate;
vibrate.wLeftMotorSpeed = speed_large * 257;
vibrate.wRightMotorSpeed = speed_small * 257;
vibrate.wLeftMotorSpeed = speed_large * 257; // between 0 to 65535
vibrate.wRightMotorSpeed = speed_small * 257; // between 0 to 65535
if ((*xinputSetState)(padnum, &vibrate) == ERROR_SUCCESS)
{

View File

@ -94,8 +94,6 @@ class xinput_pad_handler final : public PadHandlerBase
{
u32 deviceNumber{ 0 };
bool newVibrateData{ true };
u16 largeVibrate{ 0 };
u16 smallVibrate{ 0 };
steady_clock::time_point last_vibration;
bool is_scp_device{ false };
DWORD state{ ERROR_NOT_CONNECTED }; // holds internal controller state change
@ -110,7 +108,7 @@ public:
bool Init() override;
std::vector<pad_list_entry> list_devices() override;
void SetPadData(const std::string& padId, u8 player_id, u32 largeMotor, u32 smallMotor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override;
u32 get_battery_level(const std::string& padId) override;
void init_config(cfg_pad* cfg) override;

View File

@ -1367,8 +1367,8 @@ void pad_settings_dialog::ChangeHandler()
ui->l_description->setText(m_description);
// Update parameters
m_min_force = m_handler->vibration_min;
m_max_force = m_handler->vibration_max;
m_min_force = 0;
m_max_force = 255;
// Reset parameters
m_lx = 0;