mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-03 21:41:26 +12:00
input: add support for multi-assignment in emulated pads
This commit is contained in:
parent
b82dd61a0c
commit
95060efb7d
6 changed files with 98 additions and 56 deletions
|
@ -678,13 +678,14 @@ static void ds3_input_to_pad(const u32 port_no, be_t<u16>& digital_buttons, be_t
|
||||||
for (const Button& button : pad->m_buttons)
|
for (const Button& button : pad->m_buttons)
|
||||||
{
|
{
|
||||||
if (!button.m_pressed)
|
if (!button.m_pressed)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value())
|
for (const auto& btn : cfg->find_button(button.m_offset, button.m_outKeyCode))
|
||||||
{
|
{
|
||||||
switch (btn.value()->btn_id())
|
if (!btn)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (btn->btn_id())
|
||||||
{
|
{
|
||||||
case gem_btn::start:
|
case gem_btn::start:
|
||||||
digital_buttons |= CELL_GEM_CTRL_START;
|
digital_buttons |= CELL_GEM_CTRL_START;
|
||||||
|
@ -733,9 +734,32 @@ static inline void ds3_get_stick_values(u32 port_no, const std::shared_ptr<Pad>&
|
||||||
std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
|
std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
|
||||||
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
|
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
|
||||||
{
|
{
|
||||||
if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value())
|
const auto& btns = cfg->find_button(offset, keycode);
|
||||||
|
if (btns.empty())
|
||||||
{
|
{
|
||||||
switch (btn.value()->btn_id())
|
if (check_axis)
|
||||||
|
{
|
||||||
|
switch (offset)
|
||||||
|
{
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
|
||||||
|
handle_input(offset, static_cast<u32>(axis_direction::both), value, false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& btn : btns)
|
||||||
|
{
|
||||||
|
if (!btn)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (btn->btn_id())
|
||||||
{
|
{
|
||||||
case gem_btn::x_axis:
|
case gem_btn::x_axis:
|
||||||
x_pos = value;
|
x_pos = value;
|
||||||
|
@ -747,17 +771,6 @@ static inline void ds3_get_stick_values(u32 port_no, const std::shared_ptr<Pad>&
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (check_axis)
|
|
||||||
{
|
|
||||||
switch (offset)
|
|
||||||
{
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const AnalogStick& stick : pad->m_sticks)
|
for (const AnalogStick& stick : pad->m_sticks)
|
||||||
|
|
|
@ -107,13 +107,14 @@ void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/
|
||||||
for (const Button& button : pad->m_buttons)
|
for (const Button& button : pad->m_buttons)
|
||||||
{
|
{
|
||||||
if (!button.m_pressed)
|
if (!button.m_pressed)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value())
|
for (const auto& btn : cfg->find_button(button.m_offset, button.m_outKeyCode))
|
||||||
{
|
{
|
||||||
switch (btn.value()->btn_id())
|
if (!btn)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (btn->btn_id())
|
||||||
{
|
{
|
||||||
case buzz_btn::red:
|
case buzz_btn::red:
|
||||||
buf[2 + (0 + 5 * index) / 8] |= 1 << ((0 + 5 * index) % 8); // Red
|
buf[2 + (0 + 5 * index) / 8] |= 1 << ((0 + 5 * index) % 8); // Red
|
||||||
|
|
|
@ -150,9 +150,32 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
|
||||||
std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
|
std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
|
||||||
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
|
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
|
||||||
{
|
{
|
||||||
if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value())
|
const auto& btns = cfg->find_button(offset, keycode);
|
||||||
|
if (btns.empty())
|
||||||
{
|
{
|
||||||
switch (btn.value()->btn_id())
|
if (check_axis)
|
||||||
|
{
|
||||||
|
switch (offset)
|
||||||
|
{
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
|
||||||
|
handle_input(offset, static_cast<u32>(axis_direction::both), value, false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& btn : btns)
|
||||||
|
{
|
||||||
|
if (!btn)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (btn->btn_id())
|
||||||
{
|
{
|
||||||
case ghltar_btn::w1:
|
case ghltar_btn::w1:
|
||||||
buf[0] += 0x01; // W1
|
buf[0] += 0x01; // W1
|
||||||
|
@ -207,17 +230,6 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (check_axis)
|
|
||||||
{
|
|
||||||
switch (offset)
|
|
||||||
{
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const Button& button : pad->m_buttons)
|
for (const Button& button : pad->m_buttons)
|
||||||
|
|
|
@ -162,9 +162,32 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
|
||||||
std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
|
std::function<void(u32 offset, u32 keycode, u16 value, bool check_axis)> handle_input;
|
||||||
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
|
handle_input = [&](u32 offset, u32 keycode, u16 value, bool check_axis)
|
||||||
{
|
{
|
||||||
if (const auto btn = cfg->find_button(offset, keycode); btn.has_value() && btn.value())
|
const auto& btns = cfg->find_button(offset, keycode);
|
||||||
|
if (btns.empty())
|
||||||
{
|
{
|
||||||
switch (btn.value()->btn_id())
|
if (check_axis)
|
||||||
|
{
|
||||||
|
switch (offset)
|
||||||
|
{
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
|
||||||
|
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
|
||||||
|
handle_input(offset, static_cast<u32>(axis_direction::both), value, false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& btn : btns)
|
||||||
|
{
|
||||||
|
if (!btn)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (btn->btn_id())
|
||||||
{
|
{
|
||||||
case turntable_btn::blue:
|
case turntable_btn::blue:
|
||||||
buf[0] |= 0x01; // Square Button
|
buf[0] |= 0x01; // Square Button
|
||||||
|
@ -284,17 +307,6 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (check_axis)
|
|
||||||
{
|
|
||||||
switch (offset)
|
|
||||||
{
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: handle_input(offset, static_cast<u32>(axis_direction::both), value, false); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const Button& button : pad->m_buttons)
|
for (const Button& button : pad->m_buttons)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
LOG_CHANNEL(cfg_log, "CFG");
|
LOG_CHANNEL(cfg_log, "CFG");
|
||||||
|
@ -34,19 +34,20 @@ struct emulated_pad_config : cfg::node
|
||||||
using cfg::node::node;
|
using cfg::node::node;
|
||||||
|
|
||||||
std::vector<cfg_pad_btn<T>*> buttons;
|
std::vector<cfg_pad_btn<T>*> buttons;
|
||||||
std::map<u32, std::map<u32, const cfg_pad_btn<T>*>> button_map;
|
std::map<u32, std::map<u32, std::set<const cfg_pad_btn<T>*>>> button_map;
|
||||||
|
|
||||||
std::optional<const cfg_pad_btn<T>*> find_button(u32 offset, u32 keycode) const
|
const std::set<const cfg_pad_btn<T>*>& find_button(u32 offset, u32 keycode) const
|
||||||
{
|
{
|
||||||
if (const auto it = button_map.find(offset); it != button_map.cend())
|
if (const auto it = button_map.find(offset); it != button_map.cend())
|
||||||
{
|
{
|
||||||
if (const auto it2 = it->second.find(keycode); it2 != it->second.cend() && it2->second)
|
if (const auto it2 = it->second.find(keycode); it2 != it->second.cend() && !it2->second.empty())
|
||||||
{
|
{
|
||||||
return it2->second;
|
return it2->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::nullopt;
|
static const std::set<const cfg_pad_btn<T>*> empty_set;
|
||||||
|
return empty_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg_pad_btn<T>* get_button(T id)
|
cfg_pad_btn<T>* get_button(T id)
|
||||||
|
@ -85,7 +86,7 @@ struct emulated_pad_config : cfg::node
|
||||||
if (!pbtn) return;
|
if (!pbtn) return;
|
||||||
const u32 offset = pad_button_offset(pbtn->get());
|
const u32 offset = pad_button_offset(pbtn->get());
|
||||||
const u32 keycode = pad_button_keycode(pbtn->get());
|
const u32 keycode = pad_button_keycode(pbtn->get());
|
||||||
button_map[(offset >> 8) & 0xFF][keycode & 0xFF] = std::as_const(pbtn);
|
button_map[(offset >> 8) & 0xFF][keycode & 0xFF].insert(std::as_const(pbtn));
|
||||||
buttons.push_back(pbtn);
|
buttons.push_back(pbtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -201,9 +201,12 @@ void usb_device_usio::translate_input()
|
||||||
|
|
||||||
for (const Button& button : pad->m_buttons)
|
for (const Button& button : pad->m_buttons)
|
||||||
{
|
{
|
||||||
if (const auto btn = cfg->find_button(button.m_offset, button.m_outKeyCode); btn.has_value() && btn.value())
|
for (const auto& btn : cfg->find_button(button.m_offset, button.m_outKeyCode))
|
||||||
{
|
{
|
||||||
switch (btn.value()->btn_id())
|
if (!btn)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch (btn->btn_id())
|
||||||
{
|
{
|
||||||
case usio_btn::test:
|
case usio_btn::test:
|
||||||
if (player != 0) break;
|
if (player != 0) break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue