diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index c42c7aa649..0fc625ccc1 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" @@ -29,9 +30,7 @@ namespace MWInput const std::filesystem::path& userControllerBindingsFile, const std::filesystem::path& controllerBindingsFile) : mBindingsManager(bindingsManager) , mMouseManager(mouseManager) - , mJoystickEnabled(Settings::Manager::getBool("enable controller", "Input")) , mGyroAvailable(false) - , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) , mGamepadGuiCursorEnabled(true) , mGuiCursorEnabled(true) , mJoystickLastUsed(false) @@ -64,18 +63,7 @@ namespace MWInput } } - float deadZoneRadius = Settings::Manager::getFloat("joystick dead zone", "Input"); - deadZoneRadius = std::clamp(deadZoneRadius, 0.f, 0.5f); - mBindingsManager->setJoystickDeadZone(deadZoneRadius); - } - - void ControllerManager::processChangedSettings(const Settings::CategorySettingVector& changed) - { - for (const auto& setting : changed) - { - if (setting.first == "Input" && setting.second == "enable controller") - mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input"); - } + mBindingsManager->setJoystickDeadZone(Settings::input().mJoystickDeadZone); } void ControllerManager::update(float dt) @@ -92,8 +80,9 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor float uiScale = MWBase::Environment::get().getWindowManager()->getScalingFactor(); - float xMove = xAxis * dt * 1500.0f / uiScale * mGamepadCursorSpeed; - float yMove = yAxis * dt * 1500.0f / uiScale * mGamepadCursorSpeed; + const float gamepadCursorSpeed = Settings::input().mEnableController; + const float xMove = xAxis * dt * 1500.0f / uiScale * gamepadCursorSpeed; + const float yMove = yAxis * dt * 1500.0f / uiScale * gamepadCursorSpeed; float mouseWheelMove = -zAxis * dt * 1500.0f; if (xMove != 0 || yMove != 0 || mouseWheelMove != 0) @@ -120,7 +109,7 @@ namespace MWInput void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent& arg) { - if (!mJoystickEnabled || mBindingsManager->isDetectingBindingState()) + if (!Settings::input().mEnableController || mBindingsManager->isDetectingBindingState()) return; MWBase::Environment::get().getLuaManager()->inputEvent( @@ -170,13 +159,13 @@ namespace MWInput return; } - if (mJoystickEnabled) + if (Settings::input().mEnableController) { MWBase::Environment::get().getLuaManager()->inputEvent( { MWBase::LuaManager::InputEvent::ControllerReleased, arg.button }); } - if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled()) + if (!Settings::input().mEnableController || MWBase::Environment::get().getInputManager()->controlsDisabled()) return; mJoystickLastUsed = true; @@ -208,7 +197,7 @@ namespace MWInput void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent& arg) { - if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled()) + if (!Settings::input().mEnableController || MWBase::Environment::get().getInputManager()->controlsDisabled()) return; mJoystickLastUsed = true; diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index de959fc8cb..63bfc07169 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -33,8 +33,6 @@ namespace MWInput void touchpadPressed(int deviceId, const SDLUtil::TouchEvent& arg) override; void touchpadReleased(int deviceId, const SDLUtil::TouchEvent& arg) override; - void processChangedSettings(const Settings::CategorySettingVector& changed); - void setJoystickLastUsed(bool enabled) { mJoystickLastUsed = enabled; } bool joystickLastUsed() const { return mJoystickLastUsed; } @@ -59,9 +57,7 @@ namespace MWInput BindingsManager* mBindingsManager; MouseManager* mMouseManager; - bool mJoystickEnabled; bool mGyroAvailable; - float mGamepadCursorSpeed; bool mGamepadGuiCursorEnabled; bool mGuiCursorEnabled; bool mJoystickLastUsed; diff --git a/apps/openmw/mwinput/gyromanager.cpp b/apps/openmw/mwinput/gyromanager.cpp index 1ffa368729..01b3afdd89 100644 --- a/apps/openmw/mwinput/gyromanager.cpp +++ b/apps/openmw/mwinput/gyromanager.cpp @@ -5,98 +5,67 @@ #include "../mwbase/world.hpp" #include "../mwworld/player.hpp" +#include + namespace MWInput { - GyroManager::GyroscopeAxis GyroManager::gyroscopeAxisFromString(std::string_view s) - { - if (s == "x") - return GyroscopeAxis::X; - else if (s == "y") - return GyroscopeAxis::Y; - else if (s == "z") - return GyroscopeAxis::Z; - else if (s == "-x") - return GyroscopeAxis::Minus_X; - else if (s == "-y") - return GyroscopeAxis::Minus_Y; - else if (s == "-z") - return GyroscopeAxis::Minus_Z; - - return GyroscopeAxis::Unknown; - } - - GyroManager::GyroManager() - : mEnabled(Settings::Manager::getBool("enable gyroscope", "Input")) - , mGuiCursorEnabled(true) - , mSensitivityH(Settings::Manager::getFloat("gyro horizontal sensitivity", "Input")) - , mSensitivityV(Settings::Manager::getFloat("gyro vertical sensitivity", "Input")) - , mInputThreshold(Settings::Manager::getFloat("gyro input threshold", "Input")) - , mAxisH(gyroscopeAxisFromString(Settings::Manager::getString("gyro horizontal axis", "Input"))) - , mAxisV(gyroscopeAxisFromString(Settings::Manager::getString("gyro vertical axis", "Input"))) + namespace { + float getAxisValue(Settings::GyroscopeAxis axis, float threshold, std::array values) + { + const float value = [&] { + switch (axis) + { + case Settings::GyroscopeAxis::X: + return values[0]; + case Settings::GyroscopeAxis::Y: + return values[1]; + case Settings::GyroscopeAxis::Z: + return values[2]; + case Settings::GyroscopeAxis::MinusX: + return -values[0]; + case Settings::GyroscopeAxis::MinusY: + return -values[1]; + case Settings::GyroscopeAxis::MinusZ: + return -values[2]; + }; + return 0.0f; + }(); + if (std::abs(value) <= threshold) + return 0; + return value; + } } void GyroManager::update(float dt, std::array values) const { - if (!mGuiCursorEnabled) - { - float gyroH = getAxisValue(mAxisH, values); - float gyroV = getAxisValue(mAxisV, values); + if (mGuiCursorEnabled) + return; - if (gyroH == 0.f && gyroV == 0.f) - return; + const float threshold = Settings::input().mGyroInputThreshold; + const float gyroH = getAxisValue(Settings::input().mGyroHorizontalAxis, threshold, values); + const float gyroV = getAxisValue(Settings::input().mGyroVerticalAxis, threshold, values); - float rot[3]; - rot[0] = -gyroV * dt * mSensitivityV; - rot[1] = 0.0f; - rot[2] = -gyroH * dt * mSensitivityH; + if (gyroH == 0.f && gyroV == 0.f) + return; - // Only actually turn player when we're not in vanity mode - bool playerLooking = MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking"); - if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && playerLooking) - { - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - player.yaw(-rot[2]); - player.pitch(-rot[0]); - } - else if (!playerLooking) - MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation(); + const float rot[3] = { + -gyroV * dt * Settings::input().mGyroVerticalSensitivity, + 0.0f, + -gyroH * dt * Settings::input().mGyroHorizontalSensitivity, + }; - MWBase::Environment::get().getInputManager()->resetIdleTime(); - } - } - - void GyroManager::processChangedSettings(const Settings::CategorySettingVector& changed) - { - for (const auto& setting : changed) + // Only actually turn player when we're not in vanity mode + const bool playerLooking = MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking"); + if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && playerLooking) { - if (setting.first != "Input") - continue; - - if (setting.second == "enable gyroscope") - mEnabled = Settings::Manager::getBool("enable gyroscope", "Input"); - else if (setting.second == "gyro horizontal sensitivity") - mSensitivityH = Settings::Manager::getFloat("gyro horizontal sensitivity", "Input"); - else if (setting.second == "gyro vertical sensitivity") - mSensitivityV = Settings::Manager::getFloat("gyro vertical sensitivity", "Input"); - else if (setting.second == "gyro input threshold") - mInputThreshold = Settings::Manager::getFloat("gyro input threshold", "Input"); - else if (setting.second == "gyro horizontal axis") - mAxisH = gyroscopeAxisFromString(Settings::Manager::getString("gyro horizontal axis", "Input")); - else if (setting.second == "gyro vertical axis") - mAxisV = gyroscopeAxisFromString(Settings::Manager::getString("gyro vertical axis", "Input")); + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + player.yaw(-rot[2]); + player.pitch(-rot[0]); } - } + else if (!playerLooking) + MWBase::Environment::get().getWorld()->disableDeferredPreviewRotation(); - float GyroManager::getAxisValue(GyroscopeAxis axis, std::array values) const - { - if (axis == GyroscopeAxis::Unknown) - return 0; - float value = values[std::abs(axis) - 1]; - if (axis < 0) - value *= -1; - if (std::abs(value) <= mInputThreshold) - value = 0; - return value; + MWBase::Environment::get().getInputManager()->resetIdleTime(); } } diff --git a/apps/openmw/mwinput/gyromanager.hpp b/apps/openmw/mwinput/gyromanager.hpp index c9877945a6..f1064e6665 100644 --- a/apps/openmw/mwinput/gyromanager.hpp +++ b/apps/openmw/mwinput/gyromanager.hpp @@ -1,46 +1,19 @@ #ifndef MWINPUT_GYROMANAGER #define MWINPUT_GYROMANAGER -#include +#include namespace MWInput { class GyroManager { public: - GyroManager(); - - bool isEnabled() const { return mEnabled; } - void update(float dt, std::array values) const; - void processChangedSettings(const Settings::CategorySettingVector& changed); - void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } private: - enum GyroscopeAxis - { - Unknown = 0, - X = 1, - Y = 2, - Z = 3, - Minus_X = -1, - Minus_Y = -2, - Minus_Z = -3 - }; - - static GyroscopeAxis gyroscopeAxisFromString(std::string_view s); - - bool mEnabled; - bool mGuiCursorEnabled; - float mSensitivityH; - float mSensitivityV; - float mInputThreshold; - GyroscopeAxis mAxisH; - GyroscopeAxis mAxisV; - - float getAxisValue(GyroscopeAxis axis, std::array values) const; + bool mGuiCursorEnabled = true; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 560bed8548..f9ca0a3432 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/windowmanager.hpp" @@ -79,7 +80,7 @@ namespace MWInput mSensorManager->update(dt); mActionManager->update(dt); - if (mGyroManager->isEnabled()) + if (Settings::input().mEnableGyroscope) { bool controllerAvailable = mControllerManager->isGyroAvailable(); bool sensorAvailable = mSensorManager->isGyroAvailable(); @@ -118,9 +119,7 @@ namespace MWInput void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - mMouseManager->processChangedSettings(changed); mSensorManager->processChangedSettings(changed); - mGyroManager->processChangedSettings(changed); } bool InputManager::getControlSwitch(std::string_view sw) diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index 8caed79e21..363a78fadd 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -6,6 +6,7 @@ #include #include +#include #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" @@ -21,12 +22,7 @@ namespace MWInput { MouseManager::MouseManager( BindingsManager* bindingsManager, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window) - : mInvertX(Settings::Manager::getBool("invert x axis", "Input")) - , mInvertY(Settings::Manager::getBool("invert y axis", "Input")) - , mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) - , mCameraSensitivity(Settings::Manager::getFloat("camera sensitivity", "Input")) - , mCameraYMultiplier(Settings::Manager::getFloat("camera y multiplier", "Input")) - , mBindingsManager(bindingsManager) + : mBindingsManager(bindingsManager) , mInputWrapper(inputWrapper) , mGuiCursorX(0) , mGuiCursorY(0) @@ -44,24 +40,6 @@ namespace MWInput mGuiCursorY = h / (2.f * uiScale); } - void MouseManager::processChangedSettings(const Settings::CategorySettingVector& changed) - { - for (const auto& setting : changed) - { - if (setting.first == "Input" && setting.second == "invert x axis") - mInvertX = Settings::Manager::getBool("invert x axis", "Input"); - - if (setting.first == "Input" && setting.second == "invert y axis") - mInvertY = Settings::Manager::getBool("invert y axis", "Input"); - - if (setting.first == "Input" && setting.second == "camera sensitivity") - mCameraSensitivity = Settings::Manager::getFloat("camera sensitivity", "Input"); - - if (setting.first == "Input" && setting.second == "grab cursor") - mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); - } - } - void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent& arg) { mBindingsManager->mouseMoved(arg); @@ -96,8 +74,10 @@ namespace MWInput { MWBase::World* world = MWBase::Environment::get().getWorld(); - float x = arg.xrel * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f; - float y = arg.yrel * mCameraSensitivity * (mInvertY ? -1 : 1) * mCameraYMultiplier / 256.f; + const float cameraSensitivity = Settings::input().mCameraSensitivity; + float x = arg.xrel * cameraSensitivity * (Settings::input().mInvertXAxis ? -1 : 1) / 256.f; + float y = arg.yrel * cameraSensitivity * (Settings::input().mInvertYAxis ? -1 : 1) + * Settings::input().mCameraYMultiplier / 256.f; float rot[3]; rot[0] = -y; @@ -194,7 +174,7 @@ namespace MWInput mInputWrapper->setMouseRelative(isRelative); // we let the mouse escape in the main menu - mInputWrapper->setGrabPointer(grab && (mGrabCursor || isRelative)); + mInputWrapper->setGrabPointer(grab && (Settings::input().mGrabCursor || isRelative)); // we switched to non-relative mode, move our cursor to where the in-game // cursor is @@ -216,10 +196,13 @@ namespace MWInput if (xAxis == 0 && yAxis == 0) return; - float rot[3]; - rot[0] = -yAxis * dt * 1000.0f * mCameraSensitivity * (mInvertY ? -1 : 1) * mCameraYMultiplier / 256.f; - rot[1] = 0.0f; - rot[2] = -xAxis * dt * 1000.0f * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f; + const float cameraSensitivity = Settings::input().mCameraSensitivity; + const float rot[3] = { + -yAxis * dt * 1000.0f * cameraSensitivity * (Settings::input().mInvertYAxis ? -1 : 1) + * Settings::input().mCameraYMultiplier / 256.f, + 0.0f, + -xAxis * dt * 1000.0f * cameraSensitivity * (Settings::input().mInvertXAxis ? -1 : 1) / 256.f, + }; // Only actually turn player when we're not in vanity mode bool controls = MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols"); diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index 4e8996a99c..5de8a8f3bc 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -28,8 +28,6 @@ namespace MWInput void mouseReleased(const SDL_MouseButtonEvent& arg, Uint8 id) override; void mouseWheelMoved(const SDL_MouseWheelEvent& arg) override; - void processChangedSettings(const Settings::CategorySettingVector& changed); - bool injectMouseButtonPress(Uint8 button); bool injectMouseButtonRelease(Uint8 button); void injectMouseMove(float xMove, float yMove, float mouseWheelMove); @@ -42,12 +40,6 @@ namespace MWInput int getMouseMoveY() const { return mMouseMoveY; } private: - bool mInvertX; - bool mInvertY; - bool mGrabCursor; - float mCameraSensitivity; - float mCameraYMultiplier; - BindingsManager* mBindingsManager; SDLUtil::InputWrapper* mInputWrapper; diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index d700d292cc..32e48a008e 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -1,6 +1,7 @@ #include "sensormanager.hpp" #include +#include namespace MWInput { @@ -30,7 +31,7 @@ namespace MWInput void SensorManager::correctGyroscopeAxes() { - if (!Settings::Manager::getBool("enable gyroscope", "Input")) + if (!Settings::input().mEnableGyroscope) return; // Treat setting from config as axes for landscape mode. @@ -71,7 +72,7 @@ namespace MWInput void SensorManager::updateSensors() { - if (Settings::Manager::getBool("enable gyroscope", "Input")) + if (Settings::input().mEnableGyroscope) { int numSensors = SDL_NumSensors(); for (int i = 0; i < numSensors; ++i) @@ -128,7 +129,7 @@ namespace MWInput void SensorManager::sensorUpdated(const SDL_SensorEvent& arg) { - if (!Settings::Manager::getBool("enable gyroscope", "Input")) + if (!Settings::input().mEnableGyroscope) return; SDL_Sensor* sensor = SDL_SensorFromInstanceID(arg.which); diff --git a/components/settings/categories/input.hpp b/components/settings/categories/input.hpp index 7dbd326952..1e59b45334 100644 --- a/components/settings/categories/input.hpp +++ b/components/settings/categories/input.hpp @@ -30,10 +30,8 @@ namespace Settings SettingValue mJoystickDeadZone{ mIndex, "Input", "joystick dead zone", makeClampSanitizerFloat(0, 0.5f) }; SettingValue mEnableGyroscope{ mIndex, "Input", "enable gyroscope" }; - SettingValue mGyroHorizontalAxis{ mIndex, "Input", "gyro horizontal axis", - makeEnumSanitizerString({ "x", "y", "z", "-x", "-y", "-z" }) }; - SettingValue mGyroVerticalAxis{ mIndex, "Input", "gyro vertical axis", - makeEnumSanitizerString({ "x", "y", "z", "-x", "-y", "-z" }) }; + SettingValue mGyroHorizontalAxis{ mIndex, "Input", "gyro horizontal axis" }; + SettingValue mGyroVerticalAxis{ mIndex, "Input", "gyro vertical axis" }; SettingValue mGyroInputThreshold{ mIndex, "Input", "gyro input threshold", makeMaxSanitizerFloat(0) }; SettingValue mGyroHorizontalSensitivity{ mIndex, "Input", "gyro horizontal sensitivity", makeMaxStrictSanitizerFloat(0) }; diff --git a/components/settings/gyroscopeaxis.hpp b/components/settings/gyroscopeaxis.hpp new file mode 100644 index 0000000000..76386d7b66 --- /dev/null +++ b/components/settings/gyroscopeaxis.hpp @@ -0,0 +1,17 @@ +#ifndef OPENMW_COMPONENTS_SETTINGS_GYROSCOPEAXIS_H +#define OPENMW_COMPONENTS_SETTINGS_GYROSCOPEAXIS_H + +namespace Settings +{ + enum class GyroscopeAxis + { + X, + Y, + Z, + MinusX, + MinusY, + MinusZ, + }; +} + +#endif diff --git a/components/settings/settings.cpp b/components/settings/settings.cpp index bd6b10a1fb..0b5260fb8e 100644 --- a/components/settings/settings.cpp +++ b/components/settings/settings.cpp @@ -464,4 +464,21 @@ namespace Settings sInitialized.emplace(category, setting); } + GyroscopeAxis parseGyroscopeAxis(std::string_view value) + { + if (value == "x") + return GyroscopeAxis::X; + else if (value == "y") + return GyroscopeAxis::Y; + else if (value == "z") + return GyroscopeAxis::Z; + else if (value == "-x") + return GyroscopeAxis::MinusX; + else if (value == "-y") + return GyroscopeAxis::MinusY; + else if (value == "-z") + return GyroscopeAxis::MinusZ; + + throw std::runtime_error("Invalid gyroscope axis: " + std::string(value)); + } } diff --git a/components/settings/settings.hpp b/components/settings/settings.hpp index c5efe3b358..c9a5dbc6ea 100644 --- a/components/settings/settings.hpp +++ b/components/settings/settings.hpp @@ -2,6 +2,7 @@ #define COMPONENTS_SETTINGS_H #include "categories.hpp" +#include "gyroscopeaxis.hpp" #include "components/detournavigator/collisionshapetype.hpp" @@ -197,6 +198,14 @@ namespace Settings { return MyGUI::Colour::parse(getString(setting, category)); } + + GyroscopeAxis parseGyroscopeAxis(std::string_view value); + + template <> + inline GyroscopeAxis Manager::getImpl(std::string_view setting, std::string_view category) + { + return parseGyroscopeAxis(getString(setting, category)); + } } #endif // COMPONENTS_SETTINGS_H diff --git a/components/settings/settingvalue.hpp b/components/settings/settingvalue.hpp index e15ba18d1c..540ef1fe0b 100644 --- a/components/settings/settingvalue.hpp +++ b/components/settings/settingvalue.hpp @@ -1,6 +1,7 @@ #ifndef OPENMW_COMPONENTS_SETTINGS_SETTINGVALUE_H #define OPENMW_COMPONENTS_SETTINGS_SETTINGVALUE_H +#include "gyroscopeaxis.hpp" #include "sanitizer.hpp" #include "settings.hpp" @@ -36,6 +37,7 @@ namespace Settings CollisionShapeType, StringArray, MyGuiColour, + GyroscopeAxis, }; template @@ -131,6 +133,12 @@ namespace Settings return SettingValueType::MyGuiColour; } + template <> + inline constexpr SettingValueType getSettingValueType() + { + return SettingValueType::GyroscopeAxis; + } + inline constexpr std::string_view getSettingValueTypeName(SettingValueType type) { switch (type) @@ -165,6 +173,8 @@ namespace Settings return "string array"; case SettingValueType::MyGuiColour: return "colour"; + case SettingValueType::GyroscopeAxis: + return "gyroscope axis"; } return "unsupported"; }