emulated turntable: allow to map motion sensors

This commit is contained in:
Megamouse 2026-06-28 02:57:03 +02:00
parent a7fc31f321
commit 5c55819b57
6 changed files with 88 additions and 11 deletions

View File

@ -296,4 +296,27 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
break;
}
});
cfg->handle_motion_input(pad, [&buf](turntable_btn btn, pad_button /*pad_btn*/, u16 value, bool /*pressed*/, bool& /*abort*/)
{
switch (btn)
{
case turntable_btn::crossfader:
{
const u16 v = value & 0x03FF; // ensure 10-bit range
buf[21] = (v & 0xFF); // Crossfader, lower 8 bits
buf[22] = (v >> 8) & 0x03; // Crossfader, upper 2 bits
break;
}
case turntable_btn::effects_dial:
{
const u16 v = value & 0x03FF; // ensure 10-bit range
buf[19] = (v & 0xFF); // Effects Dial, lower 8 bits
buf[20] = (v >> 8) & 0x03; // Effects Dial, upper 2 bits
break;
}
default:
break;
}
});
}

View File

@ -90,14 +90,14 @@ public:
void handle_input(std::shared_ptr<Pad> pad, bool press_only, const std::function<void(T, pad_button, u16, bool, bool&)>& func) const
{
if (!pad || pad->is_copilot())
if (!func || !pad || pad->is_copilot())
return;
for (const ButtonExternal& button : pad->m_buttons_external)
{
if (button.m_pressed || !press_only)
{
if (handle_input(func, button.m_offset, button.m_outKeyCode, button.m_value, button.m_pressed, true))
if (handle_input_internal(func, button.m_offset, button.m_outKeyCode, button.m_value, button.m_pressed, true))
{
return;
}
@ -106,7 +106,21 @@ public:
for (const AnalogStickExternal& stick : pad->m_sticks_external)
{
if (handle_input(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true))
if (handle_input_internal(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true))
{
return;
}
}
}
void handle_motion_input(std::shared_ptr<Pad> pad, const std::function<void(T, pad_button, u16, bool, bool&)>& func) const
{
if (!func || !pad || pad->is_copilot())
return;
for (const AnalogSensor& sensor : pad->m_sensors)
{
if (handle_input_internal(func, sensor.m_offset, sensor.m_keyCode, sensor.m_value, true, false))
{
return;
}
@ -124,7 +138,7 @@ public:
const u32 offset = pad_button_offset(button);
const u32 keycode = pad_button_keycode(button);
if (handle_input(func, offset, keycode, 255, true, true))
if (handle_input_internal(func, offset, keycode, 255, true, true))
{
return;
}
@ -173,11 +187,11 @@ protected:
return empty_set;
}
bool handle_input(const std::function<void(T, pad_button, u16, bool, bool&)>& func, u32 offset, u32 keycode, u16 value, bool pressed, bool check_axis) const
bool handle_input_internal(const std::function<void(T, pad_button, u16, bool, bool&)>& func, u32 offset, u32 keycode, u16 value, bool pressed, bool check_axis) const
{
m_mutex.lock();
if (!func) return false;
bool abort = false;
m_mutex.lock();
const auto& btns = find_button(offset, keycode);
if (btns.empty())
@ -192,18 +206,19 @@ protected:
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
abort = handle_input(func, offset, static_cast<u32>(axis_direction::both), value, pressed, false);
break;
return handle_input_internal(func, offset, static_cast<u32>(axis_direction::both), value, pressed, false);
default:
break;
}
}
return abort;
return false;
}
bool abort = false;
for (const auto& btn : btns)
{
if (btn && func)
if (btn)
{
func(btn->btn_id(), btn->get(), value, pressed, abort);
if (abort) break;

View File

@ -40,6 +40,11 @@ void fmt_class_string<pad_button>::format(std::string& out, u64 arg)
case pad_button::rs_x: return "Right Stick X-Axis";
case pad_button::rs_y: return "Right Stick Y-Axis";
case pad_button::pad_button_max_enum: return "";
case pad_button::motion_x: return "Motion X";
case pad_button::motion_y: return "Motion Y";
case pad_button::motion_z: return "Motion Z";
case pad_button::motion_g: return "Motion G";
case pad_button::pad_motion_max_enum: return "";
case pad_button::mouse_button_1: return "Mouse Button 1";
case pad_button::mouse_button_2: return "Mouse Button 2";
case pad_button::mouse_button_3: return "Mouse Button 3";
@ -87,6 +92,11 @@ u32 pad_button_offset(pad_button button)
case pad_button::rs_right: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X;
case pad_button::rs_x: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X;
case pad_button::rs_y: return CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y;
case pad_button::motion_x: return CELL_PAD_BTN_OFFSET_SENSOR_X;
case pad_button::motion_y: return CELL_PAD_BTN_OFFSET_SENSOR_Y;
case pad_button::motion_z: return CELL_PAD_BTN_OFFSET_SENSOR_Z;
case pad_button::motion_g: return CELL_PAD_BTN_OFFSET_SENSOR_G;
case pad_button::pad_motion_max_enum:
case pad_button::pad_button_max_enum:
case pad_button::mouse_button_1:
case pad_button::mouse_button_2:
@ -135,6 +145,11 @@ u32 pad_button_keycode(pad_button button)
case pad_button::rs_x: return static_cast<u32>(axis_direction::both);
case pad_button::rs_y: return static_cast<u32>(axis_direction::both);
case pad_button::pad_button_max_enum: return 0;
case pad_button::motion_x: return 0;
case pad_button::motion_y: return 0;
case pad_button::motion_z: return 0;
case pad_button::motion_g: return 0;
case pad_button::pad_motion_max_enum: return 0;
case pad_button::mouse_button_1: return 1;
case pad_button::mouse_button_2: return 2;
case pad_button::mouse_button_3: return 3;

View File

@ -44,6 +44,13 @@ enum class pad_button : u8
pad_button_max_enum,
motion_x,
motion_y,
motion_z,
motion_g,
pad_motion_max_enum,
// Special buttons for mouse input
mouse_button_1,
mouse_button_2,

View File

@ -280,6 +280,18 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
}
}
if (std::is_same_v<T, turntable_btn> && (static_cast<turntable_btn>(i) == turntable_btn::crossfader || static_cast<turntable_btn>(i) == turntable_btn::effects_dial))
{
for (int p = static_cast<int>(pad_button::motion_x); p < static_cast<int>(pad_button::pad_motion_max_enum); p++)
{
const QString translated = localized_emu::translated_pad_button(static_cast<pad_button>(p));
combo->addItem(translated);
const int index = combo->findText(translated);
combo->setItemData(index, p, button_role::button);
combo->setItemData(index, i, button_role::emulated_button);
}
}
pad_button saved_btn_id = pad_button::pad_button_max_enum;
switch (m_type)
{

View File

@ -36,6 +36,11 @@ QString localized_emu::translated_pad_button(pad_button btn)
case pad_button::rs_x: return tr("Right Stick X-Axis");
case pad_button::rs_y: return tr("Right Stick Y-Axis");
case pad_button::pad_button_max_enum: return "";
case pad_button::motion_x: return tr("Motion X");
case pad_button::motion_y: return tr("Motion Y");
case pad_button::motion_z: return tr("Motion Z");
case pad_button::motion_g: return tr("Motion G");
case pad_button::pad_motion_max_enum: return "";
case pad_button::mouse_button_1: return tr("Mouse 1");
case pad_button::mouse_button_2: return tr("Mouse 2");
case pad_button::mouse_button_3: return tr("Mouse 3");