Merge branch 'master' into rsx-volatile

This commit is contained in:
kd-11 2025-01-10 03:17:49 +03:00 committed by GitHub
commit 76d67498ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
25 changed files with 419 additions and 96 deletions

View file

@ -40,9 +40,18 @@ void fmt_class_string<gem_btn>::format(std::string& out, u64 arg)
case gem_btn::square: return "Square"; case gem_btn::square: return "Square";
case gem_btn::move: return "Move"; case gem_btn::move: return "Move";
case gem_btn::t: return "T"; case gem_btn::t: return "T";
case gem_btn::count: return "Count";
case gem_btn::x_axis: return "X-Axis"; case gem_btn::x_axis: return "X-Axis";
case gem_btn::y_axis: return "Y-Axis"; case gem_btn::y_axis: return "Y-Axis";
case gem_btn::combo: return "Combo";
case gem_btn::combo_start: return "Combo Start";
case gem_btn::combo_select: return "Combo Select";
case gem_btn::combo_triangle: return "Combo Triangle";
case gem_btn::combo_circle: return "Combo Circle";
case gem_btn::combo_cross: return "Combo Cross";
case gem_btn::combo_square: return "Combo Square";
case gem_btn::combo_move: return "Combo Move";
case gem_btn::combo_t: return "Combo T";
case gem_btn::count: return "Count";
} }
return unknown; return unknown;
@ -177,6 +186,7 @@ using gun_thread = named_thread<gun_handler>;
cfg_gems g_cfg_gem_real; cfg_gems g_cfg_gem_real;
cfg_fake_gems g_cfg_gem_fake; cfg_fake_gems g_cfg_gem_fake;
cfg_mouse_gems g_cfg_gem_mouse;
struct gem_config_data struct gem_config_data
{ {
@ -494,8 +504,14 @@ public:
cellGem.notice("Could not load fake gem config. Using defaults."); cellGem.notice("Could not load fake gem config. Using defaults.");
} }
if (!g_cfg_gem_mouse.load())
{
cellGem.notice("Could not load mouse gem config. Using defaults.");
}
cellGem.notice("Real gem config=\n", g_cfg_gem_real.to_string()); cellGem.notice("Real gem config=\n", g_cfg_gem_real.to_string());
cellGem.notice("Fake gem config=\n", g_cfg_gem_fake.to_string()); cellGem.notice("Fake gem config=\n", g_cfg_gem_fake.to_string());
cellGem.notice("Mouse gem config=\n", g_cfg_gem_mouse.to_string());
} }
}; };
@ -1574,7 +1590,7 @@ static void ds3_input_to_pad(const u32 gem_num, be_t<u16>& digital_buttons, be_t
return; return;
} }
const auto handle_input = [&](gem_btn btn, u16 value, bool pressed) const auto handle_input = [&](gem_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;
@ -1606,9 +1622,7 @@ static void ds3_input_to_pad(const u32 gem_num, be_t<u16>& digital_buttons, be_t
digital_buttons |= CELL_GEM_CTRL_T; digital_buttons |= CELL_GEM_CTRL_T;
analog_t = std::max<u16>(analog_t, value); analog_t = std::max<u16>(analog_t, value);
break; break;
case gem_btn::x_axis: default:
case gem_btn::y_axis:
case gem_btn::count:
break; break;
} }
}; };
@ -1632,7 +1646,7 @@ static inline void ds3_get_stick_values(u32 gem_num, const std::shared_ptr<Pad>&
y_pos = 0; y_pos = 0;
const auto& cfg = ::at32(g_cfg_gem_fake.players, gem_num); const auto& cfg = ::at32(g_cfg_gem_fake.players, gem_num);
cfg->handle_input(pad, true, [&](gem_btn btn, u16 value, bool pressed) cfg->handle_input(pad, true, [&](gem_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;
@ -1828,41 +1842,97 @@ static bool mouse_input_to_pad(u32 mouse_no, be_t<u16>& digital_buttons, be_t<u1
return false; return false;
} }
std::set<MouseButtonCodes> pressed_buttons;
const Mouse& mouse_data = ::at32(handler.GetMice(), mouse_no); const Mouse& mouse_data = ::at32(handler.GetMice(), mouse_no);
const auto is_pressed = [&mouse_data, &pressed_buttons](MouseButtonCodes button) -> bool auto& cfg = ::at32(g_cfg_gem_mouse.players, mouse_no);
bool combo_active = false;
std::set<pad_button> combos;
static const std::unordered_map<gem_btn, u16> btn_map =
{ {
// Only allow each button to be used for one action unless it's the combo button. { gem_btn::start, CELL_GEM_CTRL_START },
return (mouse_data.buttons & button) && (button == (CELL_MOUSE_BUTTON_3 + 0u/*fix warning*/) || pressed_buttons.insert(button).second); { gem_btn::select, CELL_GEM_CTRL_SELECT },
{ gem_btn::triangle, CELL_GEM_CTRL_TRIANGLE },
{ gem_btn::circle, CELL_GEM_CTRL_CIRCLE },
{ gem_btn::cross, CELL_GEM_CTRL_CROSS },
{ gem_btn::square, CELL_GEM_CTRL_SQUARE },
{ gem_btn::move, CELL_GEM_CTRL_MOVE },
{ gem_btn::t, CELL_GEM_CTRL_T },
{ gem_btn::combo_start, CELL_GEM_CTRL_START },
{ gem_btn::combo_select, CELL_GEM_CTRL_SELECT },
{ gem_btn::combo_triangle, CELL_GEM_CTRL_TRIANGLE },
{ gem_btn::combo_circle, CELL_GEM_CTRL_CIRCLE },
{ gem_btn::combo_cross, CELL_GEM_CTRL_CROSS },
{ gem_btn::combo_square, CELL_GEM_CTRL_SQUARE },
{ gem_btn::combo_move, CELL_GEM_CTRL_MOVE },
{ gem_btn::combo_t, CELL_GEM_CTRL_T },
}; };
digital_buttons = 0; // Check combo button first
cfg->handle_input(mouse_data, [&combo_active](gem_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& abort)
{
if (pressed && btn == gem_btn::combo)
{
combo_active = true;
abort = true;
}
});
if ((is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_1)) || is_pressed(CELL_MOUSE_BUTTON_6)) // Check combos
digital_buttons |= CELL_GEM_CTRL_SELECT; if (combo_active)
{
cfg->handle_input(mouse_data, [&digital_buttons, &combos](gem_btn btn, pad_button pad_btn, u16 /*value*/, bool pressed, bool& /*abort*/)
{
if (!pressed)
return;
if ((is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_2)) || is_pressed(CELL_MOUSE_BUTTON_7)) switch (btn)
digital_buttons |= CELL_GEM_CTRL_START; {
case gem_btn::combo_start:
case gem_btn::combo_select:
case gem_btn::combo_triangle:
case gem_btn::combo_circle:
case gem_btn::combo_cross:
case gem_btn::combo_square:
case gem_btn::combo_move:
case gem_btn::combo_t:
digital_buttons |= ::at32(btn_map, btn);
combos.insert(pad_btn);
break;
default:
break;
}
});
}
if ((is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_4)) || is_pressed(CELL_MOUSE_BUTTON_8)) // Check normal buttons
digital_buttons |= CELL_GEM_CTRL_TRIANGLE; cfg->handle_input(mouse_data, [&digital_buttons, &combos](gem_btn btn, pad_button pad_btn, u16 /*value*/, bool pressed, bool& /*abort*/)
{
if (!pressed)
return;
if (is_pressed(CELL_MOUSE_BUTTON_3) && is_pressed(CELL_MOUSE_BUTTON_5)) switch (btn)
digital_buttons |= CELL_GEM_CTRL_SQUARE; {
case gem_btn::start:
case gem_btn::select:
case gem_btn::square:
case gem_btn::cross:
case gem_btn::circle:
case gem_btn::triangle:
case gem_btn::move:
case gem_btn::t:
// Ignore this gem_btn if the same pad_button was already used in a combo
if (!combos.contains(pad_btn))
{
digital_buttons |= ::at32(btn_map, btn);
}
break;
default:
break;
}
});
if (is_pressed(CELL_MOUSE_BUTTON_1)) analog_t = (digital_buttons & CELL_GEM_CTRL_T) ? 0xFFFF : 0;
digital_buttons |= CELL_GEM_CTRL_T;
if (is_pressed(CELL_MOUSE_BUTTON_2))
digital_buttons |= CELL_GEM_CTRL_MOVE;
if (is_pressed(CELL_MOUSE_BUTTON_4))
digital_buttons |= CELL_GEM_CTRL_CIRCLE;
if (is_pressed(CELL_MOUSE_BUTTON_5))
digital_buttons |= CELL_GEM_CTRL_CROSS;
analog_t = (mouse_data.buttons & CELL_MOUSE_BUTTON_1) ? 0xFFFF : 0;
return true; return true;
} }

View file

@ -161,7 +161,7 @@ void usb_device_buzz::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint*/
} }
const auto& cfg = g_cfg_buzz.players[i]; const auto& cfg = g_cfg_buzz.players[i];
cfg->handle_input(pad, true, [&buf, &index](buzz_btn btn, u16 /*value*/, bool pressed) cfg->handle_input(pad, true, [&buf, &index](buzz_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;

View file

@ -147,7 +147,7 @@ void usb_device_ghltar::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpoint
} }
const auto& cfg = ::at32(g_cfg_ghltar.players, m_controller_index); const auto& cfg = ::at32(g_cfg_ghltar.players, m_controller_index);
cfg->handle_input(pad, true, [&buf](ghltar_btn btn, u16 value, bool pressed) cfg->handle_input(pad, true, [&buf](ghltar_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;

View file

@ -227,7 +227,7 @@ void usb_device_guncon3::interrupt_transfer(u32 buf_size, u8* buf, u32 endpoint,
return; return;
} }
const auto input_callback = [&gc](guncon3_btn btn, u16 value, bool pressed) const auto input_callback = [&gc](guncon3_btn btn, pad_button /*pad_button*/, u16 value, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;

View file

@ -34,7 +34,7 @@ void MouseHandlerBase::save(utils::serial& ar)
bool MouseHandlerBase::is_time_for_update(double elapsed_time) bool MouseHandlerBase::is_time_for_update(double elapsed_time)
{ {
steady_clock::time_point now = steady_clock::now(); steady_clock::time_point now = steady_clock::now();
double elapsed = (now - last_update).count() / 1000'000.; const double elapsed = (now - last_update).count() / 1000'000.;
if (elapsed > elapsed_time) if (elapsed > elapsed_time)
{ {

View file

@ -280,7 +280,7 @@ void usb_device_topshotelite::interrupt_transfer(u32 buf_size, u8* buf, u32 /*en
} }
bool up = false, right = false, down = false, left = false; bool up = false, right = false, down = false, left = false;
const auto input_callback = [&ts, &up, &down, &left, &right](topshotelite_btn btn, u16 value, bool pressed) const auto input_callback = [&ts, &up, &down, &left, &right](topshotelite_btn btn, pad_button /*pad_button*/, u16 value, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;

View file

@ -308,7 +308,7 @@ void usb_device_topshotfearmaster::interrupt_transfer(u32 buf_size, u8* buf, u32
} }
bool up = false, right = false, down = false, left = false; bool up = false, right = false, down = false, left = false;
const auto input_callback = [&ts, &up, &down, &left, &right](topshotfearmaster_btn btn, u16 value, bool pressed) const auto input_callback = [&ts, &up, &down, &left, &right](topshotfearmaster_btn btn, pad_button /*pad_button*/, u16 value, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;

View file

@ -159,7 +159,7 @@ void usb_device_turntable::interrupt_transfer(u32 buf_size, u8* buf, u32 /*endpo
return; return;
const auto& cfg = ::at32(g_cfg_turntable.players, m_controller_index); const auto& cfg = ::at32(g_cfg_turntable.players, m_controller_index);
cfg->handle_input(pad, true, [&buf](turntable_btn btn, u16 value, bool pressed) cfg->handle_input(pad, true, [&buf](turntable_btn btn, pad_button /*pad_btn*/, u16 value, bool pressed, bool& /*abort*/)
{ {
if (!pressed) if (!pressed)
return; return;

View file

@ -88,7 +88,7 @@ public:
button_map.clear(); button_map.clear();
} }
void handle_input(std::shared_ptr<Pad> pad, bool press_only, const std::function<void(T, u16, bool)>& func) const 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) if (!pad)
return; return;
@ -97,19 +97,25 @@ public:
{ {
if (button.m_pressed || !press_only) if (button.m_pressed || !press_only)
{ {
handle_input(func, button.m_offset, button.m_outKeyCode, button.m_value, button.m_pressed, true); if (handle_input(func, button.m_offset, button.m_outKeyCode, button.m_value, button.m_pressed, true))
{
return;
}
} }
} }
for (const AnalogStick& stick : pad->m_sticks) for (const AnalogStick& stick : pad->m_sticks)
{ {
handle_input(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true); if (handle_input(func, stick.m_offset, get_axis_keycode(stick.m_offset, stick.m_value), stick.m_value, true, true))
{
return;
}
} }
} }
void handle_input(const Mouse& mouse, const std::function<void(T, u16, bool)>& func) const void handle_input(const Mouse& mouse, const std::function<void(T, pad_button, u16, bool, bool&)>& func) const
{ {
for (int i = 0; i < 7; i++) for (int i = 0; i < 8; i++)
{ {
const MouseButtonCodes cell_code = get_mouse_button_code(i); const MouseButtonCodes cell_code = get_mouse_button_code(i);
if ((mouse.buttons & cell_code)) if ((mouse.buttons & cell_code))
@ -117,7 +123,11 @@ public:
const pad_button button = static_cast<pad_button>(static_cast<int>(pad_button::mouse_button_1) + i); const pad_button button = static_cast<pad_button>(static_cast<int>(pad_button::mouse_button_1) + i);
const u32 offset = pad_button_offset(button); const u32 offset = pad_button_offset(button);
const u32 keycode = pad_button_keycode(button); const u32 keycode = pad_button_keycode(button);
handle_input(func, offset, keycode, 255, true, true);
if (handle_input(func, offset, keycode, 255, true, true))
{
return;
}
} }
} }
} }
@ -163,10 +173,12 @@ protected:
return empty_set; return empty_set;
} }
void handle_input(const std::function<void(T, u16, bool)>& func, u32 offset, u32 keycode, u16 value, bool pressed, bool check_axis) const 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
{ {
m_mutex.lock(); m_mutex.lock();
bool abort = false;
const auto& btns = find_button(offset, keycode); const auto& btns = find_button(offset, keycode);
if (btns.empty()) if (btns.empty())
{ {
@ -180,24 +192,26 @@ protected:
case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X:
case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y:
handle_input(func, offset, static_cast<u32>(axis_direction::both), value, pressed, false); abort = handle_input(func, offset, static_cast<u32>(axis_direction::both), value, pressed, false);
break; break;
default: default:
break; break;
} }
} }
return; return abort;
} }
for (const auto& btn : btns) for (const auto& btn : btns)
{ {
if (btn && func) if (btn && func)
{ {
func(btn->btn_id(), value, pressed); func(btn->btn_id(), btn->get(), value, pressed, abort);
if (abort) break;
} }
} }
m_mutex.unlock(); m_mutex.unlock();
return abort;
} }
}; };

View file

@ -4,7 +4,7 @@
#include <array> #include <array>
enum class gem_btn enum class gem_btn : u32
{ {
start, start,
select, select,
@ -17,6 +17,18 @@ enum class gem_btn
x_axis, x_axis,
y_axis, y_axis,
combo_begin,
combo = combo_begin,
combo_start,
combo_select,
combo_triangle,
combo_circle,
combo_cross,
combo_square,
combo_move,
combo_t,
combo_end = combo_t,
count count
}; };
@ -41,6 +53,34 @@ struct cfg_fake_gems final : public emulated_pads_config<cfg_fake_gem, 4>
cfg_fake_gems() : emulated_pads_config<cfg_fake_gem, 4>("gem") {}; cfg_fake_gems() : emulated_pads_config<cfg_fake_gem, 4>("gem") {};
}; };
struct cfg_mouse_gem final : public emulated_pad_config<gem_btn>
{
cfg_mouse_gem(node* owner, const std::string& name) : emulated_pad_config(owner, name) {}
cfg_pad_btn<gem_btn> start{ this, "Start", gem_btn::start, pad_button::mouse_button_6 };
cfg_pad_btn<gem_btn> select{ this, "Select", gem_btn::select, pad_button::mouse_button_7 };
cfg_pad_btn<gem_btn> triangle{ this, "Triangle", gem_btn::triangle, pad_button::mouse_button_8 };
cfg_pad_btn<gem_btn> circle{ this, "Circle", gem_btn::circle, pad_button::mouse_button_4 };
cfg_pad_btn<gem_btn> cross{ this, "Cross", gem_btn::cross, pad_button::mouse_button_5 };
cfg_pad_btn<gem_btn> square{ this, "Square", gem_btn::square, pad_button::mouse_button_3 };
cfg_pad_btn<gem_btn> move{ this, "Move", gem_btn::move, pad_button::mouse_button_2 };
cfg_pad_btn<gem_btn> t{ this, "T", gem_btn::t, pad_button::mouse_button_1 };
cfg_pad_btn<gem_btn> combo{ this, "Combo", gem_btn::combo, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_start{ this, "Combo Start", gem_btn::combo_start, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_select{ this, "Combo Select", gem_btn::combo_select, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_triangle{ this, "Combo Triangle", gem_btn::combo_triangle, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_circle{ this, "Combo Circle", gem_btn::combo_circle, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_cross{ this, "Combo Cross", gem_btn::combo_cross, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_square{ this, "Combo Square", gem_btn::combo_square, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_move{ this, "Combo Move", gem_btn::combo_move, pad_button::pad_button_max_enum };
cfg_pad_btn<gem_btn> combo_t{ this, "Combo T", gem_btn::combo_t, pad_button::pad_button_max_enum };
};
struct cfg_mouse_gems final : public emulated_pads_config<cfg_mouse_gem, 4>
{
cfg_mouse_gems() : emulated_pads_config<cfg_mouse_gem, 4>("gem_mouse") {};
};
struct cfg_gem final : public emulated_pad_config<gem_btn> struct cfg_gem final : public emulated_pad_config<gem_btn>
{ {
cfg_gem(node* owner, const std::string& name) : emulated_pad_config(owner, name) {} cfg_gem(node* owner, const std::string& name) : emulated_pad_config(owner, name) {}
@ -62,3 +102,4 @@ struct cfg_gems final : public emulated_pads_config<cfg_gem, 4>
extern cfg_gems g_cfg_gem_real; extern cfg_gems g_cfg_gem_real;
extern cfg_fake_gems g_cfg_gem_fake; extern cfg_fake_gems g_cfg_gem_fake;
extern cfg_mouse_gems g_cfg_gem_mouse;

View file

@ -39,7 +39,7 @@ void fmt_class_string<pad_button>::format(std::string& out, u64 arg)
case pad_button::rs_right: return "Right Stick Right"; case pad_button::rs_right: return "Right Stick Right";
case pad_button::rs_x: return "Right Stick X-Axis"; case pad_button::rs_x: return "Right Stick X-Axis";
case pad_button::rs_y: return "Right Stick Y-Axis"; case pad_button::rs_y: return "Right Stick Y-Axis";
case pad_button::pad_button_max_enum: return "MAX_ENUM"; case pad_button::pad_button_max_enum: return "";
case pad_button::mouse_button_1: return "Mouse Button 1"; 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_2: return "Mouse Button 2";
case pad_button::mouse_button_3: return "Mouse Button 3"; case pad_button::mouse_button_3: return "Mouse Button 3";

View file

@ -203,7 +203,7 @@ void usb_device_usio::translate_input_taiko()
if (const auto& pad = ::at32(handler->GetPads(), pad_number); (pad->m_port_status & CELL_PAD_STATUS_CONNECTED) && is_input_allowed()) if (const auto& pad = ::at32(handler->GetPads(), pad_number); (pad->m_port_status & CELL_PAD_STATUS_CONNECTED) && is_input_allowed())
{ {
const auto& cfg = ::at32(g_cfg_usio.players, pad_number); const auto& cfg = ::at32(g_cfg_usio.players, pad_number);
cfg->handle_input(pad, false, [&](usio_btn btn, u16 /*value*/, bool pressed) cfg->handle_input(pad, false, [&](usio_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/)
{ {
switch (btn) switch (btn)
{ {
@ -288,7 +288,7 @@ void usb_device_usio::translate_input_tekken()
if (const auto& pad = ::at32(handler->GetPads(), pad_number); (pad->m_port_status & CELL_PAD_STATUS_CONNECTED) && is_input_allowed()) if (const auto& pad = ::at32(handler->GetPads(), pad_number); (pad->m_port_status & CELL_PAD_STATUS_CONNECTED) && is_input_allowed())
{ {
const auto& cfg = ::at32(g_cfg_usio.players, pad_number); const auto& cfg = ::at32(g_cfg_usio.players, pad_number);
cfg->handle_input(pad, false, [&](usio_btn btn, u16 /*value*/, bool pressed) cfg->handle_input(pad, false, [&](usio_btn btn, pad_button /*pad_btn*/, u16 /*value*/, bool pressed, bool& /*abort*/)
{ {
switch (btn) switch (btn)
{ {

View file

@ -265,7 +265,6 @@ namespace rsx
fade_animation.end = color4f(1.f); fade_animation.end = color4f(1.f);
fade_animation.active = true; fade_animation.active = true;
this->on_close = std::move(on_close);
visible = true; visible = true;
const auto notify = std::make_shared<atomic_t<u32>>(0); const auto notify = std::make_shared<atomic_t<u32>>(0);

View file

@ -108,10 +108,10 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
switch (ev->type()) switch (ev->type())
{ {
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:
MouseButtonDown(static_cast<QMouseEvent*>(ev)); MouseButton(static_cast<QMouseEvent*>(ev), true);
break; break;
case QEvent::MouseButtonRelease: case QEvent::MouseButtonRelease:
MouseButtonUp(static_cast<QMouseEvent*>(ev)); MouseButton(static_cast<QMouseEvent*>(ev), false);
break; break;
case QEvent::MouseMove: case QEvent::MouseMove:
MouseMove(static_cast<QMouseEvent*>(ev)); MouseMove(static_cast<QMouseEvent*>(ev));
@ -119,6 +119,12 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
case QEvent::Wheel: case QEvent::Wheel:
MouseScroll(static_cast<QWheelEvent*>(ev)); MouseScroll(static_cast<QWheelEvent*>(ev));
break; break;
case QEvent::KeyPress:
Key(static_cast<QKeyEvent*>(ev), true);
break;
case QEvent::KeyRelease:
Key(static_cast<QKeyEvent*>(ev), false);
break;
default: default:
return false; return false;
} }
@ -126,22 +132,22 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
return false; return false;
} }
void basic_mouse_handler::MouseButtonDown(QMouseEvent* event) void basic_mouse_handler::Key(QKeyEvent* event, bool pressed)
{ {
if (!event) [[unlikely]] if (!event) [[unlikely]]
{ {
return; return;
} }
const int button = event->button(); const int key = event->key();
if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [button](const auto& entry){ return entry.second == button; }); if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [key](const auto& entry){ return entry.second.code == key && entry.second.is_key; });
it != m_buttons.cend()) it != m_buttons.cend())
{ {
MouseHandlerBase::Button(0, it->first, true); MouseHandlerBase::Button(0, it->first, pressed);
} }
} }
void basic_mouse_handler::MouseButtonUp(QMouseEvent* event) void basic_mouse_handler::MouseButton(QMouseEvent* event, bool pressed)
{ {
if (!event) [[unlikely]] if (!event) [[unlikely]]
{ {
@ -149,10 +155,10 @@ void basic_mouse_handler::MouseButtonUp(QMouseEvent* event)
} }
const int button = event->button(); const int button = event->button();
if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [button](const auto& entry){ return entry.second == button; }); if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [button](const auto& entry){ return entry.second.code == button && !entry.second.is_key; });
it != m_buttons.cend()) it != m_buttons.cend())
{ {
MouseHandlerBase::Button(0, it->first, false); MouseHandlerBase::Button(0, it->first, pressed);
} }
} }
@ -176,17 +182,31 @@ bool basic_mouse_handler::get_mouse_lock_state() const
return false; return false;
} }
int basic_mouse_handler::get_mouse_button(const cfg::string& button) basic_mouse_handler::mouse_button basic_mouse_handler::get_mouse_button(const cfg::string& button)
{ {
const std::string name = button.to_string(); const std::string name = button.to_string();
const auto it = std::find_if(mouse_list.cbegin(), mouse_list.cend(), [&name](const auto& entry){ return entry.second == name; }); const auto it = std::find_if(mouse_list.cbegin(), mouse_list.cend(), [&name](const auto& entry){ return entry.second == name; });
if (it != mouse_list.cend()) if (it != mouse_list.cend())
{ {
return it->first; return mouse_button{
.code = static_cast<int>(it->first),
.is_key = false
};
} }
return Qt::MouseButton::NoButton; if (const u32 key = keyboard_pad_handler::GetKeyCode(QString::fromStdString(name)))
{
return mouse_button{
.code = static_cast<int>(key),
.is_key = true
};
}
return mouse_button{
.code = Qt::MouseButton::NoButton,
.is_key = false
};
} }
void basic_mouse_handler::MouseMove(QMouseEvent* event) void basic_mouse_handler::MouseMove(QMouseEvent* event)

View file

@ -20,8 +20,8 @@ public:
void Init(const u32 max_connect) override; void Init(const u32 max_connect) override;
void SetTargetWindow(QWindow* target); void SetTargetWindow(QWindow* target);
void MouseButtonDown(QMouseEvent* event); void Key(QKeyEvent* event, bool pressed);
void MouseButtonUp(QMouseEvent* event); void MouseButton(QMouseEvent* event, bool pressed);
void MouseScroll(QWheelEvent* event); void MouseScroll(QWheelEvent* event);
void MouseMove(QMouseEvent* event); void MouseMove(QMouseEvent* event);
@ -29,8 +29,14 @@ public:
private: private:
void reload_config(); void reload_config();
bool get_mouse_lock_state() const; bool get_mouse_lock_state() const;
static int get_mouse_button(const cfg::string& button);
struct mouse_button
{
int code = Qt::MouseButton::NoButton;
bool is_key = false;
};
static mouse_button get_mouse_button(const cfg::string& button);
QWindow* m_target = nullptr; QWindow* m_target = nullptr;
std::map<u8, int> m_buttons; std::map<u8, mouse_button> m_buttons;
}; };

View file

@ -2,6 +2,8 @@
#include "raw_mouse_config.h" #include "raw_mouse_config.h"
#include "Emu/Io/MouseHandler.h" #include "Emu/Io/MouseHandler.h"
LOG_CHANNEL(cfg_log, "CFG");
std::string mouse_button_id(int code) std::string mouse_button_id(int code)
{ {
switch (code) switch (code)

View file

@ -5,8 +5,6 @@
#include <array> #include <array>
LOG_CHANNEL(cfg_log, "CFG");
std::string mouse_button_id(int code); std::string mouse_button_id(int code);
struct raw_mouse_config : cfg::node struct raw_mouse_config : cfg::node

View file

@ -190,6 +190,26 @@ void basic_mouse_settings_dialog::on_button_click(int id)
m_remap_timer.start(1000); m_remap_timer.start(1000);
} }
void basic_mouse_settings_dialog::keyPressEvent(QKeyEvent* event)
{
if (m_button_id < 0)
{
// We are not remapping a button, so pass the event to the base class.
QDialog::keyPressEvent(event);
return;
}
const std::string name = keyboard_pad_handler::GetKeyName(event, false);
g_cfg_mouse.get_button(m_button_id).from_string(name);
if (auto button = m_buttons->button(m_button_id))
{
button->setText(QString::fromStdString(name));
}
reactivate_buttons();
}
void basic_mouse_settings_dialog::mouseReleaseEvent(QMouseEvent* event) void basic_mouse_settings_dialog::mouseReleaseEvent(QMouseEvent* event)
{ {
if (m_button_id < 0) if (m_button_id < 0)

View file

@ -39,6 +39,7 @@ private:
QTimer m_remap_timer; QTimer m_remap_timer;
protected: protected:
void keyPressEvent(QKeyEvent* event) override;
void mouseReleaseEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override;
bool eventFilter(QObject* object, QEvent* event) override; bool eventFilter(QObject* object, QEvent* event) override;
}; };

View file

@ -1,6 +1,8 @@
#include "stdafx.h" #include "stdafx.h"
#include "emulated_pad_settings_dialog.h" #include "emulated_pad_settings_dialog.h"
#include "localized_emu.h" #include "localized_emu.h"
#include "Input/raw_mouse_config.h"
#include "Emu/Io/mouse_config.h"
#include "Emu/Io/buzz_config.h" #include "Emu/Io/buzz_config.h"
#include "Emu/Io/gem_config.h" #include "Emu/Io/gem_config.h"
#include "Emu/Io/ghltar_config.h" #include "Emu/Io/ghltar_config.h"
@ -13,6 +15,7 @@
#include <QDialogButtonBox> #include <QDialogButtonBox>
#include <QGroupBox> #include <QGroupBox>
#include <QLabel>
#include <QMessageBox> #include <QMessageBox>
#include <QPushButton> #include <QPushButton>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -92,6 +95,10 @@ emulated_pad_settings_dialog::emulated_pad_settings_dialog(pad_type type, QWidge
setWindowTitle(tr("Configure Emulated PS Move (Fake)")); setWindowTitle(tr("Configure Emulated PS Move (Fake)"));
add_tabs<gem_btn>(tabs); add_tabs<gem_btn>(tabs);
break; break;
case emulated_pad_settings_dialog::pad_type::mousegem:
setWindowTitle(tr("Configure Emulated PS Move (Mouse)"));
add_tabs<gem_btn>(tabs);
break;
case emulated_pad_settings_dialog::pad_type::guncon3: case emulated_pad_settings_dialog::pad_type::guncon3:
setWindowTitle(tr("Configure Emulated GunCon 3")); setWindowTitle(tr("Configure Emulated GunCon 3"));
add_tabs<guncon3_btn>(tabs); add_tabs<guncon3_btn>(tabs);
@ -116,8 +123,12 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
{ {
ensure(!!tabs); ensure(!!tabs);
constexpr u32 max_items_per_column = 6; std::set<int> ignored_values;
int count = static_cast<int>(T::count);
const auto remove_value = [&ignored_values](int value)
{
ignored_values.insert(static_cast<int>(value));
};
usz players = 0; usz players = 0;
switch (m_type) switch (m_type)
@ -137,13 +148,29 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
case pad_type::gem: case pad_type::gem:
players = g_cfg_gem_real.players.size(); players = g_cfg_gem_real.players.size();
// Ignore x and y axis // Ignore combo, x and y axis
static_assert(static_cast<int>(gem_btn::y_axis) == static_cast<int>(gem_btn::count) - 1); remove_value(static_cast<int>(gem_btn::x_axis));
static_assert(static_cast<int>(gem_btn::x_axis) == static_cast<int>(gem_btn::count) - 2); remove_value(static_cast<int>(gem_btn::y_axis));
count -= 2; for (int i = static_cast<int>(gem_btn::combo_begin); i <= static_cast<int>(gem_btn::combo_end); i++)
{
remove_value(i);
}
break; break;
case pad_type::ds3gem: case pad_type::ds3gem:
players = g_cfg_gem_fake.players.size(); players = g_cfg_gem_fake.players.size();
// Ignore combo
for (int i = static_cast<int>(gem_btn::combo_begin); i <= static_cast<int>(gem_btn::combo_end); i++)
{
remove_value(i);
}
break;
case pad_type::mousegem:
players = g_cfg_gem_mouse.players.size();
// Ignore x and y axis
remove_value(static_cast<int>(gem_btn::x_axis));
remove_value(static_cast<int>(gem_btn::y_axis));
break; break;
case pad_type::guncon3: case pad_type::guncon3:
players = g_cfg_guncon3.players.size(); players = g_cfg_guncon3.players.size();
@ -156,6 +183,8 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
break; break;
} }
constexpr u32 max_items_per_column = 6;
const int count = static_cast<int>(T::count) - static_cast<int>(ignored_values.size());
int rows = count; int rows = count;
for (u32 cols = 1; utils::aligned_div(static_cast<u32>(count), cols) > max_items_per_column;) for (u32 cols = 1; utils::aligned_div(static_cast<u32>(count), cols) > max_items_per_column;)
@ -165,13 +194,30 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
m_combos.resize(players); m_combos.resize(players);
const bool show_mouse_legend = m_type == pad_type::mousegem;
if (show_mouse_legend)
{
if (!g_cfg_mouse.load())
{
cfg_log.notice("Could not restore mouse config. Using defaults.");
}
if (!g_cfg_raw_mouse.load())
{
cfg_log.notice("Could not restore raw mouse config. Using defaults.");
}
}
for (usz player = 0; player < players; player++) for (usz player = 0; player < players; player++)
{ {
QWidget* widget = new QWidget(this); // Create grid with all buttons
QGridLayout* grid_layout = new QGridLayout(this); QGridLayout* grid_layout = new QGridLayout(this);
for (int i = 0, row = 0, col = 0; i < count; i++, row++) for (int i = 0, row = 0, col = 0; i < static_cast<int>(T::count); i++)
{ {
if (ignored_values.contains(i)) continue;
const T id = static_cast<T>(i); const T id = static_cast<T>(i);
const QString name = QString::fromStdString(fmt::format("%s", id)); const QString name = QString::fromStdString(fmt::format("%s", id));
@ -179,16 +225,35 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
QGroupBox* gb = new QGroupBox(name, this); QGroupBox* gb = new QGroupBox(name, this);
QComboBox* combo = new QComboBox; QComboBox* combo = new QComboBox;
for (int p = 0; p < static_cast<int>(pad_button::pad_button_max_enum); p++) if constexpr (std::is_same_v<T, gem_btn>)
{ {
const QString translated = localized_emu::translated_pad_button(static_cast<pad_button>(p)); const gem_btn btn = static_cast<gem_btn>(i);
combo->addItem(translated); if (btn >= gem_btn::combo_begin && btn <= gem_btn::combo_end)
const int index = combo->findText(translated); {
combo->setItemData(index, p, button_role::button); gb->setToolTip(tr("Press the \"Combo\" button in combination with any of the other combo buttons to trigger their related PS Move button.\n"
combo->setItemData(index, i, button_role::emulated_button); "This can be useful if your device does not have enough regular buttons."));
}
} }
if constexpr (std::is_same_v<T, guncon3_btn> || std::is_same_v<T, topshotelite_btn> || std::is_same_v<T, topshotfearmaster_btn>) // Add empty value
combo->addItem("");
const int index = combo->findText("");
combo->setItemData(index, static_cast<int>(pad_button::pad_button_max_enum), button_role::button);
combo->setItemData(index, i, button_role::emulated_button);
if (m_type != pad_type::mousegem)
{
for (int p = 0; p < static_cast<int>(pad_button::pad_button_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);
}
}
if (std::is_same_v<T, guncon3_btn> || std::is_same_v<T, topshotelite_btn> || std::is_same_v<T, topshotfearmaster_btn> || m_type == pad_type::mousegem)
{ {
for (int p = static_cast<int>(pad_button::mouse_button_1); p <= static_cast<int>(pad_button::mouse_button_8); p++) for (int p = static_cast<int>(pad_button::mouse_button_1); p <= static_cast<int>(pad_button::mouse_button_8); p++)
{ {
@ -221,6 +286,9 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
case pad_type::ds3gem: case pad_type::ds3gem:
saved_btn_id = ::at32(g_cfg_gem_fake.players, player)->get_pad_button(static_cast<gem_btn>(id)); saved_btn_id = ::at32(g_cfg_gem_fake.players, player)->get_pad_button(static_cast<gem_btn>(id));
break; break;
case pad_type::mousegem:
saved_btn_id = ::at32(g_cfg_gem_mouse.players, player)->get_pad_button(static_cast<gem_btn>(id));
break;
case pad_type::guncon3: case pad_type::guncon3:
saved_btn_id = ::at32(g_cfg_guncon3.players, player)->get_pad_button(static_cast<guncon3_btn>(id)); saved_btn_id = ::at32(g_cfg_guncon3.players, player)->get_pad_button(static_cast<guncon3_btn>(id));
break; break;
@ -265,6 +333,9 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
case pad_type::ds3gem: case pad_type::ds3gem:
::at32(g_cfg_gem_fake.players, player)->set_button(static_cast<gem_btn>(id), btn_id); ::at32(g_cfg_gem_fake.players, player)->set_button(static_cast<gem_btn>(id), btn_id);
break; break;
case pad_type::mousegem:
::at32(g_cfg_gem_mouse.players, player)->set_button(static_cast<gem_btn>(id), btn_id);
break;
case pad_type::guncon3: case pad_type::guncon3:
::at32(g_cfg_guncon3.players, player)->set_button(static_cast<guncon3_btn>(id), btn_id); ::at32(g_cfg_guncon3.players, player)->set_button(static_cast<guncon3_btn>(id), btn_id);
break; break;
@ -287,9 +358,60 @@ void emulated_pad_settings_dialog::add_tabs(QTabWidget* tabs)
h_layout->addWidget(combo); h_layout->addWidget(combo);
gb->setLayout(h_layout); gb->setLayout(h_layout);
grid_layout->addWidget(gb, row, col); grid_layout->addWidget(gb, row, col);
row++;
} }
widget->setLayout(grid_layout); QVBoxLayout* v_layout = new QVBoxLayout(this);
// Create a legend of the current mouse settings
if (show_mouse_legend)
{
QHBoxLayout* legend_layout = new QHBoxLayout(this);
if (player == 0)
{
std::string basic_mouse_settings;
fmt::append(basic_mouse_settings, "1: %s\n", g_cfg_mouse.mouse_button_1.to_string());
fmt::append(basic_mouse_settings, "2: %s\n", g_cfg_mouse.mouse_button_2.to_string());
fmt::append(basic_mouse_settings, "3: %s\n", g_cfg_mouse.mouse_button_3.to_string());
fmt::append(basic_mouse_settings, "4: %s\n", g_cfg_mouse.mouse_button_4.to_string());
fmt::append(basic_mouse_settings, "5: %s\n", g_cfg_mouse.mouse_button_5.to_string());
fmt::append(basic_mouse_settings, "6: %s\n", g_cfg_mouse.mouse_button_6.to_string());
fmt::append(basic_mouse_settings, "7: %s\n", g_cfg_mouse.mouse_button_7.to_string());
fmt::append(basic_mouse_settings, "8: %s", g_cfg_mouse.mouse_button_8.to_string());
QGroupBox* gb_legend_basic = new QGroupBox(tr("Current Basic Mouse Config"), this);
QVBoxLayout* gb_legend_basic_layout = new QVBoxLayout(this);
gb_legend_basic_layout->addWidget(new QLabel(QString::fromStdString(basic_mouse_settings), this));
gb_legend_basic->setLayout(gb_legend_basic_layout);
legend_layout->addWidget(gb_legend_basic);
}
{
std::string raw_mouse_settings;
const auto& raw_cfg = *ensure(::at32(g_cfg_raw_mouse.players, player));
fmt::append(raw_mouse_settings, "1: %s\n", raw_cfg.mouse_button_1.to_string());
fmt::append(raw_mouse_settings, "2: %s\n", raw_cfg.mouse_button_2.to_string());
fmt::append(raw_mouse_settings, "3: %s\n", raw_cfg.mouse_button_3.to_string());
fmt::append(raw_mouse_settings, "4: %s\n", raw_cfg.mouse_button_4.to_string());
fmt::append(raw_mouse_settings, "5: %s\n", raw_cfg.mouse_button_5.to_string());
fmt::append(raw_mouse_settings, "6: %s\n", raw_cfg.mouse_button_6.to_string());
fmt::append(raw_mouse_settings, "7: %s\n", raw_cfg.mouse_button_7.to_string());
fmt::append(raw_mouse_settings, "8: %s", raw_cfg.mouse_button_8.to_string());
QGroupBox* gb_legend_raw = new QGroupBox(tr("Current Raw Mouse Config"), this);
QVBoxLayout* gb_legend_raw_layout = new QVBoxLayout(this);
gb_legend_raw_layout->addWidget(new QLabel(QString::fromStdString(raw_mouse_settings), this));
gb_legend_raw->setLayout(gb_legend_raw_layout);
legend_layout->addWidget(gb_legend_raw);
}
v_layout->addLayout(legend_layout);
}
v_layout->addLayout(grid_layout);
QWidget* widget = new QWidget(this);
widget->setLayout(v_layout);
tabs->addTab(widget, tr("Player %0").arg(player + 1)); tabs->addTab(widget, tr("Player %0").arg(player + 1));
} }
} }
@ -334,6 +456,12 @@ void emulated_pad_settings_dialog::load_config()
cfg_log.notice("Could not load fake gem config. Using defaults."); cfg_log.notice("Could not load fake gem config. Using defaults.");
} }
break; break;
case emulated_pad_settings_dialog::pad_type::mousegem:
if (!g_cfg_gem_mouse.load())
{
cfg_log.notice("Could not load mouse gem config. Using defaults.");
}
break;
case emulated_pad_settings_dialog::pad_type::guncon3: case emulated_pad_settings_dialog::pad_type::guncon3:
if (!g_cfg_guncon3.load()) if (!g_cfg_guncon3.load())
{ {
@ -377,6 +505,9 @@ void emulated_pad_settings_dialog::save_config()
case emulated_pad_settings_dialog::pad_type::ds3gem: case emulated_pad_settings_dialog::pad_type::ds3gem:
g_cfg_gem_fake.save(); g_cfg_gem_fake.save();
break; break;
case emulated_pad_settings_dialog::pad_type::mousegem:
g_cfg_gem_mouse.save();
break;
case emulated_pad_settings_dialog::pad_type::guncon3: case emulated_pad_settings_dialog::pad_type::guncon3:
g_cfg_guncon3.save(); g_cfg_guncon3.save();
break; break;
@ -411,6 +542,9 @@ void emulated_pad_settings_dialog::reset_config()
case emulated_pad_settings_dialog::pad_type::ds3gem: case emulated_pad_settings_dialog::pad_type::ds3gem:
g_cfg_gem_fake.from_default(); g_cfg_gem_fake.from_default();
break; break;
case emulated_pad_settings_dialog::pad_type::mousegem:
g_cfg_gem_mouse.from_default();
break;
case emulated_pad_settings_dialog::pad_type::guncon3: case emulated_pad_settings_dialog::pad_type::guncon3:
g_cfg_guncon3.from_default(); g_cfg_guncon3.from_default();
break; break;
@ -454,6 +588,9 @@ void emulated_pad_settings_dialog::reset_config()
case pad_type::ds3gem: case pad_type::ds3gem:
def_btn_id = ::at32(g_cfg_gem_fake.players, player)->default_pad_button(static_cast<gem_btn>(data.toInt())); def_btn_id = ::at32(g_cfg_gem_fake.players, player)->default_pad_button(static_cast<gem_btn>(data.toInt()));
break; break;
case pad_type::mousegem:
def_btn_id = ::at32(g_cfg_gem_mouse.players, player)->default_pad_button(static_cast<gem_btn>(data.toInt()));
break;
case pad_type::guncon3: case pad_type::guncon3:
def_btn_id = ::at32(g_cfg_guncon3.players, player)->default_pad_button(static_cast<guncon3_btn>(data.toInt())); def_btn_id = ::at32(g_cfg_guncon3.players, player)->default_pad_button(static_cast<guncon3_btn>(data.toInt()));
break; break;

View file

@ -21,6 +21,7 @@ public:
usio, usio,
gem, gem,
ds3gem, ds3gem,
mousegem,
guncon3, guncon3,
topshotelite, topshotelite,
topshotfearmaster, topshotfearmaster,

View file

@ -36,14 +36,14 @@ QString localized_emu::translated_pad_button(pad_button btn)
case pad_button::rs_x: return tr("Right Stick X-Axis"); 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::rs_y: return tr("Right Stick Y-Axis");
case pad_button::pad_button_max_enum: return ""; case pad_button::pad_button_max_enum: return "";
case pad_button::mouse_button_1: return tr("Mouse Button 1"); case pad_button::mouse_button_1: return tr("Mouse 1");
case pad_button::mouse_button_2: return tr("Mouse Button 2"); case pad_button::mouse_button_2: return tr("Mouse 2");
case pad_button::mouse_button_3: return tr("Mouse Button 3"); case pad_button::mouse_button_3: return tr("Mouse 3");
case pad_button::mouse_button_4: return tr("Mouse Button 4"); case pad_button::mouse_button_4: return tr("Mouse 4");
case pad_button::mouse_button_5: return tr("Mouse Button 5"); case pad_button::mouse_button_5: return tr("Mouse 5");
case pad_button::mouse_button_6: return tr("Mouse Button 6"); case pad_button::mouse_button_6: return tr("Mouse 6");
case pad_button::mouse_button_7: return tr("Mouse Button 7"); case pad_button::mouse_button_7: return tr("Mouse 7");
case pad_button::mouse_button_8: return tr("Mouse Button 8"); case pad_button::mouse_button_8: return tr("Mouse 8");
} }
return ""; return "";
} }

View file

@ -2911,6 +2911,12 @@ void main_window::CreateConnects()
dlg->show(); dlg->show();
}); });
connect(ui->confPSMoveMouseAct, &QAction::triggered, this, [this]
{
emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::mousegem, this);
dlg->show();
});
connect(ui->confPSMoveDS3Act, &QAction::triggered, this, [this] connect(ui->confPSMoveDS3Act, &QAction::triggered, this, [this]
{ {
emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::ds3gem, this); emulated_pad_settings_dialog* dlg = new emulated_pad_settings_dialog(emulated_pad_settings_dialog::pad_type::ds3gem, this);

View file

@ -244,6 +244,7 @@
<addaction name="confUSIOAct"/> <addaction name="confUSIOAct"/>
<addaction name="confPSMoveAct"/> <addaction name="confPSMoveAct"/>
<addaction name="confPSMoveDS3Act"/> <addaction name="confPSMoveDS3Act"/>
<addaction name="confPSMoveMouseAct"/>
<addaction name="confGunCon3Act"/> <addaction name="confGunCon3Act"/>
<addaction name="confTopShotEliteAct"/> <addaction name="confTopShotEliteAct"/>
<addaction name="confTopShotFearmasterAct"/> <addaction name="confTopShotFearmasterAct"/>
@ -1333,6 +1334,11 @@
<string>PS Move (Fake)</string> <string>PS Move (Fake)</string>
</property> </property>
</action> </action>
<action name="confPSMoveMouseAct">
<property name="text">
<string>PS Move (Mouse)</string>
</property>
</action>
<action name="confGunCon3Act"> <action name="confGunCon3Act">
<property name="text"> <property name="text">
<string>GunCon 3</string> <string>GunCon 3</string>

View file

@ -11,6 +11,8 @@
#include <QMessageBox> #include <QMessageBox>
#include <QVBoxLayout> #include <QVBoxLayout>
LOG_CHANNEL(cfg_log, "CFG");
constexpr u32 button_count = 8; constexpr u32 button_count = 8;
raw_mouse_settings_dialog::raw_mouse_settings_dialog(QWidget* parent) raw_mouse_settings_dialog::raw_mouse_settings_dialog(QWidget* parent)