mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-17 18:55:19 +01:00
mmjoy: deduplicate some code
This commit is contained in:
parent
22fe14d31d
commit
6e6dd603cb
|
|
@ -11,12 +11,11 @@ PadHandlerBase::PadHandlerBase(pad_handler type) : m_type(type)
|
|||
{
|
||||
}
|
||||
|
||||
std::vector<std::set<u32>> PadHandlerBase::find_key_combos(const std::unordered_map<u32, std::string>& map, const cfg::string& cfg_string, bool fallback)
|
||||
std::vector<std::set<u32>> PadHandlerBase::find_key_combos(const std::unordered_map<u32, std::string>& map, const std::string& cfg_string, const std::string& fallback)
|
||||
{
|
||||
std::vector<std::set<u32>> key_codes;
|
||||
|
||||
const std::string& def = cfg_string.def;
|
||||
const std::vector<std::vector<std::string>> combos = cfg_pad::get_buttons(cfg_string.to_string());
|
||||
const std::vector<std::vector<std::string>> combos = cfg_pad::get_buttons(cfg_string);
|
||||
u32 def_code = umax;
|
||||
|
||||
for (const std::vector<std::string>& names : combos)
|
||||
|
|
@ -32,7 +31,7 @@ std::vector<std::set<u32>> PadHandlerBase::find_key_combos(const std::unordered_
|
|||
keys.insert(code);
|
||||
}
|
||||
|
||||
if (fallback && name == def)
|
||||
if (!fallback.empty() && name == fallback)
|
||||
def_code = code;
|
||||
}
|
||||
}
|
||||
|
|
@ -48,10 +47,10 @@ std::vector<std::set<u32>> PadHandlerBase::find_key_combos(const std::unordered_
|
|||
return key_codes;
|
||||
}
|
||||
|
||||
if (fallback)
|
||||
if (!fallback.empty())
|
||||
{
|
||||
if (!combos.empty())
|
||||
input_log.error("FindKeyCode for [name = %s] returned with [def_code = %d] for [def = %s]", cfg_string.to_string(), def_code, def);
|
||||
input_log.error("FindKeyCode for [name = %s] returned with [def_code = %d] for [fallback = %s]", cfg_string, def_code, fallback);
|
||||
|
||||
if (def_code != umax)
|
||||
{
|
||||
|
|
@ -62,6 +61,11 @@ std::vector<std::set<u32>> PadHandlerBase::find_key_combos(const std::unordered_
|
|||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::set<u32>> PadHandlerBase::find_key_combos(const std::unordered_map<u32, std::string>& map, const cfg::string& cfg_string, bool fallback)
|
||||
{
|
||||
return find_key_combos(map, cfg_string.to_string(), fallback ? cfg_string.def : "");
|
||||
}
|
||||
|
||||
std::set<u32> PadHandlerBase::find_key_codes(const std::unordered_map<u32, std::string>& map, const std::vector<std::string>& names)
|
||||
{
|
||||
std::set<u32> key_codes;
|
||||
|
|
@ -289,7 +293,7 @@ cfg_pad* PadHandlerBase::get_config(const std::string& pad_id)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_callback& callback, const pad_fail_callback& fail_callback, gui_call_type call_type, const std::vector<std::string>& /*buttons*/)
|
||||
PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_callback& callback, const pad_fail_callback& fail_callback, gui_call_type call_type, const std::vector<std::string>& buttons)
|
||||
{
|
||||
if (call_type == gui_call_type::blacklist)
|
||||
blacklist.clear();
|
||||
|
|
@ -391,12 +395,12 @@ PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::stri
|
|||
|
||||
if (callback)
|
||||
{
|
||||
pad_preview_values preview_values = get_preview_values(data);
|
||||
pad_preview_values preview_values = get_preview_values(data, buttons);
|
||||
pad_capabilities capabilities = get_capabilities(pad_id);
|
||||
const u32 battery_level = get_battery_level(pad_id);
|
||||
|
||||
if (pressed_button.value > 0)
|
||||
callback(pressed_button.value, pressed_button.name, pad_id, battery_level, std::move(preview_values), std::move(capabilities));
|
||||
callback(pressed_button.value, std::move(pressed_button.name), pad_id, battery_level, std::move(preview_values), std::move(capabilities));
|
||||
else
|
||||
callback(0, "", pad_id, battery_level, std::move(preview_values), std::move(capabilities));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -192,6 +192,9 @@ protected:
|
|||
|
||||
std::shared_ptr<Pad> m_pad_for_pad_settings;
|
||||
|
||||
// Search an unordered map for a string value and return the found combo
|
||||
static std::vector<std::set<u32>> find_key_combos(const std::unordered_map<u32, std::string>& map, const std::string& cfg_string, const std::string& fallback);
|
||||
|
||||
// Search an unordered map for a string value and return the found combo
|
||||
static std::vector<std::set<u32>> find_key_combos(const std::unordered_map<u32, std::string>& map, const cfg::string& cfg_string, bool fallback = true);
|
||||
|
||||
|
|
@ -315,7 +318,7 @@ private:
|
|||
virtual void get_extended_info(const pad_ensemble& /*binding*/) {}
|
||||
virtual void apply_pad_data(const pad_ensemble& /*binding*/) {}
|
||||
virtual std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& /*device*/) { return {}; }
|
||||
virtual pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& /*data*/) { return {}; }
|
||||
virtual pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& /*data*/, const std::vector<std::string>& /*buttons*/){ return {}; }
|
||||
|
||||
void get_orientation(const pad_ensemble& binding) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ std::unordered_map<u32, u16> ds3_pad_handler::get_button_values(const std::share
|
|||
return key_buf;
|
||||
}
|
||||
|
||||
pad_preview_values ds3_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data)
|
||||
pad_preview_values ds3_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& /*buttons*/)
|
||||
{
|
||||
return {
|
||||
::at32(data, L2),
|
||||
|
|
|
|||
|
|
@ -155,5 +155,5 @@ private:
|
|||
void get_extended_info(const pad_ensemble& binding) override;
|
||||
void apply_pad_data(const pad_ensemble& binding) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -410,7 +410,7 @@ std::unordered_map<u32, u16> ds4_pad_handler::get_button_values(const std::share
|
|||
return keyBuffer;
|
||||
}
|
||||
|
||||
pad_preview_values ds4_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data)
|
||||
pad_preview_values ds4_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& /*buttons*/)
|
||||
{
|
||||
return {
|
||||
::at32(data, L2),
|
||||
|
|
|
|||
|
|
@ -195,5 +195,5 @@ private:
|
|||
void get_extended_info(const pad_ensemble& binding) override;
|
||||
void apply_pad_data(const pad_ensemble& binding) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@ std::unordered_map<u32, u16> dualsense_pad_handler::get_button_values(const std:
|
|||
return keyBuffer;
|
||||
}
|
||||
|
||||
pad_preview_values dualsense_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data)
|
||||
pad_preview_values dualsense_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& /*buttons*/)
|
||||
{
|
||||
return {
|
||||
::at32(data, L2),
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ private:
|
|||
bool get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& device, u32 keyCode) override;
|
||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
void get_extended_info(const pad_ensemble& binding) override;
|
||||
void apply_pad_data(const pad_ensemble& binding) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,59 @@
|
|||
|
||||
mm_joystick_handler::mm_joystick_handler() : PadHandlerBase(pad_handler::mm)
|
||||
{
|
||||
button_list =
|
||||
{
|
||||
{ NO_BUTTON , "" },
|
||||
{ JOY_BUTTON1 , "Button 1" },
|
||||
{ JOY_BUTTON2 , "Button 2" },
|
||||
{ JOY_BUTTON3 , "Button 3" },
|
||||
{ JOY_BUTTON4 , "Button 4" },
|
||||
{ JOY_BUTTON5 , "Button 5" },
|
||||
{ JOY_BUTTON6 , "Button 6" },
|
||||
{ JOY_BUTTON7 , "Button 7" },
|
||||
{ JOY_BUTTON8 , "Button 8" },
|
||||
{ JOY_BUTTON9 , "Button 9" },
|
||||
{ JOY_BUTTON10, "Button 10" },
|
||||
{ JOY_BUTTON11, "Button 11" },
|
||||
{ JOY_BUTTON12, "Button 12" },
|
||||
{ JOY_BUTTON13, "Button 13" },
|
||||
{ JOY_BUTTON14, "Button 14" },
|
||||
{ JOY_BUTTON15, "Button 15" },
|
||||
{ JOY_BUTTON16, "Button 16" },
|
||||
{ JOY_BUTTON17, "Button 17" },
|
||||
{ JOY_BUTTON18, "Button 18" },
|
||||
{ JOY_BUTTON19, "Button 19" },
|
||||
{ JOY_BUTTON20, "Button 20" },
|
||||
{ JOY_BUTTON21, "Button 21" },
|
||||
{ JOY_BUTTON22, "Button 22" },
|
||||
{ JOY_BUTTON23, "Button 23" },
|
||||
{ JOY_BUTTON24, "Button 24" },
|
||||
{ JOY_BUTTON25, "Button 25" },
|
||||
{ JOY_BUTTON26, "Button 26" },
|
||||
{ JOY_BUTTON27, "Button 27" },
|
||||
{ JOY_BUTTON28, "Button 28" },
|
||||
{ JOY_BUTTON29, "Button 29" },
|
||||
{ JOY_BUTTON30, "Button 30" },
|
||||
{ JOY_BUTTON31, "Button 31" },
|
||||
{ JOY_BUTTON32, "Button 32" },
|
||||
{ mmjoy_axis::joy_x_pos, "X+" },
|
||||
{ mmjoy_axis::joy_x_neg, "X-" },
|
||||
{ mmjoy_axis::joy_y_pos, "Y+" },
|
||||
{ mmjoy_axis::joy_y_neg, "Y-" },
|
||||
{ mmjoy_axis::joy_z_pos, "Z+" },
|
||||
{ mmjoy_axis::joy_z_neg, "Z-" },
|
||||
{ mmjoy_axis::joy_r_pos, "R+" },
|
||||
{ mmjoy_axis::joy_r_neg, "R-" },
|
||||
{ mmjoy_axis::joy_u_pos, "U+" },
|
||||
{ mmjoy_axis::joy_u_neg, "U-" },
|
||||
{ mmjoy_axis::joy_v_pos, "V+" },
|
||||
{ mmjoy_axis::joy_v_neg, "V-" },
|
||||
{ mmjoy_pov::joy_pov_up, "POV Up" },
|
||||
{ mmjoy_pov::joy_pov_right, "POV Right" },
|
||||
{ mmjoy_pov::joy_pov_down, "POV Down" },
|
||||
{ mmjoy_pov::joy_pov_left, "POV Left" }
|
||||
};
|
||||
|
||||
init_configs();
|
||||
|
||||
// Define border values
|
||||
|
|
@ -26,14 +79,14 @@ void mm_joystick_handler::init_config(cfg_pad* cfg)
|
|||
if (!cfg) return;
|
||||
|
||||
// Set default button mapping
|
||||
cfg->ls_left.def = ::at32(axis_list, mmjoy_axis::joy_x_neg);
|
||||
cfg->ls_down.def = ::at32(axis_list, mmjoy_axis::joy_y_neg);
|
||||
cfg->ls_right.def = ::at32(axis_list, mmjoy_axis::joy_x_pos);
|
||||
cfg->ls_up.def = ::at32(axis_list, mmjoy_axis::joy_y_pos);
|
||||
cfg->rs_left.def = ::at32(axis_list, mmjoy_axis::joy_z_neg);
|
||||
cfg->rs_down.def = ::at32(axis_list, mmjoy_axis::joy_r_neg);
|
||||
cfg->rs_right.def = ::at32(axis_list, mmjoy_axis::joy_z_pos);
|
||||
cfg->rs_up.def = ::at32(axis_list, mmjoy_axis::joy_r_pos);
|
||||
cfg->ls_left.def = ::at32(button_list, mmjoy_axis::joy_x_neg);
|
||||
cfg->ls_down.def = ::at32(button_list, mmjoy_axis::joy_y_neg);
|
||||
cfg->ls_right.def = ::at32(button_list, mmjoy_axis::joy_x_pos);
|
||||
cfg->ls_up.def = ::at32(button_list, mmjoy_axis::joy_y_pos);
|
||||
cfg->rs_left.def = ::at32(button_list, mmjoy_axis::joy_z_neg);
|
||||
cfg->rs_down.def = ::at32(button_list, mmjoy_axis::joy_r_neg);
|
||||
cfg->rs_right.def = ::at32(button_list, mmjoy_axis::joy_z_pos);
|
||||
cfg->rs_up.def = ::at32(button_list, mmjoy_axis::joy_r_pos);
|
||||
cfg->start.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON9));
|
||||
cfg->select.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON10));
|
||||
cfg->ps.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON17));
|
||||
|
|
@ -41,10 +94,10 @@ void mm_joystick_handler::init_config(cfg_pad* cfg)
|
|||
cfg->cross.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON3));
|
||||
cfg->circle.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON2));
|
||||
cfg->triangle.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON1));
|
||||
cfg->left.def = ::at32(pov_list, static_cast<u32>(JOY_POVLEFT));
|
||||
cfg->down.def = ::at32(pov_list, static_cast<u32>(JOY_POVBACKWARD));
|
||||
cfg->right.def = ::at32(pov_list, static_cast<u32>(JOY_POVRIGHT));
|
||||
cfg->up.def = ::at32(pov_list, static_cast<u32>(JOY_POVFORWARD));
|
||||
cfg->left.def = ::at32(button_list, mmjoy_pov::joy_pov_left);
|
||||
cfg->down.def = ::at32(button_list, mmjoy_pov::joy_pov_down);
|
||||
cfg->right.def = ::at32(button_list, mmjoy_pov::joy_pov_right);
|
||||
cfg->up.def = ::at32(button_list, mmjoy_pov::joy_pov_up);
|
||||
cfg->r1.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON8));
|
||||
cfg->r2.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON6));
|
||||
cfg->r3.def = ::at32(button_list, static_cast<u32>(JOY_BUTTON12));
|
||||
|
|
@ -102,7 +155,7 @@ void mm_joystick_handler::enumerate_devices()
|
|||
{
|
||||
MMJOYDevice dev;
|
||||
|
||||
if (get_device(i, &dev) == false)
|
||||
if (!get_device(i, &dev))
|
||||
continue;
|
||||
|
||||
auto it = m_devices.find(dev.device_name);
|
||||
|
|
@ -145,290 +198,78 @@ std::vector<pad_list_entry> mm_joystick_handler::list_devices()
|
|||
return devices;
|
||||
}
|
||||
|
||||
std::vector<std::set<u32>> mm_joystick_handler::find_combos(const cfg::string& cfg_string) const
|
||||
{
|
||||
return find_combos(cfg_pad::get_buttons(cfg_string.to_string()));
|
||||
}
|
||||
|
||||
std::vector<std::set<u32>> mm_joystick_handler::find_combos(const std::vector<std::vector<std::string>>& combos) const
|
||||
{
|
||||
std::vector<std::set<u32>> res;
|
||||
|
||||
for (const std::vector<std::string>& combo : combos)
|
||||
{
|
||||
std::set<u32> keys;
|
||||
|
||||
for (u32 k : find_key_codes(axis_list, combo)) keys.insert(k);
|
||||
for (u32 k : find_key_codes(pov_list, combo)) keys.insert(k);
|
||||
for (u32 k : find_key_codes(button_list, combo)) keys.insert(k);
|
||||
|
||||
if (!keys.empty())
|
||||
{
|
||||
res.push_back(std::move(keys));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::array<std::vector<std::set<u32>>, PadHandlerBase::button::button_count> mm_joystick_handler::get_mapped_key_codes(const std::shared_ptr<PadDevice>& device, const cfg_pad* cfg)
|
||||
{
|
||||
std::array<std::vector<std::set<u32>>, button::button_count> mapping{};
|
||||
const std::array<std::vector<std::set<u32>>, button::button_count> mapping = PadHandlerBase::get_mapped_key_codes(device, cfg);
|
||||
|
||||
MMJOYDevice* dev = static_cast<MMJOYDevice*>(device.get());
|
||||
if (!dev || !cfg)
|
||||
return mapping;
|
||||
|
||||
dev->trigger_code_left = find_combos(cfg->l2);
|
||||
dev->trigger_code_right = find_combos(cfg->r2);
|
||||
dev->axis_code_left[0] = find_combos(cfg->ls_left);
|
||||
dev->axis_code_left[1] = find_combos(cfg->ls_right);
|
||||
dev->axis_code_left[2] = find_combos(cfg->ls_down);
|
||||
dev->axis_code_left[3] = find_combos(cfg->ls_up);
|
||||
dev->axis_code_right[0] = find_combos(cfg->rs_left);
|
||||
dev->axis_code_right[1] = find_combos(cfg->rs_right);
|
||||
dev->axis_code_right[2] = find_combos(cfg->rs_down);
|
||||
dev->axis_code_right[3] = find_combos(cfg->rs_up);
|
||||
|
||||
mapping[button::up] = find_combos(cfg->up);
|
||||
mapping[button::down] = find_combos(cfg->down);
|
||||
mapping[button::left] = find_combos(cfg->left);
|
||||
mapping[button::right] = find_combos(cfg->right);
|
||||
mapping[button::cross] = find_combos(cfg->cross);
|
||||
mapping[button::square] = find_combos(cfg->square);
|
||||
mapping[button::circle] = find_combos(cfg->circle);
|
||||
mapping[button::triangle] = find_combos(cfg->triangle);
|
||||
mapping[button::l1] = find_combos(cfg->l1);
|
||||
mapping[button::l2] = dev->trigger_code_left;
|
||||
mapping[button::l3] = find_combos(cfg->l3);
|
||||
mapping[button::r1] = find_combos(cfg->r1);
|
||||
mapping[button::r2] = dev->trigger_code_right;
|
||||
mapping[button::r3] = find_combos(cfg->r3);
|
||||
mapping[button::start] = find_combos(cfg->start);
|
||||
mapping[button::select] = find_combos(cfg->select);
|
||||
mapping[button::ps] = find_combos(cfg->ps);
|
||||
mapping[button::ls_left] = dev->axis_code_left[0];
|
||||
mapping[button::ls_right] = dev->axis_code_left[1];
|
||||
mapping[button::ls_down] = dev->axis_code_left[2];
|
||||
mapping[button::ls_up] = dev->axis_code_left[3];
|
||||
mapping[button::rs_left] = dev->axis_code_right[0];
|
||||
mapping[button::rs_right] = dev->axis_code_right[1];
|
||||
mapping[button::rs_down] = dev->axis_code_right[2];
|
||||
mapping[button::rs_up] = dev->axis_code_right[3];
|
||||
|
||||
mapping[button::skateboard_ir_nose] = find_combos(cfg->ir_nose);
|
||||
mapping[button::skateboard_ir_tail] = find_combos(cfg->ir_tail);
|
||||
mapping[button::skateboard_ir_left] = find_combos(cfg->ir_left);
|
||||
mapping[button::skateboard_ir_right] = find_combos(cfg->ir_right);
|
||||
mapping[button::skateboard_tilt_left] = find_combos(cfg->tilt_left);
|
||||
mapping[button::skateboard_tilt_right] = find_combos(cfg->tilt_right);
|
||||
|
||||
if (b_has_pressure_intensity_button)
|
||||
if (MMJOYDevice* dev = static_cast<MMJOYDevice*>(device.get()))
|
||||
{
|
||||
mapping[button::pressure_intensity_button] = find_combos(cfg->pressure_intensity_button);
|
||||
}
|
||||
|
||||
if (b_has_analog_limiter_button)
|
||||
{
|
||||
mapping[button::analog_limiter_button] = find_combos(cfg->analog_limiter_button);
|
||||
dev->trigger_code_left = mapping[button::l2];
|
||||
dev->trigger_code_right = mapping[button::r2];
|
||||
dev->axis_code_left[0] = mapping[button::ls_left];
|
||||
dev->axis_code_left[1] = mapping[button::ls_right];
|
||||
dev->axis_code_left[2] = mapping[button::ls_down];
|
||||
dev->axis_code_left[3] = mapping[button::ls_up];
|
||||
dev->axis_code_right[0] = mapping[button::rs_left];
|
||||
dev->axis_code_right[1] = mapping[button::rs_right];
|
||||
dev->axis_code_right[2] = mapping[button::rs_down];
|
||||
dev->axis_code_right[3] = mapping[button::rs_up];
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
PadHandlerBase::connection mm_joystick_handler::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)
|
||||
pad_preview_values mm_joystick_handler::get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons)
|
||||
{
|
||||
if (call_type == gui_call_type::blacklist)
|
||||
m_blacklist.clear();
|
||||
pad_preview_values preview_values{};
|
||||
|
||||
if (call_type == gui_call_type::reset_input || call_type == gui_call_type::blacklist)
|
||||
m_min_button_values.clear();
|
||||
if (buttons.size() != 10)
|
||||
return preview_values;
|
||||
|
||||
if (!Init())
|
||||
const auto get_key_value = [this, &data](const std::string& str) -> u16
|
||||
{
|
||||
if (fail_callback)
|
||||
fail_callback(padId);
|
||||
return connection::disconnected;
|
||||
}
|
||||
bool pressed{};
|
||||
u16 value{};
|
||||
|
||||
static std::string cur_pad;
|
||||
static int id = -1;
|
||||
|
||||
if (cur_pad != padId)
|
||||
{
|
||||
cur_pad = padId;
|
||||
const auto dev = get_device_by_name(padId);
|
||||
id = dev ? static_cast<int>(dev->device_id) : -1;
|
||||
if (id < 0)
|
||||
// The DS3 Button is considered pressed if any configured button combination is pressed
|
||||
for (const std::set<u32>& codes : find_key_combos(button_list, str, std::string()))
|
||||
{
|
||||
input_log.error("MMJOY get_next_button_press for device [%s] failed with id = %d", padId, id);
|
||||
if (fail_callback)
|
||||
fail_callback(padId);
|
||||
return connection::disconnected;
|
||||
}
|
||||
}
|
||||
bool combo_pressed = !codes.empty();
|
||||
u16 combo_val = 0;
|
||||
|
||||
JOYINFOEX js_info{};
|
||||
JOYCAPS js_caps{};
|
||||
js_info.dwSize = sizeof(js_info);
|
||||
js_info.dwFlags = JOY_RETURNALL;
|
||||
MMRESULT status = joyGetDevCaps(id, &js_caps, sizeof(js_caps));
|
||||
|
||||
if (status == JOYERR_NOERROR)
|
||||
status = joyGetPosEx(id, &js_info);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case JOYERR_UNPLUGGED:
|
||||
{
|
||||
if (fail_callback)
|
||||
fail_callback(padId);
|
||||
return connection::disconnected;
|
||||
}
|
||||
case JOYERR_NOERROR:
|
||||
{
|
||||
if (call_type == gui_call_type::get_connection)
|
||||
{
|
||||
return connection::connected;
|
||||
}
|
||||
|
||||
auto data = GetButtonValues(js_info, js_caps);
|
||||
|
||||
// Check for each button in our list if its corresponding (maybe remapped) button or axis was pressed.
|
||||
// Return the new value if the button was pressed (aka. its value was bigger than 0 or the defined threshold)
|
||||
// Get all the legally pressed buttons and use the one with highest value (prioritize first)
|
||||
struct
|
||||
{
|
||||
u16 value = 0;
|
||||
std::string name;
|
||||
} pressed_button{};
|
||||
|
||||
const auto set_button_press = [&](u32 keycode, const std::string& name, std::string_view type, u16 threshold)
|
||||
{
|
||||
if (call_type != gui_call_type::blacklist && m_blacklist.contains(keycode))
|
||||
return;
|
||||
|
||||
const u16 value = data[keycode];
|
||||
u16& min_value = m_min_button_values[keycode];
|
||||
|
||||
if (call_type == gui_call_type::reset_input || value < min_value)
|
||||
// The button combination is only considered pressed if all the buttons are pressed
|
||||
for (u32 code : codes)
|
||||
{
|
||||
min_value = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value <= threshold)
|
||||
return;
|
||||
|
||||
if (call_type == gui_call_type::blacklist)
|
||||
{
|
||||
m_blacklist.insert(keycode);
|
||||
input_log.error("MMJOY Calibration: Added %s [ %d = %s ] to blacklist. Value = %d", type, keycode, name, value);
|
||||
return;
|
||||
}
|
||||
|
||||
const u16 diff = value > min_value ? value - min_value : 0;
|
||||
|
||||
if (diff > button_press_threshold && value > pressed_button.value)
|
||||
{
|
||||
pressed_button = { .value = value, .name = name };
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto& [keycode, name] : axis_list)
|
||||
{
|
||||
set_button_press(keycode, name, "axis"sv, m_thumb_threshold);
|
||||
}
|
||||
|
||||
for (const auto& [keycode, name] : pov_list)
|
||||
{
|
||||
set_button_press(keycode, name, "pov"sv, 0);
|
||||
}
|
||||
|
||||
for (const auto& [keycode, name] : button_list)
|
||||
{
|
||||
if (keycode == NO_BUTTON)
|
||||
continue;
|
||||
|
||||
set_button_press(keycode, name, "button"sv, 0);
|
||||
}
|
||||
|
||||
if (call_type == gui_call_type::reset_input)
|
||||
{
|
||||
return connection::no_data;
|
||||
}
|
||||
|
||||
if (call_type == gui_call_type::blacklist)
|
||||
{
|
||||
if (m_blacklist.empty())
|
||||
input_log.success("MMJOY Calibration: Blacklist is clear. No input spam detected");
|
||||
return connection::connected;
|
||||
}
|
||||
|
||||
if (callback)
|
||||
{
|
||||
pad_preview_values preview_values{};
|
||||
if (buttons.size() == 10)
|
||||
{
|
||||
const auto get_key_value = [this, &data](const std::string& str) -> u16
|
||||
if (const auto it = data.find(code); it != data.cend())
|
||||
{
|
||||
bool pressed{};
|
||||
u16 value{};
|
||||
|
||||
// The DS3 Button is considered pressed if any configured button combination is pressed
|
||||
for (const std::set<u32>& codes : find_combos(cfg_pad::get_buttons(str)))
|
||||
if (it->second == 0)
|
||||
{
|
||||
bool combo_pressed = !codes.empty();
|
||||
u16 combo_val = 0;
|
||||
|
||||
// The button combination is only considered pressed if all the buttons are pressed
|
||||
for (u32 code : codes)
|
||||
{
|
||||
if (const auto it = data.find(code); it != data.cend())
|
||||
{
|
||||
if (it->second == 0)
|
||||
{
|
||||
combo_pressed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Take minimum combo value. Otherwise we will always end up with the max value in case an actual button is part of the combo.
|
||||
combo_val = (combo_val == 0) ? it->second : std::min(combo_val, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
if (combo_pressed)
|
||||
{
|
||||
value = std::max(value, combo_val);
|
||||
pressed = value > 0;
|
||||
}
|
||||
combo_pressed = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
preview_values[0] = get_key_value(buttons[0]);
|
||||
preview_values[1] = get_key_value(buttons[1]);
|
||||
preview_values[2] = get_key_value(buttons[3]) - get_key_value(buttons[2]);
|
||||
preview_values[3] = get_key_value(buttons[5]) - get_key_value(buttons[4]);
|
||||
preview_values[4] = get_key_value(buttons[7]) - get_key_value(buttons[6]);
|
||||
preview_values[5] = get_key_value(buttons[9]) - get_key_value(buttons[8]);
|
||||
// Take minimum combo value. Otherwise we will always end up with the max value in case an actual button is part of the combo.
|
||||
combo_val = (combo_val == 0) ? it->second : std::min(combo_val, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
pad_capabilities capabilities = get_capabilities(padId);
|
||||
|
||||
if (pressed_button.value > 0)
|
||||
callback(pressed_button.value, pressed_button.name, padId, 0, std::move(preview_values), std::move(capabilities));
|
||||
else
|
||||
callback(0, "", padId, 0, std::move(preview_values), std::move(capabilities));
|
||||
if (combo_pressed)
|
||||
{
|
||||
value = std::max(value, combo_val);
|
||||
pressed = value > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return connection::connected;
|
||||
}
|
||||
default:
|
||||
return connection::disconnected;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
preview_values[0] = get_key_value(buttons[0]);
|
||||
preview_values[1] = get_key_value(buttons[1]);
|
||||
preview_values[2] = get_key_value(buttons[3]) - get_key_value(buttons[2]);
|
||||
preview_values[3] = get_key_value(buttons[5]) - get_key_value(buttons[4]);
|
||||
preview_values[4] = get_key_value(buttons[7]) - get_key_value(buttons[6]);
|
||||
preview_values[5] = get_key_value(buttons[9]) - get_key_value(buttons[8]);
|
||||
|
||||
return connection::no_data;
|
||||
return preview_values;
|
||||
}
|
||||
|
||||
std::unordered_map<u32, u16> mm_joystick_handler::GetButtonValues(const JOYINFOEX& js_info, const JOYCAPS& js_caps)
|
||||
|
|
@ -437,8 +278,29 @@ std::unordered_map<u32, u16> mm_joystick_handler::GetButtonValues(const JOYINFOE
|
|||
|
||||
for (const auto& entry : button_list)
|
||||
{
|
||||
if (entry.first == NO_BUTTON)
|
||||
switch (entry.first)
|
||||
{
|
||||
case NO_BUTTON:
|
||||
case mmjoy_axis::joy_x_pos:
|
||||
case mmjoy_axis::joy_x_neg:
|
||||
case mmjoy_axis::joy_y_pos:
|
||||
case mmjoy_axis::joy_y_neg:
|
||||
case mmjoy_axis::joy_z_pos:
|
||||
case mmjoy_axis::joy_z_neg:
|
||||
case mmjoy_axis::joy_r_pos:
|
||||
case mmjoy_axis::joy_r_neg:
|
||||
case mmjoy_axis::joy_u_pos:
|
||||
case mmjoy_axis::joy_u_neg:
|
||||
case mmjoy_axis::joy_v_pos:
|
||||
case mmjoy_axis::joy_v_neg:
|
||||
case mmjoy_pov::joy_pov_up:
|
||||
case mmjoy_pov::joy_pov_right:
|
||||
case mmjoy_pov::joy_pov_down:
|
||||
case mmjoy_pov::joy_pov_left:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
button_values.emplace(entry.first, (js_info.dwButtons & entry.first) ? 255 : 0);
|
||||
}
|
||||
|
|
@ -479,7 +341,7 @@ std::unordered_map<u32, u16> mm_joystick_handler::GetButtonValues(const JOYINFOE
|
|||
{
|
||||
const int val = static_cast<int>(js_info.dwPOV);
|
||||
|
||||
auto emplacePOV = [&button_values, &val](int pov)
|
||||
const auto emplacePOV = [&button_values, &val](int pov)
|
||||
{
|
||||
const int cw = pov + 4500, ccw = pov - 4500;
|
||||
const bool pressed = (val == pov) || (val == cw) || (ccw < 0 ? val == 36000 - std::abs(ccw) : val == ccw);
|
||||
|
|
@ -535,22 +397,6 @@ std::unordered_map<u32, u16> mm_joystick_handler::get_button_values(const std::s
|
|||
return GetButtonValues(dev->device_info, dev->device_caps);
|
||||
}
|
||||
|
||||
std::shared_ptr<mm_joystick_handler::MMJOYDevice> mm_joystick_handler::get_device_by_name(const std::string& name)
|
||||
{
|
||||
// Try to find a device with valid name and index
|
||||
if (auto it = m_devices.find(name); it != m_devices.end())
|
||||
{
|
||||
if (it->second && it->second->device_id != umax)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Make sure we have a device pointer (marked as invalid and unplugged)
|
||||
std::shared_ptr<MMJOYDevice> dev = create_device_by_name(name);
|
||||
m_devices.emplace(name, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
std::shared_ptr<mm_joystick_handler::MMJOYDevice> mm_joystick_handler::create_device_by_name(const std::string& name)
|
||||
{
|
||||
std::shared_ptr<MMJOYDevice> dev = std::make_shared<MMJOYDevice>();
|
||||
|
|
@ -607,7 +453,18 @@ std::shared_ptr<PadDevice> mm_joystick_handler::get_device(const std::string& de
|
|||
if (!Init())
|
||||
return nullptr;
|
||||
|
||||
return get_device_by_name(device);
|
||||
// Try to find a device with valid name and index
|
||||
if (auto it = m_devices.find(device); it != m_devices.end())
|
||||
{
|
||||
if (it->second && it->second->device_id != umax)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
// Make sure we have a device pointer (marked as invalid and unplugged)
|
||||
std::shared_ptr<MMJOYDevice> dev = create_device_by_name(device);
|
||||
m_devices.emplace(device, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
bool mm_joystick_handler::get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u32 keyCode)
|
||||
|
|
|
|||
|
|
@ -19,53 +19,6 @@ class mm_joystick_handler final : public PadHandlerBase
|
|||
{
|
||||
static constexpr u32 NO_BUTTON = u32{umax};
|
||||
|
||||
// Unique names for the config files and our pad settings dialog
|
||||
const std::unordered_map<u32, std::string> button_list =
|
||||
{
|
||||
{ NO_BUTTON , "" },
|
||||
{ JOY_BUTTON1 , "Button 1" },
|
||||
{ JOY_BUTTON2 , "Button 2" },
|
||||
{ JOY_BUTTON3 , "Button 3" },
|
||||
{ JOY_BUTTON4 , "Button 4" },
|
||||
{ JOY_BUTTON5 , "Button 5" },
|
||||
{ JOY_BUTTON6 , "Button 6" },
|
||||
{ JOY_BUTTON7 , "Button 7" },
|
||||
{ JOY_BUTTON8 , "Button 8" },
|
||||
{ JOY_BUTTON9 , "Button 9" },
|
||||
{ JOY_BUTTON10, "Button 10" },
|
||||
{ JOY_BUTTON11, "Button 11" },
|
||||
{ JOY_BUTTON12, "Button 12" },
|
||||
{ JOY_BUTTON13, "Button 13" },
|
||||
{ JOY_BUTTON14, "Button 14" },
|
||||
{ JOY_BUTTON15, "Button 15" },
|
||||
{ JOY_BUTTON16, "Button 16" },
|
||||
{ JOY_BUTTON17, "Button 17" },
|
||||
{ JOY_BUTTON18, "Button 18" },
|
||||
{ JOY_BUTTON19, "Button 19" },
|
||||
{ JOY_BUTTON20, "Button 20" },
|
||||
{ JOY_BUTTON21, "Button 21" },
|
||||
{ JOY_BUTTON22, "Button 22" },
|
||||
{ JOY_BUTTON23, "Button 23" },
|
||||
{ JOY_BUTTON24, "Button 24" },
|
||||
{ JOY_BUTTON25, "Button 25" },
|
||||
{ JOY_BUTTON26, "Button 26" },
|
||||
{ JOY_BUTTON27, "Button 27" },
|
||||
{ JOY_BUTTON28, "Button 28" },
|
||||
{ JOY_BUTTON29, "Button 29" },
|
||||
{ JOY_BUTTON30, "Button 30" },
|
||||
{ JOY_BUTTON31, "Button 31" },
|
||||
{ JOY_BUTTON32, "Button 32" },
|
||||
};
|
||||
|
||||
// Unique names for the config files and our pad settings dialog
|
||||
const std::unordered_map<u32, std::string> pov_list =
|
||||
{
|
||||
{ JOY_POVFORWARD, "POV Up" },
|
||||
{ JOY_POVRIGHT, "POV Right" },
|
||||
{ JOY_POVBACKWARD, "POV Down" },
|
||||
{ JOY_POVLEFT, "POV Left" }
|
||||
};
|
||||
|
||||
enum mmjoy_axis : u32
|
||||
{
|
||||
joy_x_pos = 9700,
|
||||
|
|
@ -82,21 +35,12 @@ class mm_joystick_handler final : public PadHandlerBase
|
|||
joy_v_neg,
|
||||
};
|
||||
|
||||
// Unique names for the config files and our pad settings dialog
|
||||
const std::unordered_map<u32, std::string> axis_list =
|
||||
enum mmjoy_pov : u32
|
||||
{
|
||||
{ joy_x_pos, "X+" },
|
||||
{ joy_x_neg, "X-" },
|
||||
{ joy_y_pos, "Y+" },
|
||||
{ joy_y_neg, "Y-" },
|
||||
{ joy_z_pos, "Z+" },
|
||||
{ joy_z_neg, "Z-" },
|
||||
{ joy_r_pos, "R+" },
|
||||
{ joy_r_neg, "R-" },
|
||||
{ joy_u_pos, "U+" },
|
||||
{ joy_u_neg, "U-" },
|
||||
{ joy_v_pos, "V+" },
|
||||
{ joy_v_neg, "V-" },
|
||||
joy_pov_up = JOY_POVFORWARD,
|
||||
joy_pov_right = JOY_POVRIGHT,
|
||||
joy_pov_down = JOY_POVBACKWARD,
|
||||
joy_pov_left = JOY_POVLEFT,
|
||||
};
|
||||
|
||||
struct MMJOYDevice : public PadDevice
|
||||
|
|
@ -119,25 +63,18 @@ public:
|
|||
bool Init() override;
|
||||
|
||||
std::vector<pad_list_entry> list_devices() 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;
|
||||
void init_config(cfg_pad* cfg) override;
|
||||
|
||||
private:
|
||||
std::unordered_map<u32, u16> GetButtonValues(const JOYINFOEX& js_info, const JOYCAPS& js_caps);
|
||||
std::shared_ptr<MMJOYDevice> get_device_by_name(const std::string& name);
|
||||
std::shared_ptr<MMJOYDevice> create_device_by_name(const std::string& name);
|
||||
bool get_device(int index, MMJOYDevice* dev) const;
|
||||
void enumerate_devices();
|
||||
|
||||
bool m_is_init = false;
|
||||
|
||||
std::set<u32> m_blacklist;
|
||||
std::unordered_map<u32, u16> m_min_button_values;
|
||||
std::map<std::string, std::shared_ptr<MMJOYDevice>> m_devices;
|
||||
|
||||
std::vector<std::set<u32>> find_combos(const std::vector<std::vector<std::string>>& combos) const;
|
||||
std::vector<std::set<u32>> find_combos(const cfg::string& cfg_string) const;
|
||||
|
||||
std::array<std::vector<std::set<u32>>, PadHandlerBase::button::button_count> get_mapped_key_codes(const std::shared_ptr<PadDevice>& device, const cfg_pad* cfg) override;
|
||||
std::shared_ptr<PadDevice> get_device(const std::string& device) override;
|
||||
bool get_is_left_trigger(const std::shared_ptr<PadDevice>& device, u32 keyCode) override;
|
||||
|
|
@ -146,5 +83,6 @@ private:
|
|||
bool get_is_right_stick(const std::shared_ptr<PadDevice>& device, u32 keyCode) override;
|
||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -760,7 +760,7 @@ void ps_move_handler::get_extended_info(const pad_ensemble& binding)
|
|||
handle_external_device(binding);
|
||||
}
|
||||
|
||||
pad_preview_values ps_move_handler::get_preview_values(const std::unordered_map<u32, u16>& data)
|
||||
pad_preview_values ps_move_handler::get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& /*buttons*/)
|
||||
{
|
||||
return {
|
||||
std::max(::at32(data, ps_move_key_codes::L2), ::at32(data, ps_move_key_codes::t)),
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ private:
|
|||
bool get_is_right_trigger(const std::shared_ptr<PadDevice>& device, u32 keyCode) override;
|
||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
void get_extended_info(const pad_ensemble& binding) override;
|
||||
void apply_pad_data(const pad_ensemble& binding) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -1086,7 +1086,7 @@ std::unordered_map<u32, u16> sdl_pad_handler::get_button_values(const std::share
|
|||
return values;
|
||||
}
|
||||
|
||||
pad_preview_values sdl_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data)
|
||||
pad_preview_values sdl_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& /*buttons*/)
|
||||
{
|
||||
return {
|
||||
::at32(data, LT),
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ private:
|
|||
bool get_is_right_stick(const std::shared_ptr<PadDevice>& device, u32 keyCode) override;
|
||||
bool get_is_touch_pad_motion(const std::shared_ptr<PadDevice>& device, u32 keyCode) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
|
||||
u32 get_battery_color(int power_level, u32 brightness) const;
|
||||
void set_rumble(SDLDevice* dev, u8 speed_large, u8 speed_small);
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ void skateboard_pad_handler::get_extended_info(const pad_ensemble& binding)
|
|||
set_raw_orientation(*pad);
|
||||
}
|
||||
|
||||
pad_preview_values skateboard_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& /*data*/)
|
||||
pad_preview_values skateboard_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& /*data*/, const std::vector<std::string>& /*buttons*/)
|
||||
{
|
||||
// There is no proper user interface for skateboard values yet
|
||||
return {};
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ private:
|
|||
|
||||
PadHandlerBase::connection update_connection(const std::shared_ptr<PadDevice>& device) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
void get_extended_info(const pad_ensemble& binding) override;
|
||||
void apply_pad_data(const pad_ensemble& binding) override;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@ std::unordered_map<u32, u16> xinput_pad_handler::get_button_values_scp(const SCP
|
|||
return values;
|
||||
}
|
||||
|
||||
pad_preview_values xinput_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data)
|
||||
pad_preview_values xinput_pad_handler::get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& /*buttons*/)
|
||||
{
|
||||
return {
|
||||
::at32(data, LT),
|
||||
|
|
|
|||
|
|
@ -140,5 +140,5 @@ private:
|
|||
void get_extended_info(const pad_ensemble& binding) override;
|
||||
void apply_pad_data(const pad_ensemble& binding) override;
|
||||
std::unordered_map<u32, u16> get_button_values(const std::shared_ptr<PadDevice>& device) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data) override;
|
||||
pad_preview_values get_preview_values(const std::unordered_map<u32, u16>& data, const std::vector<std::string>& buttons) override;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue