Merge pull request #5233 from german77/inverted
InputCommon: Allow to invert analog axis with right click
This commit is contained in:
commit
7dbdda908c
4 changed files with 99 additions and 65 deletions
|
@ -139,10 +139,10 @@ void GCButtonFactory::EndConfiguration() {
|
||||||
|
|
||||||
class GCAnalog final : public Input::AnalogDevice {
|
class GCAnalog final : public Input::AnalogDevice {
|
||||||
public:
|
public:
|
||||||
explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_,
|
explicit GCAnalog(u32 port_, u32 axis_x_, u32 axis_y_, bool invert_x_, bool invert_y_,
|
||||||
const GCAdapter::Adapter* adapter, float range_)
|
float deadzone_, float range_, const GCAdapter::Adapter* adapter)
|
||||||
: port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter),
|
: port(port_), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), invert_y(invert_y_),
|
||||||
range(range_) {}
|
deadzone(deadzone_), range(range_), gcadapter(adapter) {}
|
||||||
|
|
||||||
float GetAxis(u32 axis) const {
|
float GetAxis(u32 axis) const {
|
||||||
if (gcadapter->DeviceConnected(port)) {
|
if (gcadapter->DeviceConnected(port)) {
|
||||||
|
@ -157,7 +157,12 @@ public:
|
||||||
std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
|
std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
|
||||||
float x = GetAxis(analog_axis_x);
|
float x = GetAxis(analog_axis_x);
|
||||||
float y = GetAxis(analog_axis_y);
|
float y = GetAxis(analog_axis_y);
|
||||||
|
if (invert_x) {
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
if (invert_y) {
|
||||||
|
y = -y;
|
||||||
|
}
|
||||||
// Make sure the coordinates are in the unit circle,
|
// Make sure the coordinates are in the unit circle,
|
||||||
// otherwise normalize it.
|
// otherwise normalize it.
|
||||||
float r = x * x + y * y;
|
float r = x * x + y * y;
|
||||||
|
@ -200,9 +205,11 @@ private:
|
||||||
const u32 port;
|
const u32 port;
|
||||||
const u32 axis_x;
|
const u32 axis_x;
|
||||||
const u32 axis_y;
|
const u32 axis_y;
|
||||||
|
const bool invert_x;
|
||||||
|
const bool invert_y;
|
||||||
const float deadzone;
|
const float deadzone;
|
||||||
const GCAdapter::Adapter* gcadapter;
|
|
||||||
const float range;
|
const float range;
|
||||||
|
const GCAdapter::Adapter* gcadapter;
|
||||||
mutable std::mutex mutex;
|
mutable std::mutex mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -223,8 +230,13 @@ std::unique_ptr<Input::AnalogDevice> GCAnalogFactory::Create(const Common::Param
|
||||||
const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
|
const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
|
||||||
const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
|
const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
|
||||||
const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
|
const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
|
||||||
|
const std::string invert_x_value = params.Get("invert_x", "+");
|
||||||
|
const std::string invert_y_value = params.Get("invert_y", "+");
|
||||||
|
const bool invert_x = invert_x_value == "-";
|
||||||
|
const bool invert_y = invert_y_value == "-";
|
||||||
|
|
||||||
return std::make_unique<GCAnalog>(port, axis_x, axis_y, deadzone, adapter.get(), range);
|
return std::make_unique<GCAnalog>(port, axis_x, axis_y, invert_x, invert_y, deadzone, range,
|
||||||
|
adapter.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCAnalogFactory::BeginConfiguration() {
|
void GCAnalogFactory::BeginConfiguration() {
|
||||||
|
@ -282,6 +294,8 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
|
||||||
params.Set("port", controller_number);
|
params.Set("port", controller_number);
|
||||||
params.Set("axis_x", analog_x_axis);
|
params.Set("axis_x", analog_x_axis);
|
||||||
params.Set("axis_y", analog_y_axis);
|
params.Set("axis_y", analog_y_axis);
|
||||||
|
params.Set("invert_x", "+");
|
||||||
|
params.Set("invert_y", "+");
|
||||||
analog_x_axis = -1;
|
analog_x_axis = -1;
|
||||||
analog_y_axis = -1;
|
analog_y_axis = -1;
|
||||||
controller_number = -1;
|
controller_number = -1;
|
||||||
|
|
|
@ -62,10 +62,10 @@ void MouseButtonFactory::EndConfiguration() {
|
||||||
|
|
||||||
class MouseAnalog final : public Input::AnalogDevice {
|
class MouseAnalog final : public Input::AnalogDevice {
|
||||||
public:
|
public:
|
||||||
explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, float deadzone_, float range_,
|
explicit MouseAnalog(u32 port_, u32 axis_x_, u32 axis_y_, bool invert_x_, bool invert_y_,
|
||||||
const MouseInput::Mouse* mouse_input_)
|
float deadzone_, float range_, const MouseInput::Mouse* mouse_input_)
|
||||||
: button(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), range(range_),
|
: button(port_), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_), invert_y(invert_y_),
|
||||||
mouse_input(mouse_input_) {}
|
deadzone(deadzone_), range(range_), mouse_input(mouse_input_) {}
|
||||||
|
|
||||||
float GetAxis(u32 axis) const {
|
float GetAxis(u32 axis) const {
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
|
@ -77,6 +77,12 @@ public:
|
||||||
std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
|
std::pair<float, float> GetAnalog(u32 analog_axis_x, u32 analog_axis_y) const {
|
||||||
float x = GetAxis(analog_axis_x);
|
float x = GetAxis(analog_axis_x);
|
||||||
float y = GetAxis(analog_axis_y);
|
float y = GetAxis(analog_axis_y);
|
||||||
|
if (invert_x) {
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
if (invert_y) {
|
||||||
|
y = -y;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the coordinates are in the unit circle,
|
// Make sure the coordinates are in the unit circle,
|
||||||
// otherwise normalize it.
|
// otherwise normalize it.
|
||||||
|
@ -104,6 +110,8 @@ private:
|
||||||
const u32 button;
|
const u32 button;
|
||||||
const u32 axis_x;
|
const u32 axis_x;
|
||||||
const u32 axis_y;
|
const u32 axis_y;
|
||||||
|
const bool invert_x;
|
||||||
|
const bool invert_y;
|
||||||
const float deadzone;
|
const float deadzone;
|
||||||
const float range;
|
const float range;
|
||||||
const MouseInput::Mouse* mouse_input;
|
const MouseInput::Mouse* mouse_input;
|
||||||
|
@ -128,8 +136,13 @@ std::unique_ptr<Input::AnalogDevice> MouseAnalogFactory::Create(
|
||||||
const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
|
const auto axis_y = static_cast<u32>(params.Get("axis_y", 1));
|
||||||
const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
|
const auto deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
|
||||||
const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
|
const auto range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
|
||||||
|
const std::string invert_x_value = params.Get("invert_x", "+");
|
||||||
|
const std::string invert_y_value = params.Get("invert_y", "+");
|
||||||
|
const bool invert_x = invert_x_value == "-";
|
||||||
|
const bool invert_y = invert_y_value == "-";
|
||||||
|
|
||||||
return std::make_unique<MouseAnalog>(port, axis_x, axis_y, deadzone, range, mouse_input.get());
|
return std::make_unique<MouseAnalog>(port, axis_x, axis_y, invert_x, invert_y, deadzone, range,
|
||||||
|
mouse_input.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MouseAnalogFactory::BeginConfiguration() {
|
void MouseAnalogFactory::BeginConfiguration() {
|
||||||
|
@ -153,6 +166,8 @@ Common::ParamPackage MouseAnalogFactory::GetNextInput() const {
|
||||||
params.Set("port", static_cast<u16>(pad.button));
|
params.Set("port", static_cast<u16>(pad.button));
|
||||||
params.Set("axis_x", 0);
|
params.Set("axis_x", 0);
|
||||||
params.Set("axis_y", 1);
|
params.Set("axis_y", 1);
|
||||||
|
params.Set("invert_x", "+");
|
||||||
|
params.Set("invert_y", "+");
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -352,13 +352,20 @@ private:
|
||||||
class SDLAnalog final : public Input::AnalogDevice {
|
class SDLAnalog final : public Input::AnalogDevice {
|
||||||
public:
|
public:
|
||||||
explicit SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_,
|
explicit SDLAnalog(std::shared_ptr<SDLJoystick> joystick_, int axis_x_, int axis_y_,
|
||||||
float deadzone_, float range_)
|
bool invert_x_, bool invert_y_, float deadzone_, float range_)
|
||||||
: joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_),
|
: joystick(std::move(joystick_)), axis_x(axis_x_), axis_y(axis_y_), invert_x(invert_x_),
|
||||||
range(range_) {}
|
invert_y(invert_y_), deadzone(deadzone_), range(range_) {}
|
||||||
|
|
||||||
std::tuple<float, float> GetStatus() const override {
|
std::tuple<float, float> GetStatus() const override {
|
||||||
const auto [x, y] = joystick->GetAnalog(axis_x, axis_y, range);
|
auto [x, y] = joystick->GetAnalog(axis_x, axis_y, range);
|
||||||
const float r = std::sqrt((x * x) + (y * y));
|
const float r = std::sqrt((x * x) + (y * y));
|
||||||
|
if (invert_x) {
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
if (invert_y) {
|
||||||
|
y = -y;
|
||||||
|
}
|
||||||
|
|
||||||
if (r > deadzone) {
|
if (r > deadzone) {
|
||||||
return std::make_tuple(x / r * (r - deadzone) / (1 - deadzone),
|
return std::make_tuple(x / r * (r - deadzone) / (1 - deadzone),
|
||||||
y / r * (r - deadzone) / (1 - deadzone));
|
y / r * (r - deadzone) / (1 - deadzone));
|
||||||
|
@ -386,6 +393,8 @@ private:
|
||||||
std::shared_ptr<SDLJoystick> joystick;
|
std::shared_ptr<SDLJoystick> joystick;
|
||||||
const int axis_x;
|
const int axis_x;
|
||||||
const int axis_y;
|
const int axis_y;
|
||||||
|
const bool invert_x;
|
||||||
|
const bool invert_y;
|
||||||
const float deadzone;
|
const float deadzone;
|
||||||
const float range;
|
const float range;
|
||||||
};
|
};
|
||||||
|
@ -572,12 +581,17 @@ public:
|
||||||
const int axis_y = params.Get("axis_y", 1);
|
const int axis_y = params.Get("axis_y", 1);
|
||||||
const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
|
const float deadzone = std::clamp(params.Get("deadzone", 0.0f), 0.0f, 1.0f);
|
||||||
const float range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
|
const float range = std::clamp(params.Get("range", 1.0f), 0.50f, 1.50f);
|
||||||
|
const std::string invert_x_value = params.Get("invert_x", "+");
|
||||||
|
const std::string invert_y_value = params.Get("invert_y", "+");
|
||||||
|
const bool invert_x = invert_x_value == "-";
|
||||||
|
const bool invert_y = invert_y_value == "-";
|
||||||
auto joystick = state.GetSDLJoystickByGUID(guid, port);
|
auto joystick = state.GetSDLJoystickByGUID(guid, port);
|
||||||
|
|
||||||
// This is necessary so accessing GetAxis with axis_x and axis_y won't crash
|
// This is necessary so accessing GetAxis with axis_x and axis_y won't crash
|
||||||
joystick->SetAxis(axis_x, 0);
|
joystick->SetAxis(axis_x, 0);
|
||||||
joystick->SetAxis(axis_y, 0);
|
joystick->SetAxis(axis_y, 0);
|
||||||
return std::make_unique<SDLAnalog>(joystick, axis_x, axis_y, deadzone, range);
|
return std::make_unique<SDLAnalog>(joystick, axis_x, axis_y, invert_x, invert_y, deadzone,
|
||||||
|
range);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -886,6 +900,8 @@ Common::ParamPackage BuildParamPackageForAnalog(int port, const std::string& gui
|
||||||
params.Set("guid", guid);
|
params.Set("guid", guid);
|
||||||
params.Set("axis_x", axis_x);
|
params.Set("axis_x", axis_x);
|
||||||
params.Set("axis_y", axis_y);
|
params.Set("axis_y", axis_y);
|
||||||
|
params.Set("invert_x", "+");
|
||||||
|
params.Set("invert_y", "+");
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
|
@ -173,61 +173,31 @@ QString AnalogToText(const Common::ParamPackage& param, const std::string& dir)
|
||||||
return ButtonToText(Common::ParamPackage{param.Get(dir, "")});
|
return ButtonToText(Common::ParamPackage{param.Get(dir, "")});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (param.Get("engine", "") == "sdl") {
|
const auto engine_str = param.Get("engine", "");
|
||||||
|
const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
|
||||||
|
const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
|
||||||
|
const bool invert_x = param.Get("invert_x", "+") == "-";
|
||||||
|
const bool invert_y = param.Get("invert_y", "+") == "-";
|
||||||
|
if (engine_str == "sdl" || engine_str == "gcpad" || engine_str == "mouse") {
|
||||||
if (dir == "modifier") {
|
if (dir == "modifier") {
|
||||||
return QObject::tr("[unused]");
|
return QObject::tr("[unused]");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dir == "left" || dir == "right") {
|
if (dir == "left") {
|
||||||
const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
|
const QString invert_x_str = QString::fromStdString(invert_x ? "+" : "-");
|
||||||
|
return QObject::tr("Axis %1%2").arg(axis_x_str, invert_x_str);
|
||||||
return QObject::tr("Axis %1").arg(axis_x_str);
|
|
||||||
}
|
}
|
||||||
|
if (dir == "right") {
|
||||||
if (dir == "up" || dir == "down") {
|
const QString invert_x_str = QString::fromStdString(invert_x ? "-" : "+");
|
||||||
const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
|
return QObject::tr("Axis %1%2").arg(axis_x_str, invert_x_str);
|
||||||
|
|
||||||
return QObject::tr("Axis %1").arg(axis_y_str);
|
|
||||||
}
|
}
|
||||||
|
if (dir == "up") {
|
||||||
return {};
|
const QString invert_y_str = QString::fromStdString(invert_y ? "-" : "+");
|
||||||
|
return QObject::tr("Axis %1%2").arg(axis_y_str, invert_y_str);
|
||||||
}
|
}
|
||||||
|
if (dir == "down") {
|
||||||
if (param.Get("engine", "") == "gcpad") {
|
const QString invert_y_str = QString::fromStdString(invert_y ? "+" : "-");
|
||||||
if (dir == "modifier") {
|
return QObject::tr("Axis %1%2").arg(axis_y_str, invert_y_str);
|
||||||
return QObject::tr("[unused]");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir == "left" || dir == "right") {
|
|
||||||
const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
|
|
||||||
|
|
||||||
return QObject::tr("GC Axis %1").arg(axis_x_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir == "up" || dir == "down") {
|
|
||||||
const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
|
|
||||||
|
|
||||||
return QObject::tr("GC Axis %1").arg(axis_y_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param.Get("engine", "") == "mouse") {
|
|
||||||
if (dir == "modifier") {
|
|
||||||
return QObject::tr("[unused]");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir == "left" || dir == "right") {
|
|
||||||
const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
|
|
||||||
|
|
||||||
return QObject::tr("Mouse %1").arg(axis_x_str);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dir == "up" || dir == "down") {
|
|
||||||
const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
|
|
||||||
|
|
||||||
return QObject::tr("Mouse %1").arg(axis_y_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
@ -396,6 +366,25 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
|
||||||
analogs_param[analog_id].Clear();
|
analogs_param[analog_id].Clear();
|
||||||
analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]"));
|
analog_map_buttons[analog_id][sub_button_id]->setText(tr("[not set]"));
|
||||||
});
|
});
|
||||||
|
context_menu.addAction(tr("Invert axis"), [&] {
|
||||||
|
if (sub_button_id == 2 || sub_button_id == 3) {
|
||||||
|
const bool invert_value =
|
||||||
|
analogs_param[analog_id].Get("invert_x", "+") == "-";
|
||||||
|
const std::string invert_str = invert_value ? "+" : "-";
|
||||||
|
analogs_param[analog_id].Set("invert_x", invert_str);
|
||||||
|
}
|
||||||
|
if (sub_button_id == 0 || sub_button_id == 1) {
|
||||||
|
const bool invert_value =
|
||||||
|
analogs_param[analog_id].Get("invert_y", "+") == "-";
|
||||||
|
const std::string invert_str = invert_value ? "+" : "-";
|
||||||
|
analogs_param[analog_id].Set("invert_y", invert_str);
|
||||||
|
}
|
||||||
|
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM;
|
||||||
|
++sub_button_id) {
|
||||||
|
analog_map_buttons[analog_id][sub_button_id]->setText(AnalogToText(
|
||||||
|
analogs_param[analog_id], analog_sub_buttons[sub_button_id]));
|
||||||
|
}
|
||||||
|
});
|
||||||
context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal(
|
context_menu.exec(analog_map_buttons[analog_id][sub_button_id]->mapToGlobal(
|
||||||
menu_location));
|
menu_location));
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue