Qt/Input: Adjust pad settings dialog based on pad capabilities

This commit is contained in:
Megamouse 2025-09-30 20:10:55 +02:00
parent 43c4947cb9
commit 25fbdfb43a
9 changed files with 98 additions and 28 deletions

View file

@ -270,7 +270,11 @@ error_code sys_ss_appliance_info_manager(u32 code, vm::ptr<u8> buffer)
// qa values (dex only) ?? // qa values (dex only) ??
[[fallthrough]]; [[fallthrough]];
} }
default: sys_ss.todo("sys_ss_appliance_info_manager(code=0x%x, buffer=*0x%x)", code, buffer); default:
{
sys_ss.todo("sys_ss_appliance_info_manager(code=0x%x, buffer=*0x%x)", code, buffer);
break;
}
} }
return CELL_OK; return CELL_OK;

View file

@ -208,6 +208,21 @@ void PadHandlerBase::init_configs()
} }
} }
pad_capabilities PadHandlerBase::get_capabilities(const std::string& /*pad_id*/)
{
return pad_capabilities
{
.has_led = b_has_rgb,
.has_mono_led = b_has_led,
.has_player_led = b_has_player_led,
.has_battery_led = b_has_battery_led,
.has_rumble = b_has_rumble,
.has_accel = b_has_motion,
.has_gyro = b_has_motion,
.has_pressure_sensitivity = b_has_pressure_intensity_button
};
}
cfg_pad* PadHandlerBase::get_config(const std::string& pad_id) cfg_pad* PadHandlerBase::get_config(const std::string& pad_id)
{ {
int index = 0; int index = 0;
@ -331,12 +346,13 @@ PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::stri
if (callback) if (callback)
{ {
pad_preview_values preview_values = get_preview_values(data); pad_preview_values preview_values = get_preview_values(data);
pad_capabilities capabilities = get_capabilities(pad_id);
const u32 battery_level = get_battery_level(pad_id); const u32 battery_level = get_battery_level(pad_id);
if (pressed_button.value > 0) if (pressed_button.value > 0)
callback(pressed_button.value, pressed_button.name, pad_id, battery_level, std::move(preview_values)); callback(pressed_button.value, pressed_button.name, pad_id, battery_level, std::move(preview_values), std::move(capabilities));
else else
callback(0, "", pad_id, battery_level, std::move(preview_values)); callback(0, "", pad_id, battery_level, std::move(preview_values), std::move(capabilities));
} }
return status; return status;

View file

@ -81,8 +81,20 @@ struct pad_list_entry
{} {}
}; };
struct pad_capabilities
{
bool has_led = false;
bool has_mono_led = false;
bool has_player_led = false;
bool has_battery_led = false;
bool has_rumble = false;
bool has_accel = false;
bool has_gyro = false;
bool has_pressure_sensitivity = false;
};
using pad_preview_values = std::array<int, 6>; using pad_preview_values = std::array<int, 6>;
using pad_callback = std::function<void(u16 /*button_value*/, std::string /*button_name*/, std::string /*pad_name*/, u32 /*battery_level*/, pad_preview_values /*preview_values*/)>; using pad_callback = std::function<void(u16 /*button_value*/, std::string /*button_name*/, std::string /*pad_name*/, u32 /*battery_level*/, pad_preview_values, pad_capabilities)>;
using pad_fail_callback = std::function<void(std::string /*pad_name*/)>; using pad_fail_callback = std::function<void(std::string /*pad_name*/)>;
using motion_preview_values = std::array<u16, 4>; using motion_preview_values = std::array<u16, 4>;
@ -326,6 +338,8 @@ public:
bool has_analog_limiter_button() const { return b_has_analog_limiter_button; } bool has_analog_limiter_button() const { return b_has_analog_limiter_button; }
bool has_orientation() const { return b_has_orientation; } bool has_orientation() const { return b_has_orientation; }
virtual pad_capabilities get_capabilities(const std::string& /*pad_id*/);
u16 NormalizeStickInput(u16 raw_value, s32 threshold, s32 multiplier, bool ignore_threshold = false) const; u16 NormalizeStickInput(u16 raw_value, s32 threshold, s32 multiplier, bool ignore_threshold = false) const;
void convert_stick_values(u16& x_out, u16& y_out, s32 x_in, s32 y_in, u32 deadzone, u32 anti_deadzone, u32 padsquircling) const; void convert_stick_values(u16& x_out, u16& y_out, s32 x_in, s32 y_in, u32 deadzone, u32 anti_deadzone, u32 padsquircling) const;
void set_trigger_recognition_mode(trigger_recognition_mode mode) { m_trigger_recognition_mode = mode; } void set_trigger_recognition_mode(trigger_recognition_mode mode) { m_trigger_recognition_mode = mode; }

View file

@ -421,7 +421,7 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
if (call_type != gui_call_type::blacklist && call_type != gui_call_type::reset_input && !has_new_event) if (call_type != gui_call_type::blacklist && call_type != gui_call_type::reset_input && !has_new_event)
{ {
if (callback) if (callback)
callback(0, "", padId, 0, preview_values); callback(0, "", padId, 0, preview_values, get_capabilities(padId));
return connection::no_data; return connection::no_data;
} }
@ -543,10 +543,12 @@ PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const s
if (callback) if (callback)
{ {
pad_capabilities capabilities = get_capabilities(padId);
if (pressed_button.value > 0) if (pressed_button.value > 0)
callback(pressed_button.value, pressed_button.name, padId, 0, std::move(preview_values)); callback(pressed_button.value, pressed_button.name, padId, 0, std::move(preview_values), std::move(capabilities));
else else
callback(0, "", padId, 0, std::move(preview_values)); callback(0, "", padId, 0, std::move(preview_values), std::move(capabilities));
} }
return connection::connected; return connection::connected;

View file

@ -384,10 +384,12 @@ PadHandlerBase::connection mm_joystick_handler::get_next_button_press(const std:
preview_values[5] = get_key_value(buttons[9]) - get_key_value(buttons[8]); preview_values[5] = get_key_value(buttons[9]) - get_key_value(buttons[8]);
} }
pad_capabilities capabilities = get_capabilities(padId);
if (pressed_button.value > 0) if (pressed_button.value > 0)
callback(pressed_button.value, pressed_button.name, padId, 0, std::move(preview_values)); callback(pressed_button.value, pressed_button.name, padId, 0, std::move(preview_values), std::move(capabilities));
else else
callback(0, "", padId, 0, std::move(preview_values)); callback(0, "", padId, 0, std::move(preview_values), std::move(capabilities));
} }
return connection::connected; return connection::connected;

View file

@ -722,6 +722,29 @@ PadHandlerBase::connection sdl_pad_handler::get_next_button_press(const std::str
return PadHandlerBase::get_next_button_press(padId, callback, fail_callback, call_type, buttons); return PadHandlerBase::get_next_button_press(padId, callback, fail_callback, call_type, buttons);
} }
pad_capabilities sdl_pad_handler::get_capabilities(const std::string& pad_id)
{
pad_capabilities capabilities = PadHandlerBase::get_capabilities(pad_id);
std::shared_ptr<PadDevice> device = get_device(pad_id);
SDLDevice* dev = static_cast<SDLDevice*>(device.get());
if (!dev || dev->sdl.is_virtual_device)
{
return capabilities;
}
capabilities.has_led &= dev->sdl.has_led;
capabilities.has_mono_led &= dev->sdl.has_mono_led;
capabilities.has_player_led &= dev->sdl.has_player_led;
capabilities.has_battery_led &= (dev->sdl.has_led || dev->sdl.has_mono_led);
capabilities.has_rumble &= dev->sdl.has_rumble;
capabilities.has_accel &= dev->sdl.has_accel;
capabilities.has_gyro &= dev->sdl.has_gyro;
capabilities.has_pressure_sensitivity &= dev->sdl.is_ds3_with_pressure_buttons;
return capabilities;
}
void sdl_pad_handler::apply_pad_data(const pad_ensemble& binding) void sdl_pad_handler::apply_pad_data(const pad_ensemble& binding)
{ {
const auto& pad = binding.pad; const auto& pad = binding.pad;

View file

@ -158,6 +158,7 @@ public:
u32 get_battery_level(const std::string& padId) override; u32 get_battery_level(const std::string& padId) override;
void get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override; void get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array<AnalogSensor, 4>& sensors) override;
connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, gui_call_type call_type, const std::vector<std::string>& buttons) override; connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, gui_call_type call_type, const std::vector<std::string>& buttons) override;
pad_capabilities get_capabilities(const std::string& pad_id) override;
private: private:
// pseudo 'controller id' to keep track of unique controllers // pseudo 'controller id' to keep track of unique controllers

View file

@ -463,12 +463,28 @@ void pad_settings_dialog::InitButtons()
return; return;
} }
const auto update_preview = [this](const std::string& pad_name, bool is_connected, int battery_level, int trigger_left, int trigger_right, int lx, int ly, int rx, int ry) const auto update_preview = [this](const std::string& pad_name, bool is_connected, int battery_level, int trigger_left, int trigger_right, int lx, int ly, int rx, int ry, const pad_capabilities& capabilities)
{ {
SwitchPadInfo(pad_name, is_connected); SwitchPadInfo(pad_name, is_connected);
if (is_connected != m_enable_buttons && (!is_connected || !m_remap_timer.isActive())) if ((!is_connected || !m_remap_timer.isActive()) && (
is_connected != m_enable_buttons ||
(is_connected && (
!capabilities.has_pressure_sensitivity != m_enable_pressure_intensity_button ||
capabilities.has_rumble != m_enable_rumble ||
capabilities.has_battery_led != m_enable_battery_led ||
(capabilities.has_led || capabilities.has_mono_led) != m_enable_led ||
(capabilities.has_accel || capabilities.has_gyro) != m_enable_motion))))
{ {
if (is_connected)
{
m_enable_pressure_intensity_button = !capabilities.has_pressure_sensitivity;
m_enable_rumble = capabilities.has_rumble;
m_enable_battery_led = capabilities.has_battery_led;
m_enable_led = capabilities.has_led || capabilities.has_mono_led;
m_enable_motion = capabilities.has_accel || capabilities.has_gyro;
}
SwitchButtons(is_connected); SwitchButtons(is_connected);
} }
@ -497,12 +513,12 @@ void pad_settings_dialog::InitButtons()
if (data.status == PadHandlerBase::connection::disconnected) if (data.status == PadHandlerBase::connection::disconnected)
{ {
// Disable Button Remapping // Disable Button Remapping
update_preview(data.pad_name, false, 0, 0, 0, 0, 0, 0, 0); update_preview(data.pad_name, false, 0, 0, 0, 0, 0, 0, 0, data.capabilities);
return; return;
} }
// Enable Button Remapping // Enable Button Remapping
update_preview(data.pad_name, true, data.battery_level, data.preview_values[0], data.preview_values[1], data.preview_values[2], data.preview_values[3], data.preview_values[4], data.preview_values[5]); update_preview(data.pad_name, true, data.battery_level, data.preview_values[0], data.preview_values[1], data.preview_values[2], data.preview_values[3], data.preview_values[4], data.preview_values[5], data.capabilities);
// Handle Button Presses // Handle Button Presses
for (const input_callback_data::input_values& values : data.values) for (const input_callback_data::input_values& values : data.values)
@ -566,7 +582,7 @@ void pad_settings_dialog::InitButtons()
const PadHandlerBase::gui_call_type call_type = first_call ? PadHandlerBase::gui_call_type::reset_input : PadHandlerBase::gui_call_type::normal; const PadHandlerBase::gui_call_type call_type = first_call ? PadHandlerBase::gui_call_type::reset_input : PadHandlerBase::gui_call_type::normal;
const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name, const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name,
[this, button_id](u16 val, std::string button_name, std::string pad_name, u32 battery_level, pad_preview_values preview_values) [this, button_id](u16 val, std::string button_name, std::string pad_name, u32 battery_level, pad_preview_values preview_values, pad_capabilities capabilities)
{ {
std::lock_guard lock(m_input_mutex); std::lock_guard lock(m_input_mutex);
if (m_input_callback_data.pad_name != pad_name) if (m_input_callback_data.pad_name != pad_name)
@ -576,6 +592,7 @@ void pad_settings_dialog::InitButtons()
} }
m_input_callback_data.battery_level = battery_level; m_input_callback_data.battery_level = battery_level;
m_input_callback_data.preview_values = std::move(preview_values); m_input_callback_data.preview_values = std::move(preview_values);
m_input_callback_data.capabilities = std::move(capabilities);
m_input_callback_data.has_new_data = true; m_input_callback_data.has_new_data = true;
m_input_callback_data.status = PadHandlerBase::connection::connected; m_input_callback_data.status = PadHandlerBase::connection::connected;
if (val > 0) if (val > 0)
@ -1235,12 +1252,9 @@ void pad_settings_dialog::UpdateLabels(bool is_reset)
ui->pressure_intensity_deadzone->setValue(cfg.pressure_intensity_deadzone.get()); ui->pressure_intensity_deadzone->setValue(cfg.pressure_intensity_deadzone.get());
// Apply stored/default LED settings to the device // Apply stored/default LED settings to the device
m_enable_led = m_handler->has_led();
m_enable_battery_led = m_handler->has_battery_led();
SetPadData(0, 0); SetPadData(0, 0);
// Enable battery and LED group box // Enable battery and LED group box
m_enable_battery = m_handler->has_battery();
ui->gb_battery->setVisible(m_enable_battery || m_enable_led); ui->gb_battery->setVisible(m_enable_battery || m_enable_led);
} }
@ -1472,22 +1486,15 @@ void pad_settings_dialog::ChangeHandler()
m_rx = 0; m_rx = 0;
m_ry = 0; m_ry = 0;
// Enable Vibration Checkboxes // Enable Capabilities
m_enable_led = m_handler->has_led();
m_enable_battery_led = m_handler->has_battery_led();
m_enable_battery = m_handler->has_battery();
m_enable_rumble = m_handler->has_rumble(); m_enable_rumble = m_handler->has_rumble();
// Enable Motion Settings
m_enable_motion = m_handler->has_motion(); m_enable_motion = m_handler->has_motion();
// Enable Deadzone Settings
m_enable_deadzones = m_handler->has_deadzones(); m_enable_deadzones = m_handler->has_deadzones();
// Enable Pressure Sensitivity Settings
m_enable_pressure_intensity_button = m_handler->has_pressure_intensity_button(); m_enable_pressure_intensity_button = m_handler->has_pressure_intensity_button();
// Enable Analog Limiter Settings
m_enable_analog_limiter_button = m_handler->has_analog_limiter_button(); m_enable_analog_limiter_button = m_handler->has_analog_limiter_button();
// Enable Orientation Reset Settings
m_enable_orientation_reset_button = m_handler->has_orientation(); m_enable_orientation_reset_button = m_handler->has_orientation();
// Change our contextual widgets // Change our contextual widgets

View file

@ -173,6 +173,7 @@ private:
std::string pad_name; std::string pad_name;
u32 battery_level = 0; u32 battery_level = 0;
std::array<int, 6> preview_values{}; std::array<int, 6> preview_values{};
pad_capabilities capabilities{};
struct input_values struct input_values
{ {