input: add absolute mouse movement mode

This commit is contained in:
Megamouse 2022-05-05 16:23:30 +02:00
parent d1e468fefb
commit 2706486559
8 changed files with 100 additions and 4 deletions

View File

@ -66,6 +66,7 @@ struct cfg_pad final : cfg::node
cfg::_bool enable_vibration_motor_small{ this, "Enable Small Vibration Motor", true };
cfg::_bool switch_vibration_motors{ this, "Switch Vibration Motors", false };
cfg::_enum<mouse_movement_mode> mouse_move_mode{ this, "Mouse Movement Mode", mouse_movement_mode::relative };
cfg::uint<0, 255> mouse_deadzone_x{ this, "Mouse Deadzone X Axis", 60 };
cfg::uint<0, 255> mouse_deadzone_y{ this, "Mouse Deadzone Y Axis", 60 };
cfg::uint<0, 999999> mouse_acceleration_x{ this, "Mouse Acceleration X Axis", 200 };

View File

@ -25,3 +25,18 @@ void fmt_class_string<pad_handler>::format(std::string& out, u64 arg)
return unknown;
});
}
template <>
void fmt_class_string<mouse_movement_mode>::format(std::string& out, u64 arg)
{
format_enum(out, arg, [](mouse_movement_mode value)
{
switch (value)
{
case mouse_movement_mode::relative: return "Relative";
case mouse_movement_mode::absolute: return "Absolute";
}
return unknown;
});
}

View File

@ -18,6 +18,12 @@ enum class pad_handler
#endif
};
enum class mouse_movement_mode : s32
{
relative = 0,
absolute = 1
};
struct PadInfo
{
u32 now_connect;

View File

@ -415,10 +415,28 @@ void keyboard_pad_handler::mouseMoveEvent(QMouseEvent* event)
// get the delta of the mouse position to the screen center
const QPoint p_delta = event->pos() - p_center;
movement_x = p_delta.x();
movement_y = p_delta.y();
if (m_mouse_movement_mode == mouse_movement_mode::relative)
{
movement_x = p_delta.x();
movement_y = p_delta.y();
}
else
{
// current mouse position, starting at the center
static QPoint p_real(p_center);
// update the current position without leaving the screen borders
p_real.setX(std::clamp(p_real.x() + p_delta.x(), 0, screen.width()));
p_real.setY(std::clamp(p_real.y() + p_delta.y(), 0, screen.height()));
// get the delta of the real mouse position to the screen center
const QPoint p_real_delta = p_real - p_center;
movement_x = p_real_delta.x();
movement_y = p_real_delta.y();
}
}
else
else if (m_mouse_movement_mode == mouse_movement_mode::relative)
{
static int last_pos_x = 0;
static int last_pos_y = 0;
@ -429,6 +447,23 @@ void keyboard_pad_handler::mouseMoveEvent(QMouseEvent* event)
last_pos_x = event->x();
last_pos_y = event->y();
}
else if (m_target && m_target->isActive())
{
// get the screen dimensions
const QSize screen = m_target->size();
// get the center of the screen in global coordinates
QPoint p_center = m_target->geometry().topLeft() + QPoint(screen.width() / 2, screen.height() / 2);
// convert the center into screen coordinates
p_center = m_target->mapFromGlobal(p_center);
// get the delta of the mouse position to the screen center
const QPoint p_delta = event->pos() - p_center;
movement_x = p_delta.x();
movement_y = p_delta.y();
}
movement_x *= m_multi_x;
movement_y *= m_multi_y;
@ -759,6 +794,7 @@ bool keyboard_pad_handler::bindPadToDevice(std::shared_ptr<Pad> pad, const std::
if (cfg == nullptr)
return false;
m_mouse_movement_mode = cfg->mouse_move_mode;
m_mouse_move_used = false;
m_mouse_wheel_used = false;
m_deadzone_x = cfg->mouse_deadzone_x;
@ -872,7 +908,7 @@ void keyboard_pad_handler::ThreadProc()
m_button_time = now;
}
if (m_mouse_move_used)
if (m_mouse_move_used && m_mouse_movement_mode == mouse_movement_mode::relative)
{
static const double mouse_interval = 30.0;

View File

@ -104,6 +104,7 @@ protected:
private:
QWindow* m_target = nullptr;
mouse_movement_mode m_mouse_movement_mode = mouse_movement_mode::relative;
bool m_mouse_move_used = false;
bool m_mouse_wheel_used = false;
bool get_mouse_lock_state() const;

View File

@ -177,6 +177,9 @@ pad_settings_dialog::pad_settings_dialog(std::shared_ptr<gui_settings> gui_setti
RepaintPreviewLabel(ui->preview_stick_right, ui->slider_stick_right->value(), ui->slider_stick_right->size().width(), m_rx, m_ry, cfg.rpadsquircling, cfg.rstickmultiplier / 100.0);
});
ui->mouse_movement->addItem(tr("Relative"), static_cast<int>(mouse_movement_mode::relative));
ui->mouse_movement->addItem(tr("Absolute"), static_cast<int>(mouse_movement_mode::absolute));
// Initialize configurable buttons
InitButtons();
@ -947,6 +950,11 @@ void pad_settings_dialog::UpdateLabels(bool is_reset)
std::vector<std::string> range;
// Update Mouse Movement Mode
const int mouse_movement_index = ui->mouse_movement->findData(static_cast<int>(cfg.mouse_move_mode.get()));
ensure(mouse_movement_index >= 0);
ui->mouse_movement->setCurrentIndex(mouse_movement_index);
// Update Mouse Deadzones
range = cfg.mouse_deadzone_x.to_list();
ui->mouse_dz_x->setRange(std::stoi(range.front()), std::stoi(range.back()));
@ -1608,6 +1616,9 @@ void pad_settings_dialog::ApplyCurrentPlayerConfig(int new_player_id)
if (m_handler->m_type == pad_handler::keyboard)
{
const int mouse_move_mode = ui->mouse_movement->currentData().toInt();
ensure(mouse_move_mode >= 0 && mouse_move_mode <= 1);
cfg.mouse_move_mode.set(static_cast<mouse_movement_mode>(mouse_move_mode));
cfg.mouse_acceleration_x.set(ui->mouse_accel_x->value() * 100);
cfg.mouse_acceleration_y.set(ui->mouse_accel_y->value() * 100);
cfg.mouse_deadzone_x.set(ui->mouse_dz_x->value());
@ -1757,4 +1768,5 @@ void pad_settings_dialog::SubscribeTooltips()
SubscribeTooltip(ui->gb_stick_lerp, tooltips.gamepad_settings.stick_lerp);
SubscribeTooltip(ui->gb_mouse_accel, tooltips.gamepad_settings.mouse_acceleration);
SubscribeTooltip(ui->gb_mouse_dz, tooltips.gamepad_settings.mouse_deadzones);
SubscribeTooltip(ui->gb_mouse_movement, tooltips.gamepad_settings.mouse_movement);
}

View File

@ -1026,6 +1026,30 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="gb_mouse_movement">
<property name="title">
<string>Mouse Movement Mode</string>
</property>
<layout class="QVBoxLayout" name="gb_mouse_movement_layout">
<property name="leftMargin">
<number>5</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<widget class="QComboBox" name="mouse_movement"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="mouse_page_spacer">
<property name="orientation">

View File

@ -257,6 +257,7 @@ public:
const QString stick_lerp = tr("With keyboards, you are inevitably restricted to 8 stick directions (4 straight + 4 diagonal). Furthermore, the stick will jump to the maximum value of the chosen direction immediately when a key is pressed. The stick interpolation can be used to work-around both of these issues by smoothening out these directional changes. The lower the value, the longer you have to press or release a key until the maximum amplitude is reached.");
const QString mouse_deadzones = tr("The mouse deadzones represent the games' own deadzones on the x and y axes. Games usually enforce their own deadzones to filter out small unwanted stick movements. In consequence, mouse input feels unintuitive since it relies on immediate responsiveness. You can change these values temporarily during gameplay in order to find out the optimal values for your game (Alt+T and Alt+Y for x, Alt+U and Alt+I for y).");
const QString mouse_acceleration = tr("The mouse acceleration can be used to amplify your mouse movements on the x and y axes. Increase these values if your mouse movements feel too slow while playing a game. You can change these values temporarily during gameplay in order to find out the optimal values (Alt+G and Alt+H for x, Alt+J and Alt+K for y). Keep in mind that modern mice usually provide different modes and settings that can be used to change mouse movement speeds as well.");
const QString mouse_movement = tr("The mouse movement mode determines how the mouse movement is translated to pad input.<br>Use the relative mode for traditional mouse movement.<br>Use the absolute mode to use the mouse's distance to the center of the screen as input value.");
} gamepad_settings;
};