input: allow dynamic change of mouse configs

This commit is contained in:
Megamouse 2024-06-26 18:57:41 +02:00
parent a9d53e98de
commit e790842007
10 changed files with 81 additions and 39 deletions

View file

@ -314,9 +314,9 @@ std::unordered_map<Id, Note> create_id_to_note_mapping()
Note id_to_note(Id id) Note id_to_note(Id id)
{ {
static auto mapping = create_id_to_note_mapping(); static const auto mapping = create_id_to_note_mapping();
auto it = mapping.find(id); const auto it = mapping.find(id);
return it != std::end(mapping) ? it->second : Note::Invalid; return it != mapping.cend() ? it->second : Note::Invalid;
} }
namespace combo namespace combo

View file

@ -27,7 +27,7 @@ bool mouse_config::load()
return false; return false;
} }
void mouse_config::save() const void mouse_config::save()
{ {
fs::pending_file file(cfg_name); fs::pending_file file(cfg_name);
@ -36,6 +36,8 @@ void mouse_config::save() const
file.file.write(to_string()); file.file.write(to_string());
file.commit(); file.commit();
} }
reload_requested = true;
} }
cfg::string& mouse_config::get_button(int code) cfg::string& mouse_config::get_button(int code)

View file

@ -9,18 +9,20 @@ struct mouse_config final : cfg::node
const std::string cfg_name; const std::string cfg_name;
cfg::string mouse_button_1{this, "Button 1", "Mouse Left"}; cfg::string mouse_button_1{ this, "Button 1", "Mouse Left", true };
cfg::string mouse_button_2{this, "Button 2", "Mouse Right"}; cfg::string mouse_button_2{ this, "Button 2", "Mouse Right", true };
cfg::string mouse_button_3{this, "Button 3", "Mouse Middle"}; cfg::string mouse_button_3{ this, "Button 3", "Mouse Middle", true };
cfg::string mouse_button_4{this, "Button 4", ""}; cfg::string mouse_button_4{ this, "Button 4", "", true };
cfg::string mouse_button_5{this, "Button 5", ""}; cfg::string mouse_button_5{ this, "Button 5", "", true };
cfg::string mouse_button_6{this, "Button 6", ""}; cfg::string mouse_button_6{ this, "Button 6", "", true };
cfg::string mouse_button_7{this, "Button 7", ""}; cfg::string mouse_button_7{ this, "Button 7", "", true };
cfg::string mouse_button_8{this, "Button 8", ""}; cfg::string mouse_button_8{ this, "Button 8", "", true };
atomic_t<bool> reload_requested = true;
bool exist() const; bool exist() const;
bool load(); bool load();
void save() const; void save();
cfg::string& get_button(int code); cfg::string& get_button(int code);
}; };

View file

@ -23,14 +23,7 @@ void basic_mouse_handler::Init(const u32 max_connect)
g_cfg_mouse.from_default(); g_cfg_mouse.from_default();
g_cfg_mouse.load(); g_cfg_mouse.load();
m_buttons[CELL_MOUSE_BUTTON_1] = get_mouse_button(g_cfg_mouse.mouse_button_1); reload_config();
m_buttons[CELL_MOUSE_BUTTON_2] = get_mouse_button(g_cfg_mouse.mouse_button_2);
m_buttons[CELL_MOUSE_BUTTON_3] = get_mouse_button(g_cfg_mouse.mouse_button_3);
m_buttons[CELL_MOUSE_BUTTON_4] = get_mouse_button(g_cfg_mouse.mouse_button_4);
m_buttons[CELL_MOUSE_BUTTON_5] = get_mouse_button(g_cfg_mouse.mouse_button_5);
m_buttons[CELL_MOUSE_BUTTON_6] = get_mouse_button(g_cfg_mouse.mouse_button_6);
m_buttons[CELL_MOUSE_BUTTON_7] = get_mouse_button(g_cfg_mouse.mouse_button_7);
m_buttons[CELL_MOUSE_BUTTON_8] = get_mouse_button(g_cfg_mouse.mouse_button_8);
m_mice.clear(); m_mice.clear();
m_mice.emplace_back(Mouse()); m_mice.emplace_back(Mouse());
@ -52,6 +45,18 @@ void basic_mouse_handler::Init(const u32 max_connect)
type = mouse_handler::basic; type = mouse_handler::basic;
} }
void basic_mouse_handler::reload_config()
{
m_buttons[CELL_MOUSE_BUTTON_1] = get_mouse_button(g_cfg_mouse.mouse_button_1);
m_buttons[CELL_MOUSE_BUTTON_2] = get_mouse_button(g_cfg_mouse.mouse_button_2);
m_buttons[CELL_MOUSE_BUTTON_3] = get_mouse_button(g_cfg_mouse.mouse_button_3);
m_buttons[CELL_MOUSE_BUTTON_4] = get_mouse_button(g_cfg_mouse.mouse_button_4);
m_buttons[CELL_MOUSE_BUTTON_5] = get_mouse_button(g_cfg_mouse.mouse_button_5);
m_buttons[CELL_MOUSE_BUTTON_6] = get_mouse_button(g_cfg_mouse.mouse_button_6);
m_buttons[CELL_MOUSE_BUTTON_7] = get_mouse_button(g_cfg_mouse.mouse_button_7);
m_buttons[CELL_MOUSE_BUTTON_8] = get_mouse_button(g_cfg_mouse.mouse_button_8);
}
/* Sets the target window for the event handler, and also installs an event filter on the target. */ /* Sets the target window for the event handler, and also installs an event filter on the target. */
void basic_mouse_handler::SetTargetWindow(QWindow* target) void basic_mouse_handler::SetTargetWindow(QWindow* target)
{ {
@ -80,6 +85,11 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
// !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target) // !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target)
if (!m_target || !m_target->isVisible() || target == m_target) if (!m_target || !m_target->isVisible() || target == m_target)
{ {
if (g_cfg_mouse.reload_requested.exchange(false))
{
reload_config();
}
switch (ev->type()) switch (ev->type())
{ {
case QEvent::MouseButtonPress: case QEvent::MouseButtonPress:

View file

@ -27,9 +27,10 @@ public:
bool eventFilter(QObject* obj, QEvent* ev) override; bool eventFilter(QObject* obj, QEvent* ev) override;
private: private:
QWindow* m_target = nullptr; void reload_config();
bool get_mouse_lock_state() const; bool get_mouse_lock_state() const;
static int get_mouse_button(const cfg::string& button); static int get_mouse_button(const cfg::string& button);
QWindow* m_target = nullptr;
std::map<u8, int> m_buttons; std::map<u8, int> m_buttons;
}; };

View file

@ -102,4 +102,6 @@ void raw_mice_config::save()
{ {
cfg_log.error("Failed to save %s config to '%s' (error=%s)", cfg_id, cfg_name, fs::g_tls_error); cfg_log.error("Failed to save %s config to '%s' (error=%s)", cfg_id, cfg_name, fs::g_tls_error);
} }
reload_requested = true;
} }

View file

@ -18,14 +18,14 @@ public:
cfg::_float<10, 1000> mouse_acceleration{ this, "Mouse Acceleration", 100.0f, true }; cfg::_float<10, 1000> mouse_acceleration{ this, "Mouse Acceleration", 100.0f, true };
cfg::string mouse_button_1{this, "Button 1", "Button 1"}; cfg::string mouse_button_1{ this, "Button 1", "Button 1", true };
cfg::string mouse_button_2{this, "Button 2", "Button 2"}; cfg::string mouse_button_2{ this, "Button 2", "Button 2", true };
cfg::string mouse_button_3{this, "Button 3", "Button 3"}; cfg::string mouse_button_3{ this, "Button 3", "Button 3", true };
cfg::string mouse_button_4{this, "Button 4", "Button 4"}; cfg::string mouse_button_4{ this, "Button 4", "Button 4", true };
cfg::string mouse_button_5{this, "Button 5", "Button 5"}; cfg::string mouse_button_5{ this, "Button 5", "Button 5", true };
cfg::string mouse_button_6{this, "Button 6", ""}; cfg::string mouse_button_6{ this, "Button 6", "", true };
cfg::string mouse_button_7{this, "Button 7", ""}; cfg::string mouse_button_7{ this, "Button 7", "", true };
cfg::string mouse_button_8{this, "Button 8", ""}; cfg::string mouse_button_8{ this, "Button 8", "", true };
cfg::string& get_button_by_index(int index); cfg::string& get_button_by_index(int index);
cfg::string& get_button(int code); cfg::string& get_button(int code);
@ -38,6 +38,7 @@ struct raw_mice_config : cfg::node
shared_mutex m_mutex; shared_mutex m_mutex;
static constexpr std::string_view cfg_id = "raw_mouse"; static constexpr std::string_view cfg_id = "raw_mouse";
std::array<std::shared_ptr<raw_mouse_config>, 4> players; std::array<std::shared_ptr<raw_mouse_config>, 4> players;
atomic_t<bool> reload_requested = false;
bool load(); bool load();
void save(); void save();

View file

@ -35,6 +35,15 @@ u32 g_registered_handlers = 0;
raw_mouse::raw_mouse(u32 index, const std::string& device_name, void* handle, raw_mouse_handler* handler) raw_mouse::raw_mouse(u32 index, const std::string& device_name, void* handle, raw_mouse_handler* handler)
: m_index(index), m_device_name(device_name), m_handle(handle), m_handler(handler) : m_index(index), m_device_name(device_name), m_handle(handle), m_handler(handler)
{
reload_config();
}
raw_mouse::~raw_mouse()
{
}
void raw_mouse::reload_config()
{ {
if (m_index < ::size32(g_cfg_raw_mouse.players)) if (m_index < ::size32(g_cfg_raw_mouse.players))
{ {
@ -54,10 +63,6 @@ raw_mouse::raw_mouse(u32 index, const std::string& device_name, void* handle, ra
} }
} }
raw_mouse::~raw_mouse()
{
}
std::pair<int, int> raw_mouse::get_mouse_button(const cfg::string& button) std::pair<int, int> raw_mouse::get_mouse_button(const cfg::string& button)
{ {
const std::string value = button.to_string(); const std::string value = button.to_string();
@ -119,6 +124,11 @@ void raw_mouse::update_values(const RAWMOUSE& state)
// Update window handle and size // Update window handle and size
update_window_handle(); update_window_handle();
if (std::exchange(reload_requested, false))
{
reload_config();
}
const auto get_button_pressed = [this](u8 button, int button_flags) const auto get_button_pressed = [this](u8 button, int button_flags)
{ {
const auto& [down, up] = ::at32(m_buttons, button); const auto& [down, up] = ::at32(m_buttons, button);
@ -142,6 +152,9 @@ void raw_mouse::update_values(const RAWMOUSE& state)
get_button_pressed(CELL_MOUSE_BUTTON_3, state.usButtonFlags); get_button_pressed(CELL_MOUSE_BUTTON_3, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_4, state.usButtonFlags); get_button_pressed(CELL_MOUSE_BUTTON_4, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_5, state.usButtonFlags); get_button_pressed(CELL_MOUSE_BUTTON_5, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_6, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_7, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_8, state.usButtonFlags);
// Get mouse wheel // Get mouse wheel
if ((state.usButtonFlags & RI_MOUSE_WHEEL)) if ((state.usButtonFlags & RI_MOUSE_WHEEL))
@ -556,6 +569,14 @@ void raw_mouse_handler::handle_native_event(const MSG& msg)
{ {
std::lock_guard lock(m_raw_mutex); std::lock_guard lock(m_raw_mutex);
if (g_cfg_raw_mouse.reload_requested.exchange(false))
{
for (auto& [handle, mouse] : m_raw_mice)
{
mouse.request_reload();
}
}
if (auto it = m_raw_mice.find(raw_input.header.hDevice); it != m_raw_mice.end()) if (auto it = m_raw_mice.find(raw_input.header.hDevice); it != m_raw_mice.end())
{ {
it->second.update_values(raw_input.data.mouse); it->second.update_values(raw_input.data.mouse);

View file

@ -43,8 +43,10 @@ public:
const std::string& device_name() const { return m_device_name; } const std::string& device_name() const { return m_device_name; }
u32 index() const { return m_index; } u32 index() const { return m_index; }
void set_index(u32 index) { m_index = index; } void set_index(u32 index) { m_index = index; }
void request_reload() { reload_requested = true; }
private: private:
void reload_config();
static std::pair<int, int> get_mouse_button(const cfg::string& button); static std::pair<int, int> get_mouse_button(const cfg::string& button);
u32 m_index = 0; u32 m_index = 0;
@ -60,6 +62,7 @@ private:
float m_mouse_acceleration = 1.0f; float m_mouse_acceleration = 1.0f;
raw_mouse_handler* m_handler{}; raw_mouse_handler* m_handler{};
std::map<u8, std::pair<int, int>> m_buttons; std::map<u8, std::pair<int, int>> m_buttons;
bool reload_requested = false;
}; };
class raw_mouse_handler final : public MouseHandlerBase class raw_mouse_handler final : public MouseHandlerBase

View file

@ -748,9 +748,9 @@ skylander_dialog* skylander_dialog::get_dlg(QWidget* parent)
void skylander_dialog::clear_skylander(u8 slot) void skylander_dialog::clear_skylander(u8 slot)
{ {
if (auto slot_infos = sky_slots[slot]) if (const auto& slot_infos = sky_slots[slot])
{ {
auto [cur_slot, id, var] = slot_infos.value(); const auto& [cur_slot, id, var] = slot_infos.value();
g_skyportal.remove_skylander(cur_slot); g_skyportal.remove_skylander(cur_slot);
sky_slots[slot] = {}; sky_slots[slot] = {};
update_edits(); update_edits();
@ -811,10 +811,10 @@ void skylander_dialog::update_edits()
for (auto i = 0; i < UI_SKY_NUM; i++) for (auto i = 0; i < UI_SKY_NUM; i++)
{ {
QString display_string; QString display_string;
if (auto sd = sky_slots[i]) if (const auto& sd = sky_slots[i])
{ {
auto [portal_slot, sky_id, sky_var] = sd.value(); const auto& [portal_slot, sky_id, sky_var] = sd.value();
auto found_sky = list_skylanders.find(std::make_pair(sky_id, sky_var)); const auto found_sky = list_skylanders.find(std::make_pair(sky_id, sky_var));
if (found_sky != list_skylanders.end()) if (found_sky != list_skylanders.end())
{ {
display_string = QString::fromStdString(found_sky->second); display_string = QString::fromStdString(found_sky->second);