implement mouse handler config

This commit is contained in:
Megamouse 2020-12-24 13:48:22 +01:00
parent 3ba4c8a1c7
commit eb8ab8ef15
29 changed files with 850 additions and 105 deletions

View File

@ -77,6 +77,7 @@ target_sources(rpcs3
Input/mm_joystick_handler.cpp
Input/pad_thread.cpp
Input/product_info.cpp
Input/raw_mouse_config.cpp
Input/raw_mouse_handler.cpp
Input/sdl_pad_handler.cpp
Input/skateboard_pad_handler.cpp

View File

@ -404,6 +404,7 @@ target_sources(rpcs3_emu PRIVATE
Io/interception.cpp
Io/KeyboardHandler.cpp
Io/midi_config_types.cpp
Io/mouse_config.cpp
Io/pad_config.cpp
Io/pad_config_types.cpp
Io/pad_types.cpp

View File

@ -864,8 +864,6 @@ static void ds3_input_to_ext(const u32 gem_num, const gem_config::gem_controller
/**
* \brief Maps Move controller data (digital buttons, and analog Trigger data) to mouse input.
* Move Button: Mouse1
* Trigger: Mouse2
* \param mouse_no Mouse index number to use
* \param digital_buttons Bitmask filled with CELL_GEM_CTRL_* values
* \param analog_t Analog value of Move's Trigger.

View File

@ -15,7 +15,7 @@ void fmt_class_string<guncon3_btn>::format(std::string& out, u64 arg)
format_enum(out, arg, [](guncon3_btn value)
{
switch (value)
{
{
case guncon3_btn::trigger: return "Trigger";
case guncon3_btn::a1: return "A1";
case guncon3_btn::a2: return "A2";

View File

@ -3,6 +3,7 @@
#include <list>
#include <algorithm>
#include <vector>
#include "Utilities/StrFmt.h"
#include "Utilities/mutex.h"
#include "util/init_mutex.hpp"
#include "Emu/system_config_types.h"
@ -49,6 +50,22 @@ enum
CELL_MOUSE_INFO_INTERCEPTED = 1
};
static inline MouseButtonCodes get_mouse_button_code(int i)
{
switch (i)
{
case 0: return CELL_MOUSE_BUTTON_1;
case 1: return CELL_MOUSE_BUTTON_2;
case 2: return CELL_MOUSE_BUTTON_3;
case 3: return CELL_MOUSE_BUTTON_4;
case 4: return CELL_MOUSE_BUTTON_5;
case 5: return CELL_MOUSE_BUTTON_6;
case 6: return CELL_MOUSE_BUTTON_7;
case 7: return CELL_MOUSE_BUTTON_8;
default: fmt::throw_exception("get_mouse_button_code: Invalid index %d", i);
}
}
static const u32 MAX_MICE = 127;
static const u32 MOUSE_MAX_DATA_LIST_NUM = 8;
static const u32 MOUSE_MAX_CODES = 64;
@ -191,7 +208,7 @@ public:
MouseData new_data;
new_data.update = CELL_MOUSE_DATA_UPDATE;
new_data.wheel = std::clamp(rotation / 120, -128, 127); //120=event.GetWheelDelta()
new_data.wheel = std::clamp(rotation / 120, -128, 127); // 120=event.GetWheelDelta()
new_data.buttons = mouse.buttons;
datalist.push_back(new_data);
@ -236,9 +253,9 @@ public:
mouse.x_pos = x_pos_new;
mouse.y_pos = y_pos_new;
/*CellMouseRawData& rawdata = GetRawData(p);
rawdata.data[rawdata.len % CELL_MOUSE_MAX_CODES] = 0; // (TODO)
rawdata.len++;*/
//CellMouseRawData& rawdata = GetRawData(p);
//rawdata.data[rawdata.len % CELL_MOUSE_MAX_CODES] = 0; // (TODO)
//rawdata.len++;
datalist.push_back(new_data);
}

View File

@ -0,0 +1,45 @@
#include "stdafx.h"
#include "mouse_config.h"
#include "MouseHandler.h"
#include "Utilities/File.h"
mouse_config::mouse_config()
: cfg_name(fs::get_config_dir() + "/config_mouse.yml")
{
}
bool mouse_config::exist() const
{
return fs::is_file(cfg_name);
}
bool mouse_config::load()
{
if (fs::file cfg_file{cfg_name, fs::read})
{
return from_string(cfg_file.to_string());
}
return false;
}
void mouse_config::save() const
{
fs::file(cfg_name, fs::rewrite).write(to_string());
}
cfg::string& mouse_config::get_button(int code)
{
switch (code)
{
case CELL_MOUSE_BUTTON_1: return mouse_button_1;
case CELL_MOUSE_BUTTON_2: return mouse_button_2;
case CELL_MOUSE_BUTTON_3: return mouse_button_3;
case CELL_MOUSE_BUTTON_4: return mouse_button_4;
case CELL_MOUSE_BUTTON_5: return mouse_button_5;
case CELL_MOUSE_BUTTON_6: return mouse_button_6;
case CELL_MOUSE_BUTTON_7: return mouse_button_7;
case CELL_MOUSE_BUTTON_8: return mouse_button_8;
default: fmt::throw_exception("Invalid code %d", code);
}
}

View File

@ -0,0 +1,28 @@
#pragma once
#include "Utilities/Config.h"
// For simplicity's sake, there is only one config instead of 127 for MAX_MICE
struct mouse_config final : cfg::node
{
mouse_config();
const std::string cfg_name;
cfg::string mouse_button_1{this, "Button 1", "LeftButton"};
cfg::string mouse_button_2{this, "Button 2", "RightButton"};
cfg::string mouse_button_3{this, "Button 3", "MiddleButton"};
cfg::string mouse_button_4{this, "Button 4", "NoButton"};
cfg::string mouse_button_5{this, "Button 5", "NoButton"};
cfg::string mouse_button_6{this, "Button 6", "NoButton"};
cfg::string mouse_button_7{this, "Button 7", "NoButton"};
cfg::string mouse_button_8{this, "Button 8", "NoButton"};
bool exist() const;
bool load();
void save() const;
cfg::string& get_button(int code);
};
extern mouse_config g_cfg_mouse;

View File

@ -7,9 +7,12 @@
#include "basic_mouse_handler.h"
#include "rpcs3qt/gs_frame.h"
#include "Emu/Io/interception.h"
#include "Emu/Io/mouse_config.h"
LOG_CHANNEL(input_log, "Input");
mouse_config g_cfg_mouse;
void basic_mouse_handler::Init(const u32 max_connect)
{
if (m_info.max_connect > 0)
@ -18,8 +21,21 @@ void basic_mouse_handler::Init(const u32 max_connect)
return;
}
g_cfg_mouse.from_default();
g_cfg_mouse.load();
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);
m_mice.clear();
m_mice.emplace_back(Mouse());
m_info = {};
m_info.max_connect = max_connect;
m_info.now_connect = std::min(::size32(m_mice), max_connect);
@ -88,28 +104,20 @@ bool basic_mouse_handler::eventFilter(QObject* target, QEvent* ev)
void basic_mouse_handler::MouseButtonDown(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_1, true);
else if (event->button() == Qt::RightButton) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_2, true);
else if (event->button() == Qt::MiddleButton) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_3, true);
// TODO: verify these
else if (event->button() == Qt::ExtraButton1) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_4, true);
else if (event->button() == Qt::ExtraButton2) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_5, true);
else if (event->button() == Qt::ExtraButton3) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_6, true);
else if (event->button() == Qt::ExtraButton4) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_7, true);
else if (event->button() == Qt::ExtraButton5) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_8, true);
if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [event](const auto& entry){ return entry.second == event->button(); });
it != m_buttons.cend())
{
MouseHandlerBase::Button(0, it->first, true);
}
}
void basic_mouse_handler::MouseButtonUp(QMouseEvent* event)
{
if (event->button() == Qt::LeftButton) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_1, false);
else if (event->button() == Qt::RightButton) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_2, false);
else if (event->button() == Qt::MiddleButton) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_3, false);
// TODO: verify these
else if (event->button() == Qt::ExtraButton1) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_4, false);
else if (event->button() == Qt::ExtraButton2) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_5, false);
else if (event->button() == Qt::ExtraButton3) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_6, false);
else if (event->button() == Qt::ExtraButton4) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_7, false);
else if (event->button() == Qt::ExtraButton5) MouseHandlerBase::Button(0, CELL_MOUSE_BUTTON_8, false);
if (const auto it = std::find_if(m_buttons.cbegin(), m_buttons.cend(), [event](const auto& entry){ return entry.second == event->button(); });
it != m_buttons.cend())
{
MouseHandlerBase::Button(0, it->first, false);
}
}
void basic_mouse_handler::MouseScroll(QWheelEvent* event)
@ -124,6 +132,18 @@ bool basic_mouse_handler::get_mouse_lock_state() const
return false;
}
Qt::MouseButton basic_mouse_handler::get_mouse_button(const cfg::string& button)
{
const std::string value = button.to_string();
if (const auto it = qt_mouse_button_map.find(value); it != qt_mouse_button_map.cend())
{
return it->second;
}
return Qt::MouseButton::NoButton;
}
void basic_mouse_handler::MouseMove(QMouseEvent* event)
{
if (is_time_for_update())

View File

@ -7,6 +7,43 @@
#include <QMouseEvent>
#include <QWheelEvent>
namespace cfg
{
class string;
}
static const std::map<std::string, Qt::MouseButton> qt_mouse_button_map
{
{ "NoButton", Qt::MouseButton::NoButton },
{ "LeftButton", Qt::MouseButton::LeftButton },
{ "RightButton", Qt::MouseButton::RightButton },
{ "MiddleButton", Qt::MouseButton::MiddleButton },
{ "BackButton", Qt::MouseButton::BackButton },
{ "ForwardButton", Qt::MouseButton::ForwardButton },
{ "TaskButton", Qt::MouseButton::TaskButton },
{ "ExtraButton4", Qt::MouseButton::ExtraButton4 },
{ "ExtraButton5", Qt::MouseButton::ExtraButton5 },
{ "ExtraButton6", Qt::MouseButton::ExtraButton6 },
{ "ExtraButton7", Qt::MouseButton::ExtraButton7 },
{ "ExtraButton8", Qt::MouseButton::ExtraButton8 },
{ "ExtraButton9", Qt::MouseButton::ExtraButton9 },
{ "ExtraButton10", Qt::MouseButton::ExtraButton10 },
{ "ExtraButton11", Qt::MouseButton::ExtraButton11 },
{ "ExtraButton12", Qt::MouseButton::ExtraButton12 },
{ "ExtraButton13", Qt::MouseButton::ExtraButton13 },
{ "ExtraButton14", Qt::MouseButton::ExtraButton14 },
{ "ExtraButton15", Qt::MouseButton::ExtraButton15 },
{ "ExtraButton16", Qt::MouseButton::ExtraButton16 },
{ "ExtraButton17", Qt::MouseButton::ExtraButton17 },
{ "ExtraButton18", Qt::MouseButton::ExtraButton18 },
{ "ExtraButton19", Qt::MouseButton::ExtraButton19 },
{ "ExtraButton20", Qt::MouseButton::ExtraButton20 },
{ "ExtraButton21", Qt::MouseButton::ExtraButton21 },
{ "ExtraButton22", Qt::MouseButton::ExtraButton22 },
{ "ExtraButton23", Qt::MouseButton::ExtraButton23 },
{ "ExtraButton24", Qt::MouseButton::ExtraButton24 }
};
class basic_mouse_handler final : public MouseHandlerBase, public QObject
{
using MouseHandlerBase::MouseHandlerBase;
@ -24,4 +61,7 @@ public:
private:
QWindow* m_target = nullptr;
bool get_mouse_lock_state() const;
static Qt::MouseButton get_mouse_button(const cfg::string& button);
std::map<u8, Qt::MouseButton> m_buttons;
};

View File

@ -0,0 +1,73 @@
#include "stdafx.h"
#include "raw_mouse_config.h"
#include "Emu/Io/MouseHandler.h"
cfg::string& raw_mouse_config::get_button(int code)
{
switch (code)
{
case CELL_MOUSE_BUTTON_1: return mouse_button_1;
case CELL_MOUSE_BUTTON_2: return mouse_button_2;
case CELL_MOUSE_BUTTON_3: return mouse_button_3;
case CELL_MOUSE_BUTTON_4: return mouse_button_4;
case CELL_MOUSE_BUTTON_5: return mouse_button_5;
case CELL_MOUSE_BUTTON_6: return mouse_button_6;
case CELL_MOUSE_BUTTON_7: return mouse_button_7;
case CELL_MOUSE_BUTTON_8: return mouse_button_8;
default: fmt::throw_exception("Invalid code %d", code);
}
}
raw_mice_config::raw_mice_config()
{
for (u32 i = 0; i < ::size32(players); i++)
{
players.at(i) = std::make_shared<raw_mouse_config>(this, fmt::format("Player %d", i + 1));
}
}
bool raw_mice_config::load()
{
m_mutex.lock();
bool result = false;
const std::string cfg_name = fmt::format("%sconfig/%s.yml", fs::get_config_dir(), cfg_id);
cfg_log.notice("Loading %s config: %s", cfg_id, cfg_name);
from_default();
if (fs::file cfg_file{ cfg_name, fs::read })
{
if (std::string content = cfg_file.to_string(); !content.empty())
{
result = from_string(content);
}
m_mutex.unlock();
}
else
{
m_mutex.unlock();
save();
}
return result;
}
void raw_mice_config::save()
{
std::lock_guard lock(m_mutex);
const std::string cfg_name = fmt::format("%sconfig/%s.yml", fs::get_config_dir(), cfg_id);
cfg_log.notice("Saving %s config to '%s'", cfg_id, cfg_name);
if (!fs::create_path(fs::get_parent_dir(cfg_name)))
{
cfg_log.fatal("Failed to create path: %s (%s)", cfg_name, fs::g_tls_error);
}
if (!cfg::node::save(cfg_name))
{
cfg_log.error("Failed to save %s config to '%s' (error=%s)", cfg_id, cfg_name, fs::g_tls_error);
}
}

View File

@ -13,67 +13,29 @@ public:
using cfg::node::node;
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_2{this, "Button 2", "Button 2"};
cfg::string mouse_button_3{this, "Button 3", "Button 3"};
cfg::string mouse_button_4{this, "Button 4", "Button 4"};
cfg::string mouse_button_5{this, "Button 5", "Button 5"};
cfg::string mouse_button_6{this, "Button 6", "No Button"};
cfg::string mouse_button_7{this, "Button 7", "No Button"};
cfg::string mouse_button_8{this, "Button 8", "No Button"};
cfg::string& get_button(int code);
};
struct raw_mice_config : cfg::node
{
raw_mice_config()
{
for (u32 i = 0; i < ::size32(players); i++)
{
players.at(i) = std::make_shared<raw_mouse_config>(this, fmt::format("Player %d", i + 1));
}
}
raw_mice_config();
shared_mutex m_mutex;
static constexpr std::string_view cfg_id = "raw_mouse";
std::array<std::shared_ptr<raw_mouse_config>, 4> players;
bool load()
{
m_mutex.lock();
bool result = false;
const std::string cfg_name = fmt::format("%sconfig/%s.yml", fs::get_config_dir(), cfg_id);
cfg_log.notice("Loading %s config: %s", cfg_id, cfg_name);
from_default();
if (fs::file cfg_file{ cfg_name, fs::read })
{
if (std::string content = cfg_file.to_string(); !content.empty())
{
result = from_string(content);
}
m_mutex.unlock();
}
else
{
m_mutex.unlock();
save();
}
return result;
}
void save()
{
std::lock_guard lock(m_mutex);
const std::string cfg_name = fmt::format("%sconfig/%s.yml", fs::get_config_dir(), cfg_id);
cfg_log.notice("Saving %s config to '%s'", cfg_id, cfg_name);
if (!fs::create_path(fs::get_parent_dir(cfg_name)))
{
cfg_log.fatal("Failed to create path: %s (%s)", cfg_name, fs::g_tls_error);
}
if (!cfg::node::save(cfg_name))
{
cfg_log.error("Failed to save %s config to '%s' (error=%s)", cfg_id, cfg_name, fs::g_tls_error);
}
}
bool load();
void save();
};
extern raw_mice_config g_cfg_raw_mouse;

View File

@ -38,6 +38,15 @@ raw_mouse::raw_mouse(u32 index, const std::string& device_name, void* handle, ra
if (const auto& player = ::at32(g_cfg_raw_mouse.players, m_index))
{
m_mouse_acceleration = static_cast<float>(player->mouse_acceleration.get()) / 100.0f;
m_buttons[CELL_MOUSE_BUTTON_1] = get_mouse_button(player->mouse_button_1);
m_buttons[CELL_MOUSE_BUTTON_2] = get_mouse_button(player->mouse_button_2);
m_buttons[CELL_MOUSE_BUTTON_3] = get_mouse_button(player->mouse_button_3);
m_buttons[CELL_MOUSE_BUTTON_4] = get_mouse_button(player->mouse_button_4);
m_buttons[CELL_MOUSE_BUTTON_5] = get_mouse_button(player->mouse_button_5);
m_buttons[CELL_MOUSE_BUTTON_6] = get_mouse_button(player->mouse_button_6);
m_buttons[CELL_MOUSE_BUTTON_7] = get_mouse_button(player->mouse_button_7);
m_buttons[CELL_MOUSE_BUTTON_8] = get_mouse_button(player->mouse_button_8);
}
}
}
@ -46,6 +55,29 @@ raw_mouse::~raw_mouse()
{
}
std::pair<int, int> raw_mouse::get_mouse_button(const cfg::string& button)
{
const std::string value = button.to_string();
#ifdef _WIN32
static const std::unordered_map<int, std::pair<int, int>> btn_pairs
{
{ RI_MOUSE_BUTTON_1_UP, { RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP }},
{ RI_MOUSE_BUTTON_2_UP, { RI_MOUSE_BUTTON_2_DOWN, RI_MOUSE_BUTTON_2_UP }},
{ RI_MOUSE_BUTTON_3_UP, { RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP }},
{ RI_MOUSE_BUTTON_4_UP, { RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP }},
{ RI_MOUSE_BUTTON_5_UP, { RI_MOUSE_BUTTON_5_DOWN, RI_MOUSE_BUTTON_5_UP }},
};
if (const auto it = raw_mouse_button_map.find(value); it != raw_mouse_button_map.cend())
{
return ::at32(btn_pairs, it->second);
}
#endif
return {};
}
void raw_mouse::update_window_handle()
{
#ifdef _WIN32
@ -89,8 +121,10 @@ void raw_mouse::update_values(const RAWMOUSE& state)
return;
}
const auto get_button_pressed = [this](u8 button, int button_flags, int down, int up)
const auto get_button_pressed = [this](u8 button, int button_flags)
{
const auto& [down, up] = ::at32(m_buttons, button);
// Only update the value if either down or up flags are present
if ((button_flags & down))
{
@ -103,11 +137,11 @@ void raw_mouse::update_values(const RAWMOUSE& state)
};
// Get mouse buttons
get_button_pressed(CELL_MOUSE_BUTTON_1, state.usButtonFlags, RI_MOUSE_BUTTON_1_DOWN, RI_MOUSE_BUTTON_1_UP);
get_button_pressed(CELL_MOUSE_BUTTON_2, state.usButtonFlags, RI_MOUSE_BUTTON_2_DOWN, RI_MOUSE_BUTTON_2_UP);
get_button_pressed(CELL_MOUSE_BUTTON_3, state.usButtonFlags, RI_MOUSE_BUTTON_3_DOWN, RI_MOUSE_BUTTON_3_UP);
get_button_pressed(CELL_MOUSE_BUTTON_4, state.usButtonFlags, RI_MOUSE_BUTTON_4_DOWN, RI_MOUSE_BUTTON_4_UP);
get_button_pressed(CELL_MOUSE_BUTTON_5, state.usButtonFlags, RI_MOUSE_BUTTON_5_DOWN, RI_MOUSE_BUTTON_5_UP);
get_button_pressed(CELL_MOUSE_BUTTON_1, state.usButtonFlags);
get_button_pressed(CELL_MOUSE_BUTTON_2, 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_5, state.usButtonFlags);
// Get vertical mouse wheel
if ((state.usButtonFlags & RI_MOUSE_WHEEL))

View File

@ -7,6 +7,18 @@
#include <windows.h>
#endif
static const std::map<std::string, int> raw_mouse_button_map
{
{ "No Button", 0 },
#ifdef _WIN32
{ "Button 1", RI_MOUSE_BUTTON_1_UP },
{ "Button 2", RI_MOUSE_BUTTON_2_UP },
{ "Button 3", RI_MOUSE_BUTTON_3_UP },
{ "Button 4", RI_MOUSE_BUTTON_4_UP },
{ "Button 5", RI_MOUSE_BUTTON_5_UP },
#endif
};
class raw_mouse_handler;
class raw_mouse
@ -26,6 +38,8 @@ public:
#endif
private:
static std::pair<int, int> get_mouse_button(const cfg::string& button);
u32 m_index = 0;
std::string m_device_name;
void* m_handle{};
@ -38,6 +52,7 @@ private:
int m_pos_y{};
float m_mouse_acceleration = 1.0f;
raw_mouse_handler* m_handler{};
std::map<u8, std::pair<int, int>> m_buttons;
};
class raw_mouse_handler final : public MouseHandlerBase

View File

@ -88,6 +88,7 @@
<ClCompile Include="Emu\Audio\AudioBackend.cpp" />
<ClCompile Include="Emu\Io\interception.cpp" />
<ClCompile Include="Emu\Io\KeyboardHandler.cpp" />
<ClCompile Include="Emu\Io\mouse_config.cpp" />
<ClCompile Include="Emu\Io\pad_config.cpp" />
<ClCompile Include="Emu\Io\pad_config_types.cpp" />
<ClCompile Include="Emu\IPC_config.cpp" />
@ -557,6 +558,7 @@
<ClInclude Include="Emu\Io\turntable_config.h" />
<ClInclude Include="Emu\Io\usio.h" />
<ClInclude Include="Emu\Io\interception.h" />
<ClInclude Include="Emu\Io\mouse_config.h" />
<ClInclude Include="Emu\Io\pad_types.h" />
<ClInclude Include="Emu\Io\Keyboard.h" />
<ClInclude Include="Emu\Io\pad_config.h" />
@ -663,7 +665,6 @@
<ClInclude Include="Emu\system_config.h" />
<ClInclude Include="Emu\system_config_types.h" />
<ClInclude Include="Emu\vfs_config.h" />
<ClInclude Include="Input\raw_mouse_config.h" />
<ClInclude Include="Loader\disc.h" />
<ClInclude Include="Loader\mself.hpp" />
<ClInclude Include="util\atomic.hpp" />

View File

@ -1249,6 +1249,9 @@
<ClCompile Include="Emu\RSX\NV47\FW\draw_call.cpp">
<Filter>Emu\GPU\RSX\NV47\FW</Filter>
</ClCompile>
<ClCompile Include="Emu\Io\mouse_config.cpp">
<Filter>Emu\Io</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Crypto\aes.h">
@ -2488,9 +2491,6 @@
<ClInclude Include="Emu\Io\rb3drums_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>
<ClInclude Include="Input\raw_mouse_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>
<ClInclude Include="Emu\RSX\Program\SPIRVCommon.h">
<Filter>Emu\GPU\RSX\Program</Filter>
</ClInclude>
@ -2542,6 +2542,9 @@
<ClInclude Include="Emu\RSX\NV47\FW\GRAPH_backend.h">
<Filter>Emu\GPU\RSX\NV47\FW</Filter>
</ClInclude>
<ClInclude Include="Emu\Io\mouse_config.h">
<Filter>Emu\Io</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="Emu\RSX\Program\GLSLSnippets\GPUDeswizzle.glsl">

View File

@ -179,6 +179,7 @@
<ClCompile Include="Input\evdev_gun_handler.cpp" />
<ClCompile Include="Input\gui_pad_thread.cpp" />
<ClCompile Include="Input\hid_pad_handler.cpp" />
<ClCompile Include="Input\raw_mouse_config.cpp" />
<ClCompile Include="Input\raw_mouse_handler.cpp" />
<ClCompile Include="Input\sdl_pad_handler.cpp" />
<ClCompile Include="Input\skateboard_pad_handler.cpp" />
@ -445,6 +446,12 @@
<ClCompile Include="QTGeneratedFiles\Debug\moc_welcome_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_basic_mouse_handler_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_raw_mouse_handler_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\qrc_resources.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</PrecompiledHeader>
@ -709,7 +716,14 @@
<ClCompile Include="QTGeneratedFiles\Release\moc_welcome_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_basic_mouse_settings_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_raw_mouse_settings_dialog.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="rpcs3qt\about_dialog.cpp" />
<ClCompile Include="rpcs3qt\basic_mouse_settings_dialog.cpp" />
<ClCompile Include="rpcs3qt\breakpoint_handler.cpp" />
<ClCompile Include="rpcs3qt\breakpoint_list.cpp" />
<ClCompile Include="rpcs3qt\call_stack_list.cpp" />
@ -754,6 +768,7 @@
<ClCompile Include="rpcs3qt\progress_indicator.cpp" />
<ClCompile Include="rpcs3qt\qt_camera_handler.cpp" />
<ClCompile Include="rpcs3qt\qt_music_handler.cpp" />
<ClCompile Include="rpcs3qt\raw_mouse_settings_dialog.cpp" />
<ClCompile Include="rpcs3qt\recvmessage_dialog_frame.cpp" />
<ClCompile Include="rpcs3qt\render_creator.cpp" />
<ClCompile Include="rpcs3qt\rpcn_settings_dialog.cpp" />
@ -931,6 +946,7 @@
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath);$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
</CustomBuild>
<ClInclude Include="Input\raw_mouse_config.h" />
<ClInclude Include="Input\raw_mouse_handler.h" />
<ClInclude Include="Input\sdl_pad_handler.h" />
<ClInclude Include="Input\skateboard_pad_handler.h" />
@ -1408,6 +1424,26 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg"</Command>
</CustomBuild>
<CustomBuild Include="rpcs3qt\basic_mouse_settings_dialog.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg"</Command>
</CustomBuild>
<CustomBuild Include="rpcs3qt\raw_mouse_settings_dialog.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing %(Identity)...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWIN32_LEAN_AND_MEAN -DHAVE_VULKAN -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -DQT_MULTIMEDIAWIDGETS_LIB -DQT_SVG_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\SoundTouch\soundtouch\include" "-I.\..\3rdparty\cubeb\extra" "-I.\..\3rdparty\cubeb\cubeb\include" "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" "-I$(QTDIR)\include\QtMultimediaWidgets" "-I$(QTDIR)\include\QtSvg"</Command>
</CustomBuild>
<ClInclude Include="rpcs3qt\richtext_item_delegate.h" />
<CustomBuild Include="rpcs3qt\sendmessage_dialog_frame.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
@ -1945,4 +1981,4 @@
<UserProperties MocDir=".\QTGeneratedFiles\$(ConfigurationName)" Qt5Version_x0020_x64="$(DefaultQtVersion)" RccDir=".\QTGeneratedFiles" UicDir=".\QTGeneratedFiles" />
</VisualStudio>
</ProjectExtensions>
</Project>
</Project>

View File

@ -285,6 +285,18 @@
<ClCompile Include="QTGeneratedFiles\Release\moc_welcome_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_basic_mouse_settings_dialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_basic_mouse_settings_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_raw_mouse_settings_dialog.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_raw_mouse_settings_dialog.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_game_list_grid.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
@ -1065,6 +1077,15 @@
<ClCompile Include="util\console.cpp">
<Filter>rpcs3</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\basic_mouse_settings_dialog.cpp">
<Filter>Gui\settings</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\raw_mouse_settings_dialog.cpp">
<Filter>Gui\settings</Filter>
</ClCompile>
<ClCompile Include="Input\raw_mouse_config.cpp">
<Filter>Io\raw</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Input\ds4_pad_handler.h">
@ -1247,6 +1268,15 @@
<ClInclude Include="util\console.h">
<Filter>rpcs3</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\basic_mouse_settings_dialog.h">
<Filter>Gui\settings</Filter>
</ClInclude>
<ClInclude Include="rpcs3qt\raw_mouse_settings_dialog.h">
<Filter>Gui\settings</Filter>
</ClInclude>
<ClInclude Include="Input\raw_mouse_config.h">
<Filter>Io\raw</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="debug\moc_predefs.h.cbt">
@ -1636,4 +1666,4 @@
<Filter>Scripts</Filter>
</None>
</ItemGroup>
</Project>
</Project>

View File

@ -1,6 +1,7 @@
add_library(rpcs3_ui STATIC
about_dialog.cpp
auto_pause_settings_dialog.cpp
basic_mouse_settings_dialog.cpp
breakpoint_handler.cpp
breakpoint_list.cpp
call_stack_list.cpp
@ -67,6 +68,7 @@ add_library(rpcs3_ui STATIC
qt_camera_video_sink.cpp
qt_music_handler.cpp
qt_utils.cpp
raw_mouse_settings_dialog.cpp
register_editor_dialog.cpp
recvmessage_dialog_frame.cpp
render_creator.cpp

View File

@ -0,0 +1,149 @@
#include "stdafx.h"
#include "basic_mouse_settings_dialog.h"
#include "localized_emu.h"
#include "Input/basic_mouse_handler.h"
#include "Emu/Io/mouse_config.h"
#include "Emu/Io/MouseHandler.h"
#include "util/asm.hpp"
#include <QDialogButtonBox>
#include <QGroupBox>
#include <QMessageBox>
#include <QPushButton>
#include <QVBoxLayout>
LOG_CHANNEL(cfg_log, "CFG");
enum button_role
{
button_name = Qt::UserRole,
button_code
};
basic_mouse_settings_dialog::basic_mouse_settings_dialog(QWidget* parent)
: QDialog(parent)
{
setObjectName("basic_mouse_settings_dialog");
setWindowTitle(tr("Configure Basic Mouse Handler"));
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_StyledBackground);
setModal(true);
QVBoxLayout* v_layout = new QVBoxLayout(this);
QDialogButtonBox* buttons = new QDialogButtonBox(this);
buttons->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Cancel | QDialogButtonBox::Save | QDialogButtonBox::RestoreDefaults);
connect(buttons, &QDialogButtonBox::clicked, this, [this, buttons](QAbstractButton* button)
{
if (button == buttons->button(QDialogButtonBox::Apply))
{
g_cfg_mouse.save();
}
else if (button == buttons->button(QDialogButtonBox::Save))
{
g_cfg_mouse.save();
accept();
}
else if (button == buttons->button(QDialogButtonBox::RestoreDefaults))
{
if (QMessageBox::question(this, tr("Confirm Reset"), tr("Reset all settings?")) != QMessageBox::Yes)
return;
reset_config();
}
else if (button == buttons->button(QDialogButtonBox::Cancel))
{
reject();
}
});
if (!g_cfg_mouse.load())
{
cfg_log.notice("Could not load basic mouse config. Using defaults.");
}
constexpr u32 button_count = 8;
constexpr u32 max_items_per_column = 4;
int rows = button_count;
for (u32 cols = 1; utils::aligned_div(button_count, cols) > max_items_per_column;)
{
rows = utils::aligned_div(button_count, ++cols);
}
QWidget* widget = new QWidget(this);
QGridLayout* grid_layout = new QGridLayout(this);
for (int i = 0, row = 0, col = 0; i < static_cast<int>(button_count); i++, row++)
{
const int cell_code = get_mouse_button_code(i);
const QString translated_cell_button = localized_emu::translated_mouse_button(cell_code);
QHBoxLayout* h_layout = new QHBoxLayout(this);
QGroupBox* gb = new QGroupBox(translated_cell_button, this);
QComboBox* combo = new QComboBox;
for (const auto& [name, btn] : qt_mouse_button_map)
{
const QString id = QString::fromStdString(name);
const QString translated_id = id; // We could localize the id, but I am too lazy at the moment
combo->addItem(translated_id);
const int index = combo->findText(translated_id);
combo->setItemData(index, id, button_role::button_name);
combo->setItemData(index, cell_code, button_role::button_code);
}
const std::string saved_btn = g_cfg_mouse.get_button(cell_code);
combo->setCurrentIndex(combo->findData(QString::fromStdString(saved_btn), button_role::button_name));
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this, cell_code, combo](int index)
{
if (index < 0 || !combo)
return;
const QVariant data = combo->itemData(index, button_role::button_name);
if (!data.isValid() || !data.canConvert<QString>())
return;
g_cfg_mouse.get_button(cell_code).from_string(data.toString().toStdString());
});
if (row >= rows)
{
row = 0;
col++;
}
m_combos.push_back(combo);
h_layout->addWidget(combo);
gb->setLayout(h_layout);
grid_layout->addWidget(gb, row, col);
}
widget->setLayout(grid_layout);
v_layout->addWidget(widget);
v_layout->addWidget(buttons);
setLayout(v_layout);
}
void basic_mouse_settings_dialog::reset_config()
{
g_cfg_mouse.from_default();
for (QComboBox* combo : m_combos)
{
if (!combo)
continue;
const QVariant data = combo->itemData(0, button_role::button_code);
if (!data.isValid() || !data.canConvert<int>())
continue;
const int cell_code = data.toInt();
const QString def_btn_id = QString::fromStdString(g_cfg_mouse.get_button(cell_code).def);
combo->setCurrentIndex(combo->findData(def_btn_id, button_role::button_name));
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#include <QComboBox>
#include <QDialog>
#include <vector>
class basic_mouse_settings_dialog : public QDialog
{
Q_OBJECT
public:
basic_mouse_settings_dialog(QWidget* parent = nullptr);
private:
void reset_config();
std::vector<QComboBox*> m_combos;
};

View File

@ -34,7 +34,7 @@ emulated_pad_settings_dialog::emulated_pad_settings_dialog(pad_type type, QWidge
QTabWidget* tabs = new QTabWidget();
tabs->setUsesScrollButtons(false);
QDialogButtonBox* buttons =new QDialogButtonBox(this);
QDialogButtonBox* buttons = new QDialogButtonBox(this);
buttons->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Cancel | QDialogButtonBox::Save | QDialogButtonBox::RestoreDefaults);
connect(buttons, &QDialogButtonBox::clicked, this, [this, buttons](QAbstractButton* button)

View File

@ -1,5 +1,6 @@
#include "stdafx.h"
#include "localized_emu.h"
#include "Emu/Io/MouseHandler.h"
QString localized_emu::translated_pad_button(pad_button btn)
{
@ -38,3 +39,19 @@ QString localized_emu::translated_pad_button(pad_button btn)
}
return "";
}
QString localized_emu::translated_mouse_button(int btn)
{
switch (btn)
{
case CELL_MOUSE_BUTTON_1: return tr("Button 1");
case CELL_MOUSE_BUTTON_2: return tr("Button 2");
case CELL_MOUSE_BUTTON_3: return tr("Button 3");
case CELL_MOUSE_BUTTON_4: return tr("Button 4");
case CELL_MOUSE_BUTTON_5: return tr("Button 5");
case CELL_MOUSE_BUTTON_6: return tr("Button 6");
case CELL_MOUSE_BUTTON_7: return tr("Button 7");
case CELL_MOUSE_BUTTON_8: return tr("Button 8");
}
return "";
}

View File

@ -18,6 +18,7 @@ public:
localized_emu() = default;
static QString translated_pad_button(pad_button btn);
static QString translated_mouse_button(int btn);
template <typename... Args>
static std::string get_string(localized_string_id id, Args&&... args)

View File

@ -35,6 +35,8 @@
#include "shortcut_dialog.h"
#include "system_cmd_dialog.h"
#include "emulated_pad_settings_dialog.h"
#include "basic_mouse_settings_dialog.h"
#include "raw_mouse_settings_dialog.h"
#include "welcome_dialog.h"
#include <thread>
@ -2757,6 +2759,22 @@ void main_window::CreateConnects()
dlg->show();
});
connect(ui->actionBasic_Mouse, &QAction::triggered, this, [this]
{
basic_mouse_settings_dialog* dlg = new basic_mouse_settings_dialog(this);
dlg->show();
});
#ifndef _WIN32
ui->actionRaw_Mouse->setVisible(false);
#else
connect(ui->actionRaw_Mouse, &QAction::triggered, this, [this]
{
raw_mouse_settings_dialog* dlg = new raw_mouse_settings_dialog(this);
dlg->show();
});
#endif
connect(ui->confCamerasAct, &QAction::triggered, this, [this]()
{
camera_settings_dialog dlg(this);

View File

@ -242,10 +242,18 @@
<addaction name="confPSMoveDS3Act"/>
<addaction name="confGunCon3Act"/>
</widget>
<widget class="QMenu" name="menuMice">
<property name="title">
<string>Mice</string>
</property>
<addaction name="actionBasic_Mouse"/>
<addaction name="actionRaw_Mouse"/>
</widget>
<addaction name="confCPUAct"/>
<addaction name="confGPUAct"/>
<addaction name="separator"/>
<addaction name="confPadsAct"/>
<addaction name="menuMice"/>
<addaction name="menuEmulatedPads"/>
<addaction name="confCamerasAct"/>
<addaction name="confAudioAct"/>
@ -1195,7 +1203,7 @@
<string>Create Savestate</string>
</property>
</action>
<action name="actionCreate_Savestate_And_Exit">
<action name="actionCreate_Savestate_And_Exit">
<property name="enabled">
<bool>false</bool>
</property>
@ -1330,6 +1338,16 @@
<string>GunCon 3</string>
</property>
</action>
<action name="actionBasic_Mouse">
<property name="text">
<string>Basic Mouse</string>
</property>
</action>
<action name="actionRaw_Mouse">
<property name="text">
<string>Raw Mouse</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>

View File

@ -322,7 +322,10 @@ void pad_settings_dialog::InitButtons()
ReactivateButtons();
return;
}
m_pad_buttons->button(m_button_id)->setText(tr("[ Waiting %1 ]").arg(m_seconds));
if (auto button = m_pad_buttons->button(m_button_id))
{
button->setText(tr("[ Waiting %1 ]").arg(m_seconds));
}
});
connect(ui->chb_vibration_large, &QCheckBox::clicked, this, [this](bool checked)
@ -731,10 +734,10 @@ void pad_settings_dialog::ReactivateButtons()
return;
}
if (m_pad_buttons->button(m_button_id))
if (auto button = m_pad_buttons->button(m_button_id))
{
m_pad_buttons->button(m_button_id)->setPalette(m_palette);
m_pad_buttons->button(m_button_id)->releaseMouse();
button->setPalette(m_palette);
button->releaseMouse();
}
m_button_id = button_ids::id_pad_begin;
@ -1209,7 +1212,10 @@ void pad_settings_dialog::UpdateLabels(bool is_reset)
}
// The button has to contain at least one character, because it would be square'ish otherwise
m_pad_buttons->button(id)->setText(button.text.isEmpty() ? QStringLiteral("-") : button.text);
if (auto btn = m_pad_buttons->button(id))
{
btn->setText(button.text.isEmpty() ? QStringLiteral("-") : button.text);
}
}
}
@ -1243,7 +1249,10 @@ void pad_settings_dialog::SwitchButtons(bool is_enabled)
for (int i = button_ids::id_pad_begin + 1; i < button_ids::id_pad_end; i++)
{
m_pad_buttons->button(i)->setEnabled(is_enabled);
if (auto button = m_pad_buttons->button(i))
{
button->setEnabled(is_enabled);
}
}
}
@ -1256,8 +1265,6 @@ void pad_settings_dialog::OnPadButtonClicked(int id)
case button_ids::id_pad_end:
case button_ids::id_add_config_file:
case button_ids::id_refresh:
case button_ids::id_ok:
case button_ids::id_cancel:
return;
case button_ids::id_reset_parameters:
ReactivateButtons();
@ -1302,9 +1309,12 @@ void pad_settings_dialog::OnPadButtonClicked(int id)
m_last_pos = QCursor::pos();
m_button_id = id;
m_pad_buttons->button(m_button_id)->setText(tr("[ Waiting %1 ]").arg(MAX_SECONDS));
m_pad_buttons->button(m_button_id)->setPalette(QPalette(Qt::blue));
m_pad_buttons->button(m_button_id)->grabMouse();
if (auto button = m_pad_buttons->button(m_button_id))
{
button->setText(tr("[ Waiting %1 ]").arg(MAX_SECONDS));
button->setPalette(QPalette(Qt::blue));
button->grabMouse();
}
SwitchButtons(false); // disable all buttons, needed for using Space, Enter and other specific buttons
m_remap_timer.start(1000);
}

View File

@ -72,9 +72,7 @@ class pad_settings_dialog : public QDialog
id_reset_parameters,
id_blacklist,
id_refresh,
id_add_config_file,
id_ok,
id_cancel
id_add_config_file
};
struct pad_button

View File

@ -0,0 +1,187 @@
#include "stdafx.h"
#include "raw_mouse_settings_dialog.h"
#include "localized_emu.h"
#include "Input/raw_mouse_config.h"
#include "Input/raw_mouse_handler.h"
#include "util/asm.hpp"
#include <QDialogButtonBox>
#include <QDoubleSpinBox>
#include <QGroupBox>
#include <QMessageBox>
#include <QPushButton>
#include <QVBoxLayout>
enum button_role
{
button_name = Qt::UserRole,
button_code
};
raw_mouse_settings_dialog::raw_mouse_settings_dialog(QWidget* parent)
: QDialog(parent)
{
setObjectName("raw_mouse_settings_dialog");
setWindowTitle(tr("Configure Raw Mouse Handler"));
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_StyledBackground);
setModal(true);
QVBoxLayout* v_layout = new QVBoxLayout(this);
QTabWidget* tabs = new QTabWidget();
tabs->setUsesScrollButtons(false);
QDialogButtonBox* buttons = new QDialogButtonBox(this);
buttons->setStandardButtons(QDialogButtonBox::Apply | QDialogButtonBox::Cancel | QDialogButtonBox::Save | QDialogButtonBox::RestoreDefaults);
connect(buttons, &QDialogButtonBox::clicked, this, [this, buttons](QAbstractButton* button)
{
if (button == buttons->button(QDialogButtonBox::Apply))
{
g_cfg_raw_mouse.save();
}
else if (button == buttons->button(QDialogButtonBox::Save))
{
g_cfg_raw_mouse.save();
accept();
}
else if (button == buttons->button(QDialogButtonBox::RestoreDefaults))
{
if (QMessageBox::question(this, tr("Confirm Reset"), tr("Reset settings of all players?")) != QMessageBox::Yes)
return;
reset_config();
}
else if (button == buttons->button(QDialogButtonBox::Cancel))
{
reject();
}
});
if (!g_cfg_raw_mouse.load())
{
cfg_log.notice("Could not load raw mouse config. Using defaults.");
}
add_tabs(tabs);
v_layout->addWidget(tabs);
v_layout->addWidget(buttons);
setLayout(v_layout);
}
void raw_mouse_settings_dialog::add_tabs(QTabWidget* tabs)
{
ensure(!!tabs);
constexpr u32 button_count = 8;
constexpr u32 max_items_per_column = 6;
int rows = button_count;
for (u32 cols = 1; utils::aligned_div(button_count, cols) > max_items_per_column;)
{
rows = utils::aligned_div(button_count, ++cols);
}
const usz players = g_cfg_raw_mouse.players.size();
m_combos.resize(players);
for (usz player = 0; player < players; player++)
{
QWidget* widget = new QWidget(this);
QGridLayout* grid_layout = new QGridLayout(this);
auto& config = ::at32(g_cfg_raw_mouse.players, player);
for (int i = 0, row = 0, col = 0; i < static_cast<int>(button_count); i++, row++)
{
const int cell_code = get_mouse_button_code(i);
const QString translated_cell_button = localized_emu::translated_mouse_button(cell_code);
QHBoxLayout* h_layout = new QHBoxLayout(this);
QGroupBox* gb = new QGroupBox(translated_cell_button, this);
QComboBox* combo = new QComboBox;
for (const auto& [name, btn] : raw_mouse_button_map)
{
const QString id = QString::fromStdString(name);
const QString translated_id = id; // We could localize the id, but I am too lazy at the moment
combo->addItem(translated_id);
const int index = combo->findText(translated_id);
combo->setItemData(index, id, button_role::button_name);
combo->setItemData(index, cell_code, button_role::button_code);
}
const std::string saved_btn = config->get_button(cell_code);
combo->setCurrentIndex(combo->findData(QString::fromStdString(saved_btn), button_role::button_name));
connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [this, player, cell_code, combo](int index)
{
if (index < 0 || !combo)
return;
const QVariant data = combo->itemData(index, button_role::button_name);
if (!data.isValid() || !data.canConvert<QString>())
return;
::at32(g_cfg_raw_mouse.players, player)->get_button(cell_code).from_string(data.toString().toStdString());
});
if (row >= rows)
{
row = 0;
col++;
}
::at32(m_combos, player).push_back(combo);
h_layout->addWidget(combo);
gb->setLayout(h_layout);
grid_layout->addWidget(gb, row, col);
}
QHBoxLayout* h_layout = new QHBoxLayout(this);
QGroupBox* gb = new QGroupBox(tr("Mouse Acceleration"), this);
QDoubleSpinBox* mouse_acceleration_spin_box = new QDoubleSpinBox(this);
mouse_acceleration_spin_box->setRange(0.1, 10.0);
mouse_acceleration_spin_box->setValue(config->mouse_acceleration.get() / 100.0);
connect(mouse_acceleration_spin_box, QOverload<double>::of(&QDoubleSpinBox::valueChanged), this, [player](double value)
{
auto& config = ::at32(g_cfg_raw_mouse.players, player)->mouse_acceleration;
config.set(std::clamp(value * 100.0, config.min, config.max));
});
h_layout->addWidget(mouse_acceleration_spin_box);
gb->setLayout(h_layout);
grid_layout->addWidget(gb, grid_layout->rowCount(), 0);
widget->setLayout(grid_layout);
tabs->addTab(widget, tr("Player %0").arg(player + 1));
}
}
void raw_mouse_settings_dialog::reset_config()
{
g_cfg_raw_mouse.from_default();
for (usz player = 0; player < m_combos.size(); player++)
{
auto& config = ::at32(g_cfg_raw_mouse.players, player);
for (QComboBox* combo : m_combos.at(player))
{
if (!combo)
continue;
const QVariant data = combo->itemData(0, button_role::button_code);
if (!data.isValid() || !data.canConvert<int>())
continue;
const int cell_code = data.toInt();
const QString def_btn_id = QString::fromStdString(config->get_button(cell_code).def);
combo->setCurrentIndex(combo->findData(def_btn_id, button_role::button_name));
}
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include <QComboBox>
#include <QDialog>
#include <QTabWidget>
#include <vector>
class raw_mouse_settings_dialog : public QDialog
{
Q_OBJECT
public:
raw_mouse_settings_dialog(QWidget* parent = nullptr);
private:
void add_tabs(QTabWidget* tabs);
void reset_config();
std::vector<std::vector<QComboBox*>> m_combos;
};