diff --git a/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp b/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp index a7e88e3092..1648175360 100644 --- a/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/IOWindow.cpp @@ -278,6 +278,18 @@ void IOWindow::CreateMainLayout() m_functions_combo->addItem(QStringLiteral("tap")); m_functions_combo->addItem(QStringLiteral("relative")); m_functions_combo->addItem(QStringLiteral("pulse")); + m_functions_combo->addItem(QStringLiteral("sin")); + m_functions_combo->addItem(QStringLiteral("cos")); + m_functions_combo->addItem(QStringLiteral("tan")); + m_functions_combo->addItem(QStringLiteral("asin")); + m_functions_combo->addItem(QStringLiteral("acos")); + m_functions_combo->addItem(QStringLiteral("atan")); + m_functions_combo->addItem(QStringLiteral("atan2")); + m_functions_combo->addItem(QStringLiteral("sqrt")); + m_functions_combo->addItem(QStringLiteral("pow")); + m_functions_combo->addItem(QStringLiteral("min")); + m_functions_combo->addItem(QStringLiteral("max")); + m_functions_combo->addItem(QStringLiteral("clamp")); // Devices m_main_layout->addWidget(m_devices_combo); diff --git a/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp index 4d8e2866db..dbd75098bb 100644 --- a/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp +++ b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp @@ -86,6 +86,197 @@ private: ControlState GetValue() const override { return std::sin(GetArg(0).GetValue()); } }; +// usage: cos(expression) +class CosExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 1) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"expression"}; + } + + ControlState GetValue() const override { return std::cos(GetArg(0).GetValue()); } +}; + +// usage: tan(expression) +class TanExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 1) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"expression"}; + } + + ControlState GetValue() const override { return std::tan(GetArg(0).GetValue()); } +}; + +// usage: asin(expression) +class ASinExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 1) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"expression"}; + } + + ControlState GetValue() const override { return std::asin(GetArg(0).GetValue()); } +}; + +// usage: acos(expression) +class ACosExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 1) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"expression"}; + } + + ControlState GetValue() const override { return std::acos(GetArg(0).GetValue()); } +}; + +// usage: atan(expression) +class ATanExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 1) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"expression"}; + } + + ControlState GetValue() const override { return std::atan(GetArg(0).GetValue()); } +}; + +// usage: atan2(y, x) +class ATan2Expression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 2) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"y, x"}; + } + + ControlState GetValue() const override + { + return std::atan2(GetArg(0).GetValue(), GetArg(1).GetValue()); + } +}; + +// usage: sqrt(expression) +class SqrtExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 1) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"expression"}; + } + + ControlState GetValue() const override { return std::sqrt(GetArg(0).GetValue()); } +}; + +// usage: pow(base, exponent) +class PowExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 2) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"base, exponent"}; + } + + ControlState GetValue() const override + { + return std::pow(GetArg(0).GetValue(), GetArg(1).GetValue()); + } +}; + +// usage: min(a, b) +class MinExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 2) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"a, b"}; + } + + ControlState GetValue() const override + { + return std::min(GetArg(0).GetValue(), GetArg(1).GetValue()); + } +}; + +// usage: max(a, b) +class MaxExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 2) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"a, b"}; + } + + ControlState GetValue() const override + { + return std::max(GetArg(0).GetValue(), GetArg(1).GetValue()); + } +}; + +// usage: clamp(value, min, max) +class ClampExpression : public FunctionExpression +{ +private: + ArgumentValidation + ValidateArguments(const std::vector>& args) override + { + if (args.size() == 3) + return ArgumentsAreValid{}; + else + return ExpectedArguments{"value, min, max"}; + } + + ControlState GetValue() const override + { + return std::clamp(GetArg(0).GetValue(), GetArg(1).GetValue(), GetArg(2).GetValue()); + } +}; + // usage: timer(seconds) class TimerExpression : public FunctionExpression { @@ -453,6 +644,28 @@ std::unique_ptr MakeFunctionExpression(std::string_view name return std::make_unique(); if (name == "sin") return std::make_unique(); + if (name == "cos") + return std::make_unique(); + if (name == "tan") + return std::make_unique(); + if (name == "asin") + return std::make_unique(); + if (name == "acos") + return std::make_unique(); + if (name == "atan") + return std::make_unique(); + if (name == "atan2") + return std::make_unique(); + if (name == "sqrt") + return std::make_unique(); + if (name == "pow") + return std::make_unique(); + if (name == "min") + return std::make_unique(); + if (name == "max") + return std::make_unique(); + if (name == "clamp") + return std::make_unique(); if (name == "timer") return std::make_unique(); if (name == "toggle")