cellPad: Add DS3 motor speed threshold

Also add motor speeds to pad debug overlay
This commit is contained in:
Megamouse 2025-09-10 01:10:57 +02:00
parent eb6d13a8c0
commit 6911d0b5e1
7 changed files with 44 additions and 22 deletions

View file

@ -86,6 +86,8 @@ void show_debug_overlay(const CellPadData& data, const Pad& pad, const pad_info&
"> Digital: %5s %5s\n"
"> Press: %5s %5s\n"
"> Sensor: %5s %5s\n"
"> Large Motor: %5d %5d\n"
"> Small Motor: %5d %5d\n"
">\n"
"> Digital 1: 0x%04x 0x%04x\n"
"> Digital 2: 0x%04x 0x%04x\n"
@ -126,6 +128,8 @@ void show_debug_overlay(const CellPadData& data, const Pad& pad, const pad_info&
"on", data.len >= CELL_PAD_LEN_CHANGE_DEFAULT ? "on" : "off",
(setting & CELL_PAD_SETTING_PRESS_ON) ? "on" : "off", data.len >= CELL_PAD_LEN_CHANGE_PRESS_ON ? "on" : "off",
(setting & CELL_PAD_SETTING_SENSOR_ON) ? "on" : "off", data.len >= CELL_PAD_LEN_CHANGE_SENSOR_ON ? "on" : "off",
pad.m_vibrateMotors[0].m_value, pad.m_vibrateMotors[0].m_adjusted_value,
pad.m_vibrateMotors[1].m_value, pad.m_vibrateMotors[1].m_adjusted_value,
pad.m_digital_1, d1,
pad.m_digital_2, d2,
pad.m_press_up, !!(d1 & CELL_PAD_CTRL_UP), data.button[CELL_PAD_BTN_OFFSET_PRESS_UP],

View file

@ -40,7 +40,7 @@ f32 PadHandlerBase::ScaledInput(f32 raw_value, f32 minimum, f32 maximum, f32 dea
}
// convert [min, max] to [0, 1]
const f32 val = static_cast<f32>(std::clamp(raw_value, minimum, maximum) - minimum) / (maximum - minimum);
const f32 val = static_cast<f32>(std::max(minimum, std::min(raw_value, maximum)) - minimum) / (maximum - minimum);
// convert [0, 1] to [0, range]
return range * val;
@ -50,7 +50,7 @@ f32 PadHandlerBase::ScaledInput(f32 raw_value, f32 minimum, f32 maximum, f32 dea
f32 PadHandlerBase::ScaledAxisInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range)
{
// convert [min, max] to [0, 1]
f32 val = static_cast<f32>(std::clamp(raw_value, minimum, maximum) - minimum) / (maximum - minimum);
f32 val = static_cast<f32>(std::max(minimum, std::min(raw_value, maximum)) - minimum) / (maximum - minimum);
if (deadzone > 0)
{
@ -762,6 +762,7 @@ void PadHandlerBase::process()
for (VibrateMotor& motor : pad->m_vibrateMotors)
{
motor.m_value = 0;
motor.m_adjusted_value = 0;
}
pad->m_last_rumble_time_us = 0;

View file

@ -255,15 +255,6 @@ protected:
return {};
}
// Get new multiplied value based on the multiplier
static s32 MultipliedInput(s32 raw_value, s32 multiplier);
// Get new scaled value between 0 and 255 based on its minimum and maximum
static f32 ScaledInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range = 255.0f);
// Get new scaled value between -255 and 255 based on its minimum and maximum
static f32 ScaledAxisInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range = 255.0f);
// Get normalized trigger value based on the range defined by a threshold
u16 NormalizeTriggerInput(u16 value, u32 threshold) const;
@ -276,6 +267,17 @@ protected:
// return is new x and y values in 0-255 range
std::tuple<u16, u16> NormalizeStickDeadzone(s32 inX, s32 inY, u32 deadzone, u32 anti_deadzone) const;
public:
// Get new multiplied value based on the multiplier
static s32 MultipliedInput(s32 raw_value, s32 multiplier);
// Get new scaled value between 0 and 255 based on its minimum and maximum
static f32 ScaledInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range = 255.0f);
// Get new scaled value between -255 and 255 based on its minimum and maximum
static f32 ScaledAxisInput(f32 raw_value, f32 minimum, f32 maximum, f32 deadzone, f32 range = 255.0f);
// get clamped value between 0 and 255
static u16 Clamp0To255(f32 input);
@ -291,7 +293,6 @@ protected:
// This function assumes inX and inY is already in 0-255
static void ConvertToSquirclePoint(u16& inX, u16& inY, u32 squircle_factor);
public:
// u32 thumb_min = 0; // Unused. Make sure all handlers report 0+ values for sticks in get_button_values.
u32 thumb_max = 255;
u32 trigger_min = 0;

View file

@ -1,8 +1,7 @@
#include "stdafx.h"
#include "pad_config.h"
#include "Emu/system_utils.hpp"
LOG_CHANNEL(input_log, "Input");
#include "Emu/Io/PadHandler.h"
extern std::string g_input_config_override;
@ -32,18 +31,30 @@ std::string cfg_pad::get_buttons(std::vector<std::string> vec)
return fmt::merge(vec, ",");
}
u8 cfg_pad::get_large_motor_speed(const std::array<VibrateMotor, 2>& motor_speed) const
u8 cfg_pad::get_large_motor_speed(std::array<VibrateMotor, 2>& motors) const
{
const u8 idx = switch_vibration_motors ? 1 : 0;
VibrateMotor& motor = motors[switch_vibration_motors ? 1 : 0];
const f32 multiplier = multiplier_vibration_motor_large / 100.0f;
return static_cast<u8>(std::clamp(motor_speed[idx].m_value * multiplier, 0.0f, 255.0f));
// Ignore lower range. Scale remaining range to full range.
const f32 adjusted = PadHandlerBase::ScaledInput(motor.m_value, static_cast<f32>(vibration_threshold.get()), 255.0f, 0.0f, 255.0f);
// Apply multiplier
motor.m_adjusted_value = static_cast<u8>(std::clamp(adjusted * multiplier, 0.0f, 255.0f));
return motor.m_adjusted_value;
}
u8 cfg_pad::get_small_motor_speed(const std::array<VibrateMotor, 2>& motor_speed) const
u8 cfg_pad::get_small_motor_speed(std::array<VibrateMotor, 2>& motors) const
{
const u8 idx = switch_vibration_motors ? 0 : 1;
VibrateMotor& motor = motors[switch_vibration_motors ? 0 : 1];
const f32 multiplier = multiplier_vibration_motor_small / 100.0f;
return static_cast<u8>(std::clamp(motor_speed[idx].m_value * multiplier, 0.0f, 255.0f));
// Ignore lower range. Scale remaining range to full range.
const f32 adjusted = PadHandlerBase::ScaledInput(motor.m_value, static_cast<f32>(vibration_threshold.get()), 255.0f, 0.0f, 255.0f);
// Apply multiplier
motor.m_adjusted_value = static_cast<u8>(std::clamp(adjusted * multiplier, 0.0f, 255.0f));
return motor.m_adjusted_value;
}
bool cfg_input::load(const std::string& title_id, const std::string& config_file, bool strict)

View file

@ -28,8 +28,8 @@ struct cfg_pad final : cfg::node
static std::vector<std::string> get_buttons(const std::string& str);
static std::string get_buttons(std::vector<std::string> vec);
u8 get_large_motor_speed(const std::array<VibrateMotor, 2>& motor_speed) const;
u8 get_small_motor_speed(const std::array<VibrateMotor, 2>& motor_speed) const;
u8 get_large_motor_speed(std::array<VibrateMotor, 2>& motors) const;
u8 get_small_motor_speed(std::array<VibrateMotor, 2>& motors) const;
cfg::string ls_left{ this, "Left Stick Left", "" };
cfg::string ls_down{ this, "Left Stick Down", "" };
@ -102,6 +102,7 @@ struct cfg_pad final : cfg::node
cfg::uint<0, 200> multiplier_vibration_motor_large{ this, "Large Vibration Motor Multiplier", 100 };
cfg::uint<0, 200> multiplier_vibration_motor_small{ this, "Small Vibration Motor Multiplier", 100 };
cfg::_bool switch_vibration_motors{ this, "Switch Vibration Motors", false };
cfg::uint<0, 255> vibration_threshold{ this, "Vibration Threshold", MOTOR_THRESHOLD };
cfg::_enum<mouse_movement_mode> mouse_move_mode{ this, "Mouse Movement Mode", mouse_movement_mode::relative };
cfg::uint<0, 255> mouse_deadzone_x{ this, "Mouse Deadzone X Axis", 60 };

View file

@ -344,6 +344,8 @@ struct CellPadData
be_t<u16> button[CELL_PAD_MAX_CODES];
};
static constexpr u8 MOTOR_THRESHOLD = 63; // The DS3 does not seem to respond to values <= 63. So we should ignore those in other handlers as well.
static constexpr u16 MOTION_ONE_G = 113;
static constexpr u16 DEFAULT_MOTION_X = 512;
static constexpr u16 DEFAULT_MOTION_Y = 399; // 512 - 113 (113 is 1G gravity)
@ -459,6 +461,7 @@ struct VibrateMotor
{
bool m_is_large_motor = false;
u8 m_value = 0;
u8 m_adjusted_value = 0;
VibrateMotor() {}
VibrateMotor(bool is_large_motor, u8 value)

View file

@ -209,6 +209,7 @@ void ds3_pad_handler::init_config(cfg_pad* cfg)
cfg->rtriggerthreshold.def = 0; // between 0 and 255
cfg->lpadsquircling.def = 0;
cfg->rpadsquircling.def = 0;
cfg->vibration_threshold.def = 0;
// Set default LED options
cfg->led_battery_indicator.def = false;