From 15dc4d241dd2f0a92c5e9c28611282747f75d059 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 10:55:35 +0400 Subject: [PATCH 01/23] Split sensors handling so the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 241 ++------------------- apps/openmw/mwinput/inputmanagerimp.hpp | 42 +--- apps/openmw/mwinput/sensormanager.cpp | 274 ++++++++++++++++++++++++ apps/openmw/mwinput/sensormanager.hpp | 73 +++++++ 5 files changed, 371 insertions(+), 261 deletions(-) create mode 100644 apps/openmw/mwinput/sensormanager.cpp create mode 100644 apps/openmw/mwinput/sensormanager.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2b4739ba92..19cf4ef69b 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - inputmanagerimp + inputmanagerimp sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index acfe4f8cd5..590cf61a66 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -31,6 +31,8 @@ #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "sensormanager.hpp" + namespace MWInput { InputManager::InputManager( @@ -79,20 +81,10 @@ namespace MWInput , mAttemptJump(false) , mInvUiScalingFactor(1.f) , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) - , mGyroXSpeed(0.f) - , mGyroYSpeed(0.f) - , mGyroUpdateTimer(0.f) - , mGyroHSensitivity (Settings::Manager::getFloat("gyro horizontal sensitivity", "Input")) - , mGyroVSensitivity (Settings::Manager::getFloat("gyro vertical sensitivity", "Input")) - , mGyroHAxis(GyroscopeAxis::Minus_X) - , mGyroVAxis(GyroscopeAxis::Y) - , mGyroInputThreshold(Settings::Manager::getFloat("gyro input threshold", "Input")) , mFakeDeviceID(1) - , mGyroscope(nullptr) { mInputManager = new SDLUtil::InputWrapper(window, viewer, grab); mInputManager->setMouseEventCallback (this); - mInputManager->setSensorEventCallback (this); mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); mInputManager->setControllerEventCallback(this); @@ -149,8 +141,8 @@ namespace MWInput } } - correctGyroscopeAxes(); - updateSensors(); + mSensorManager = new SensorManager(); + mInputManager->setSensorEventCallback (mSensorManager); float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); if (uiScale != 0.f) @@ -168,17 +160,15 @@ namespace MWInput // Enable all controls for (std::map::iterator it = mControlSwitch.begin(); it != mControlSwitch.end(); ++it) it->second = true; + + mSensorManager->clear(); } InputManager::~InputManager() { mInputBinder->save (mUserFile); - if (mGyroscope != nullptr) - { - SDL_SensorClose(mGyroscope); - mGyroscope = nullptr; - } + delete mSensorManager; delete mInputBinder; @@ -187,112 +177,6 @@ namespace MWInput delete mVideoWrapper; } - InputManager::GyroscopeAxis InputManager::mapGyroscopeAxis(const std::string& axis) - { - if (axis == "x") - return GyroscopeAxis::X; - else if (axis == "y") - return GyroscopeAxis::Y; - else if (axis == "z") - return GyroscopeAxis::Z; - else if (axis == "-x") - return GyroscopeAxis::Minus_X; - else if (axis == "-y") - return GyroscopeAxis::Minus_Y; - else if (axis == "-z") - return GyroscopeAxis::Minus_Z; - - return GyroscopeAxis::Unknown; - } - - void InputManager::correctGyroscopeAxes() - { - if (!Settings::Manager::getBool("enable gyroscope", "Input")) - return; - - // Treat setting from config as axes for landscape mode. - // If the device does not support orientation change, do nothing. - // Note: in is unclear how to correct axes for devices with non-standart Z axis direction. - mGyroHAxis = mapGyroscopeAxis(Settings::Manager::getString("gyro horizontal axis", "Input")); - mGyroVAxis = mapGyroscopeAxis(Settings::Manager::getString("gyro vertical axis", "Input")); - - SDL_DisplayOrientation currentOrientation = SDL_GetDisplayOrientation(Settings::Manager::getInt("screen", "Video")); - switch (currentOrientation) - { - case SDL_ORIENTATION_UNKNOWN: - return; - case SDL_ORIENTATION_LANDSCAPE: - break; - case SDL_ORIENTATION_LANDSCAPE_FLIPPED: - { - mGyroHAxis = GyroscopeAxis(-mGyroHAxis); - mGyroVAxis = GyroscopeAxis(-mGyroVAxis); - - break; - } - case SDL_ORIENTATION_PORTRAIT: - { - GyroscopeAxis oldVAxis = mGyroVAxis; - mGyroVAxis = mGyroHAxis; - mGyroHAxis = GyroscopeAxis(-oldVAxis); - - break; - } - case SDL_ORIENTATION_PORTRAIT_FLIPPED: - { - GyroscopeAxis oldVAxis = mGyroVAxis; - mGyroVAxis = GyroscopeAxis(-mGyroHAxis); - mGyroHAxis = oldVAxis; - - break; - } - } - } - - void InputManager::updateSensors() - { - if (Settings::Manager::getBool("enable gyroscope", "Input")) - { - int numSensors = SDL_NumSensors(); - - for (int i = 0; i < numSensors; ++i) - { - if (SDL_SensorGetDeviceType(i) == SDL_SENSOR_GYRO) - { - // It is unclear how to handle several enabled gyroscopes, so use the first one. - // Note: Android registers some gyroscope as two separate sensors, for non-wake-up mode and for wake-up mode. - if (mGyroscope != nullptr) - { - SDL_SensorClose(mGyroscope); - mGyroscope = nullptr; - mGyroXSpeed = mGyroYSpeed = 0.f; - mGyroUpdateTimer = 0.f; - } - - // FIXME: SDL2 does not provide a way to configure a sensor update frequency so far. - SDL_Sensor *sensor = SDL_SensorOpen(i); - if (sensor == nullptr) - Log(Debug::Error) << "Couldn't open sensor " << SDL_SensorGetDeviceName(i) << ": " << SDL_GetError(); - else - { - mGyroscope = sensor; - break; - } - } - } - } - else - { - if (mGyroscope != nullptr) - { - SDL_SensorClose(mGyroscope); - mGyroscope = nullptr; - mGyroXSpeed = mGyroYSpeed = 0.f; - mGyroUpdateTimer = 0.f; - } - } - } - bool InputManager::isWindowVisible() { return mWindowVisible; @@ -731,36 +615,8 @@ namespace MWInput } } - if (mGyroXSpeed != 0.f || mGyroYSpeed != 0.f) - { - if (mGyroUpdateTimer > 0.5f) - { - // More than half of second passed since the last gyroscope update. - // A device more likely was disconnected or switched to the sleep mode. - // Reset current rotation speed and wait for update. - mGyroXSpeed = mGyroYSpeed = 0.f; - mGyroUpdateTimer = 0.f; - } - - if (!mGuiCursorEnabled) - { - resetIdleTime(); - - float rot[3]; - rot[0] = mGyroYSpeed * dt * mGyroVSensitivity * 4 * (mInvertY ? -1 : 1); - rot[1] = 0.0f; - rot[2] = mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1); - - // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && mControlSwitch["playerlooking"]) - { - mPlayer->yaw(rot[2]); - mPlayer->pitch(rot[0]); - } - } - - mGyroUpdateTimer += dt; - } + if (mSensorManager->update(dt, mGuiCursorEnabled, mControlSwitch["playerlooking"])) + resetIdleTime(); // Disable movement in Gui mode if (!(MWBase::Environment::get().getWindowManager()->isGuiMode() @@ -957,27 +813,6 @@ namespace MWInput if (it->first == "Input" && it->second == "camera sensitivity") mCameraSensitivity = Settings::Manager::getFloat("camera sensitivity", "Input"); - if (it->first == "Input" && it->second == "gyro horizontal sensitivity") - mGyroHSensitivity = Settings::Manager::getFloat("gyro horizontal sensitivity", "Input"); - - if (it->first == "Input" && it->second == "gyro vertical sensitivity") - mGyroVSensitivity = Settings::Manager::getFloat("gyro vertical sensitivity", "Input"); - - if (it->first == "Input" && it->second == "enable gyroscope") - { - correctGyroscopeAxes(); - updateSensors(); - } - - if (it->first == "Input" && it->second == "gyro horizontal axis") - correctGyroscopeAxes(); - - if (it->first == "Input" && it->second == "gyro vertical axis") - correctGyroscopeAxes(); - - if (it->first == "Input" && it->second == "gyro input threshold") - mGyroInputThreshold = Settings::Manager::getFloat("gyro input threshold", "Input"); - if (it->first == "Input" && it->second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); @@ -1006,6 +841,8 @@ namespace MWInput Settings::Manager::getBool("fullscreen", "Video"), Settings::Manager::getBool("window border", "Video")); } + + mSensorManager->processChangedSettings(changed); } bool InputManager::getControlSwitch (const std::string& sw) @@ -1131,57 +968,6 @@ namespace MWInput mJoystickLastUsed = false; } - float InputManager::getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const - { - switch (axis) - { - case GyroscopeAxis::X: - case GyroscopeAxis::Y: - case GyroscopeAxis::Z: - return std::abs(arg.data[0]) >= mGyroInputThreshold ? arg.data[axis-1] : 0.f; - case GyroscopeAxis::Minus_X: - case GyroscopeAxis::Minus_Y: - case GyroscopeAxis::Minus_Z: - return std::abs(arg.data[0]) >= mGyroInputThreshold ? -arg.data[std::abs(axis)-1] : 0.f; - default: - return 0.f; - } - } - - void InputManager::displayOrientationChanged() - { - correctGyroscopeAxes(); - } - - void InputManager::sensorUpdated(const SDL_SensorEvent &arg) - { - if (!Settings::Manager::getBool("enable gyroscope", "Input")) - return; - - SDL_Sensor *sensor = SDL_SensorFromInstanceID(arg.which); - if (!sensor) - { - Log(Debug::Info) << "Couldn't get sensor for sensor event"; - return; - } - - switch (SDL_SensorGetType(sensor)) - { - case SDL_SENSOR_ACCEL: - break; - case SDL_SENSOR_GYRO: - { - mGyroXSpeed = getGyroAxisSpeed(mGyroHAxis, arg); - mGyroYSpeed = getGyroAxisSpeed(mGyroVAxis, arg); - mGyroUpdateTimer = 0.f; - - break; - } - default: - break; - } - } - void InputManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg ) { mInputBinder->mouseMoved (arg); @@ -2235,4 +2021,9 @@ namespace MWInput //MyGUI's buttons are 0 indexed return MyGUI::MouseButton::Enum(button - 1); } + + void InputManager::setPlayer (MWWorld::Player* player) + { + mPlayer = player; + } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 23562ba798..6b5b216535 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -17,6 +17,11 @@ #include "../mwbase/inputmanager.hpp" +namespace MWInput +{ + class SensorManager; +} + namespace MWWorld { class Player; @@ -67,7 +72,6 @@ namespace MWInput public MWBase::InputManager, public SDLUtil::KeyListener, public SDLUtil::MouseListener, - public SDLUtil::SensorListener, public SDLUtil::WindowListener, public SDLUtil::ControllerListener, public ICS::ChannelListener, @@ -92,7 +96,7 @@ namespace MWInput virtual void update(float dt, bool disableControls=false, bool disableEvents=false); - void setPlayer (MWWorld::Player* player) { mPlayer = player; } + void setPlayer (MWWorld::Player* player); virtual void changeInputMode(bool guiMode); @@ -115,7 +119,6 @@ namespace MWInput virtual bool joystickLastUsed() {return mJoystickLastUsed;} - public: virtual void keyPressed(const SDL_KeyboardEvent &arg ); virtual void keyReleased( const SDL_KeyboardEvent &arg ); virtual void textInput (const SDL_TextInputEvent &arg); @@ -126,9 +129,6 @@ namespace MWInput virtual void mouseWheelMoved( const SDL_MouseWheelEvent &arg); - virtual void sensorUpdated(const SDL_SensorEvent &arg); - virtual void displayOrientationChanged(); - virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); @@ -168,17 +168,6 @@ namespace MWInput virtual void readRecord(ESM::ESMReader& reader, uint32_t type); private: - enum GyroscopeAxis - { - Unknown = 0, - X = 1, - Y = 2, - Z = 3, - Minus_X = -1, - Minus_Y = -2, - Minus_Z = -3 - }; - SDL_Window* mWindow; bool mWindowVisible; osg::ref_ptr mViewer; @@ -235,17 +224,8 @@ namespace MWInput float mInvUiScalingFactor; float mGamepadCursorSpeed; - float mGyroXSpeed; - float mGyroYSpeed; - float mGyroUpdateTimer; + SensorManager* mSensorManager; - float mGyroHSensitivity; - float mGyroVSensitivity; - GyroscopeAxis mGyroHAxis; - GyroscopeAxis mGyroVAxis; - float mGyroInputThreshold; - - private: void convertMousePosForMyGUI(int& x, int& y); MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button); @@ -263,15 +243,9 @@ namespace MWInput bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg); void updateCursorMode(); - void updateSensors(); - void correctGyroscopeAxes(); - GyroscopeAxis mapGyroscopeAxis(const std::string& axis); bool checkAllowedToUseItems() const; - float getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const; - - private: void toggleMainMenu(); void toggleSpell(); void toggleWeapon(); @@ -296,9 +270,7 @@ namespace MWInput void loadControllerDefaults(bool force = false); int mFakeDeviceID; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers - SDL_Sensor* mGyroscope; - private: enum Actions { // please add new actions at the bottom, in order to preserve the channel IDs in the key configuration files diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp new file mode 100644 index 0000000000..55a0882f5d --- /dev/null +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -0,0 +1,274 @@ +#include "sensormanager.hpp" + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +namespace MWInput +{ + SensorManager::SensorManager() + : mInvertX(Settings::Manager::getBool("invert x axis", "Input")) + , mInvertY(Settings::Manager::getBool("invert y axis", "Input")) + , mGyroXSpeed(0.f) + , mGyroYSpeed(0.f) + , mGyroUpdateTimer(0.f) + , mGyroHSensitivity(Settings::Manager::getFloat("gyro horizontal sensitivity", "Input")) + , mGyroVSensitivity(Settings::Manager::getFloat("gyro vertical sensitivity", "Input")) + , mGyroHAxis(GyroscopeAxis::Minus_X) + , mGyroVAxis(GyroscopeAxis::Y) + , mGyroInputThreshold(Settings::Manager::getFloat("gyro input threshold", "Input")) + , mGyroscope(nullptr) + { + init(); + } + + void SensorManager::init() + { + correctGyroscopeAxes(); + updateSensors(); + } + + void SensorManager::clear() + { + mGyroXSpeed = 0.f; + mGyroYSpeed = 0.f; + mGyroUpdateTimer = 0.f; + } + + SensorManager::~SensorManager() + { + if (mGyroscope != nullptr) + { + SDL_SensorClose(mGyroscope); + mGyroscope = nullptr; + } + } + + SensorManager::GyroscopeAxis SensorManager::mapGyroscopeAxis(const std::string& axis) + { + if (axis == "x") + return GyroscopeAxis::X; + else if (axis == "y") + return GyroscopeAxis::Y; + else if (axis == "z") + return GyroscopeAxis::Z; + else if (axis == "-x") + return GyroscopeAxis::Minus_X; + else if (axis == "-y") + return GyroscopeAxis::Minus_Y; + else if (axis == "-z") + return GyroscopeAxis::Minus_Z; + + return GyroscopeAxis::Unknown; + } + + void SensorManager::correctGyroscopeAxes() + { + if (!Settings::Manager::getBool("enable gyroscope", "Input")) + return; + + // Treat setting from config as axes for landscape mode. + // If the device does not support orientation change, do nothing. + // Note: in is unclear how to correct axes for devices with non-standart Z axis direction. + mGyroHAxis = mapGyroscopeAxis(Settings::Manager::getString("gyro horizontal axis", "Input")); + mGyroVAxis = mapGyroscopeAxis(Settings::Manager::getString("gyro vertical axis", "Input")); + + SDL_DisplayOrientation currentOrientation = SDL_GetDisplayOrientation(Settings::Manager::getInt("screen", "Video")); + switch (currentOrientation) + { + case SDL_ORIENTATION_UNKNOWN: + return; + case SDL_ORIENTATION_LANDSCAPE: + break; + case SDL_ORIENTATION_LANDSCAPE_FLIPPED: + { + mGyroHAxis = GyroscopeAxis(-mGyroHAxis); + mGyroVAxis = GyroscopeAxis(-mGyroVAxis); + + break; + } + case SDL_ORIENTATION_PORTRAIT: + { + GyroscopeAxis oldVAxis = mGyroVAxis; + mGyroVAxis = mGyroHAxis; + mGyroHAxis = GyroscopeAxis(-oldVAxis); + + break; + } + case SDL_ORIENTATION_PORTRAIT_FLIPPED: + { + GyroscopeAxis oldVAxis = mGyroVAxis; + mGyroVAxis = GyroscopeAxis(-mGyroHAxis); + mGyroHAxis = oldVAxis; + + break; + } + } + } + + void SensorManager::updateSensors() + { + if (Settings::Manager::getBool("enable gyroscope", "Input")) + { + int numSensors = SDL_NumSensors(); + + for (int i = 0; i < numSensors; ++i) + { + if (SDL_SensorGetDeviceType(i) == SDL_SENSOR_GYRO) + { + // It is unclear how to handle several enabled gyroscopes, so use the first one. + // Note: Android registers some gyroscope as two separate sensors, for non-wake-up mode and for wake-up mode. + if (mGyroscope != nullptr) + { + SDL_SensorClose(mGyroscope); + mGyroscope = nullptr; + mGyroXSpeed = mGyroYSpeed = 0.f; + mGyroUpdateTimer = 0.f; + } + + // FIXME: SDL2 does not provide a way to configure a sensor update frequency so far. + SDL_Sensor *sensor = SDL_SensorOpen(i); + if (sensor == nullptr) + Log(Debug::Error) << "Couldn't open sensor " << SDL_SensorGetDeviceName(i) << ": " << SDL_GetError(); + else + { + mGyroscope = sensor; + break; + } + } + } + } + else + { + if (mGyroscope != nullptr) + { + SDL_SensorClose(mGyroscope); + mGyroscope = nullptr; + mGyroXSpeed = mGyroYSpeed = 0.f; + mGyroUpdateTimer = 0.f; + } + } + } + + void SensorManager::processChangedSettings(const Settings::CategorySettingVector& changed) + { + for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + { + if (it->first == "Input" && it->second == "invert x axis") + mInvertX = Settings::Manager::getBool("invert x axis", "Input"); + + if (it->first == "Input" && it->second == "invert y axis") + mInvertY = Settings::Manager::getBool("invert y axis", "Input"); + + if (it->first == "Input" && it->second == "gyro horizontal sensitivity") + mGyroHSensitivity = Settings::Manager::getFloat("gyro horizontal sensitivity", "Input"); + + if (it->first == "Input" && it->second == "gyro vertical sensitivity") + mGyroVSensitivity = Settings::Manager::getFloat("gyro vertical sensitivity", "Input"); + + if (it->first == "Input" && it->second == "enable gyroscope") + init(); + + if (it->first == "Input" && it->second == "gyro horizontal axis") + correctGyroscopeAxes(); + + if (it->first == "Input" && it->second == "gyro vertical axis") + correctGyroscopeAxes(); + + if (it->first == "Input" && it->second == "gyro input threshold") + mGyroInputThreshold = Settings::Manager::getFloat("gyro input threshold", "Input"); + } + } + + float SensorManager::getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const + { + switch (axis) + { + case GyroscopeAxis::X: + case GyroscopeAxis::Y: + case GyroscopeAxis::Z: + return std::abs(arg.data[0]) >= mGyroInputThreshold ? arg.data[axis-1] : 0.f; + case GyroscopeAxis::Minus_X: + case GyroscopeAxis::Minus_Y: + case GyroscopeAxis::Minus_Z: + return std::abs(arg.data[0]) >= mGyroInputThreshold ? -arg.data[std::abs(axis)-1] : 0.f; + default: + return 0.f; + } + } + + void SensorManager::displayOrientationChanged() + { + correctGyroscopeAxes(); + } + + void SensorManager::sensorUpdated(const SDL_SensorEvent &arg) + { + if (!Settings::Manager::getBool("enable gyroscope", "Input")) + return; + + SDL_Sensor *sensor = SDL_SensorFromInstanceID(arg.which); + if (!sensor) + { + Log(Debug::Info) << "Couldn't get sensor for sensor event"; + return; + } + + switch (SDL_SensorGetType(sensor)) + { + case SDL_SENSOR_ACCEL: + break; + case SDL_SENSOR_GYRO: + { + mGyroXSpeed = getGyroAxisSpeed(mGyroHAxis, arg); + mGyroYSpeed = getGyroAxisSpeed(mGyroVAxis, arg); + mGyroUpdateTimer = 0.f; + + break; + } + default: + break; + } + } + + bool SensorManager::update(float dt, bool isCursorEnabled, bool isTurningEnabled) + { + if (mGyroXSpeed == 0.f && mGyroYSpeed == 0.f) + return false; + + if (mGyroUpdateTimer > 0.5f) + { + // More than half of second passed since the last gyroscope update. + // A device more likely was disconnected or switched to the sleep mode. + // Reset current rotation speed and wait for update. + clear(); + mGyroUpdateTimer = 0.f; + return false; + } + + mGyroUpdateTimer += dt; + + if (!isCursorEnabled) + { + float rot[3]; + rot[0] = mGyroYSpeed * dt * mGyroVSensitivity * 4 * (mInvertY ? -1 : 1); + rot[1] = 0.0f; + rot[2] = mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1); + + // Only actually turn player when we're not in vanity mode + if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && isTurningEnabled) + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + player.yaw(rot[2]); + player.pitch(rot[0]); + } + + return true; + } + + return false; + } +} diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp new file mode 100644 index 0000000000..d655e9c078 --- /dev/null +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -0,0 +1,73 @@ +#ifndef MWINPUT_MWSENSORMANAGER_H +#define MWINPUT_MWSENSORMANAGER_H + +#include + +#include +#include + +namespace SDLUtil +{ + class InputWrapper; +} + +namespace MWWorld +{ + class Player; +} + +namespace MWInput +{ + class SensorManager : public SDLUtil::SensorListener + { + public: + SensorManager(); + + virtual ~SensorManager(); + + void init(); + + void clear(); + + bool update(float dt, bool isCursorEnabled, bool isTurningEnabled); + + public: + virtual void sensorUpdated(const SDL_SensorEvent &arg); + virtual void displayOrientationChanged(); + void processChangedSettings(const Settings::CategorySettingVector& changed); + + private: + enum GyroscopeAxis + { + Unknown = 0, + X = 1, + Y = 2, + Z = 3, + Minus_X = -1, + Minus_Y = -2, + Minus_Z = -3 + }; + + bool mInvertX; + bool mInvertY; + + float mGyroXSpeed; + float mGyroYSpeed; + float mGyroUpdateTimer; + + float mGyroHSensitivity; + float mGyroVSensitivity; + GyroscopeAxis mGyroHAxis; + GyroscopeAxis mGyroVAxis; + float mGyroInputThreshold; + + private: + + void updateSensors(); + void correctGyroscopeAxes(); + GyroscopeAxis mapGyroscopeAxis(const std::string& axis); + float getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const; + SDL_Sensor* mGyroscope; + }; +} +#endif From 3c09d05615d73daa1627fef48eff386dfb6dd20f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 11:10:17 +0400 Subject: [PATCH 02/23] Split actions enum to the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwinput/actions.hpp | 79 +++++++++++++++++++++++++ apps/openmw/mwinput/inputmanagerimp.hpp | 75 +---------------------- 3 files changed, 82 insertions(+), 74 deletions(-) create mode 100644 apps/openmw/mwinput/actions.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 19cf4ef69b..100d56525a 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - inputmanagerimp sensormanager + inputmanagerimp sensormanager actions ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwinput/actions.hpp b/apps/openmw/mwinput/actions.hpp new file mode 100644 index 0000000000..a1c1607126 --- /dev/null +++ b/apps/openmw/mwinput/actions.hpp @@ -0,0 +1,79 @@ +#ifndef MWINPUT_ACTIONS_H +#define MWINPUT_ACTIONS_H + +namespace MWInput +{ + enum Actions + { + // please add new actions at the bottom, in order to preserve the channel IDs in the key configuration files + + A_GameMenu, + + A_Unused, + + A_Screenshot, // Take a screenshot + + A_Inventory, // Toggle inventory screen + + A_Console, // Toggle console screen + + A_MoveLeft, // Move player left / right + A_MoveRight, + A_MoveForward, // Forward / Backward + A_MoveBackward, + + A_Activate, + + A_Use, //Use weapon, spell, etc. + A_Jump, + A_AutoMove, //Toggle Auto-move forward + A_Rest, //Rest + A_Journal, //Journal + A_Weapon, //Draw/Sheath weapon + A_Spell, //Ready/Unready Casting + A_Run, //Run when held + A_CycleSpellLeft, //cycling through spells + A_CycleSpellRight, + A_CycleWeaponLeft, //Cycling through weapons + A_CycleWeaponRight, + A_ToggleSneak, //Toggles Sneak + A_AlwaysRun, //Toggle Walking/Running + A_Sneak, + + A_QuickSave, + A_QuickLoad, + A_QuickMenu, + A_ToggleWeapon, + A_ToggleSpell, + + A_TogglePOV, + + A_QuickKey1, + A_QuickKey2, + A_QuickKey3, + A_QuickKey4, + A_QuickKey5, + A_QuickKey6, + A_QuickKey7, + A_QuickKey8, + A_QuickKey9, + A_QuickKey10, + + A_QuickKeysMenu, + + A_ToggleHUD, + + A_ToggleDebug, + + A_LookUpDown, //Joystick look + A_LookLeftRight, + A_MoveForwardBackward, + A_MoveLeftRight, + + A_ZoomIn, + A_ZoomOut, + + A_Last // Marker for the last item + }; +} +#endif diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 6b5b216535..d2278483d3 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -17,6 +17,8 @@ #include "../mwbase/inputmanager.hpp" +#include "actions.hpp" + namespace MWInput { class SensorManager; @@ -270,79 +272,6 @@ namespace MWInput void loadControllerDefaults(bool force = false); int mFakeDeviceID; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers - - enum Actions - { - // please add new actions at the bottom, in order to preserve the channel IDs in the key configuration files - - A_GameMenu, - - A_Unused, - - A_Screenshot, // Take a screenshot - - A_Inventory, // Toggle inventory screen - - A_Console, // Toggle console screen - - A_MoveLeft, // Move player left / right - A_MoveRight, - A_MoveForward, // Forward / Backward - A_MoveBackward, - - A_Activate, - - A_Use, //Use weapon, spell, etc. - A_Jump, - A_AutoMove, //Toggle Auto-move forward - A_Rest, //Rest - A_Journal, //Journal - A_Weapon, //Draw/Sheath weapon - A_Spell, //Ready/Unready Casting - A_Run, //Run when held - A_CycleSpellLeft, //cycling through spells - A_CycleSpellRight, - A_CycleWeaponLeft, //Cycling through weapons - A_CycleWeaponRight, - A_ToggleSneak, //Toggles Sneak - A_AlwaysRun, //Toggle Walking/Running - A_Sneak, - - A_QuickSave, - A_QuickLoad, - A_QuickMenu, - A_ToggleWeapon, - A_ToggleSpell, - - A_TogglePOV, - - A_QuickKey1, - A_QuickKey2, - A_QuickKey3, - A_QuickKey4, - A_QuickKey5, - A_QuickKey6, - A_QuickKey7, - A_QuickKey8, - A_QuickKey9, - A_QuickKey10, - - A_QuickKeysMenu, - - A_ToggleHUD, - - A_ToggleDebug, - - A_LookUpDown, //Joystick look - A_LookLeftRight, - A_MoveForwardBackward, - A_MoveLeftRight, - - A_ZoomIn, - A_ZoomOut, - - A_Last // Marker for the last item - }; }; } #endif From 1560e71f4ee394d751e66b5d1139cfa2d666b2f9 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 11:43:45 +0400 Subject: [PATCH 03/23] Move SDL mappigs to the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/inputmanager.hpp | 2 - apps/openmw/mwinput/inputmanagerimp.cpp | 72 +--------------------- apps/openmw/mwinput/inputmanagerimp.hpp | 10 --- apps/openmw/mwinput/sdlmappings.cpp | 81 +++++++++++++++++++++++++ apps/openmw/mwinput/sdlmappings.hpp | 21 +++++++ 6 files changed, 104 insertions(+), 84 deletions(-) create mode 100644 apps/openmw/mwinput/sdlmappings.cpp create mode 100644 apps/openmw/mwinput/sdlmappings.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 100d56525a..ff24b880f8 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - inputmanagerimp sensormanager actions + actions inputmanagerimp sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 0eb06ee3de..bb2ff99985 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -54,8 +54,6 @@ namespace MWBase virtual std::string getActionDescription (int action) = 0; virtual std::string getActionKeyBindingName (int action) = 0; virtual std::string getActionControllerBindingName (int action) = 0; - virtual std::string sdlControllerAxisToString(int axis) = 0; - virtual std::string sdlControllerButtonToString(int button) = 0; ///Actions available for binding to keyboard buttons virtual std::vector getActionKeySorting() = 0; ///Actions available for binding to controller buttons diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 590cf61a66..5326c2d5c5 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -31,6 +31,7 @@ #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "sdlmappings.hpp" #include "sensormanager.hpp" namespace MWInput @@ -1705,65 +1706,6 @@ namespace MWInput return "#{sNone}"; } - std::string InputManager::sdlControllerButtonToString(int button) - { - switch(button) - { - case SDL_CONTROLLER_BUTTON_A: - return "A Button"; - case SDL_CONTROLLER_BUTTON_B: - return "B Button"; - case SDL_CONTROLLER_BUTTON_BACK: - return "Back Button"; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: - return "DPad Down"; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: - return "DPad Left"; - case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: - return "DPad Right"; - case SDL_CONTROLLER_BUTTON_DPAD_UP: - return "DPad Up"; - case SDL_CONTROLLER_BUTTON_GUIDE: - return "Guide Button"; - case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: - return "Left Shoulder"; - case SDL_CONTROLLER_BUTTON_LEFTSTICK: - return "Left Stick Button"; - case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: - return "Right Shoulder"; - case SDL_CONTROLLER_BUTTON_RIGHTSTICK: - return "Right Stick Button"; - case SDL_CONTROLLER_BUTTON_START: - return "Start Button"; - case SDL_CONTROLLER_BUTTON_X: - return "X Button"; - case SDL_CONTROLLER_BUTTON_Y: - return "Y Button"; - default: - return "Button " + std::to_string(button); - } - } - std::string InputManager::sdlControllerAxisToString(int axis) - { - switch(axis) - { - case SDL_CONTROLLER_AXIS_LEFTX: - return "Left Stick X"; - case SDL_CONTROLLER_AXIS_LEFTY: - return "Left Stick Y"; - case SDL_CONTROLLER_AXIS_RIGHTX: - return "Right Stick X"; - case SDL_CONTROLLER_AXIS_RIGHTY: - return "Right Stick Y"; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: - return "Left Trigger"; - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - return "Right Trigger"; - default: - return "Axis " + std::to_string(axis); - } - } - std::vector InputManager::getActionKeySorting() { std::vector ret; @@ -2010,18 +1952,6 @@ namespace MWInput loadControllerDefaults(true); } - MyGUI::MouseButton InputManager::sdlButtonToMyGUI(Uint8 button) - { - //The right button is the second button, according to MyGUI - if(button == SDL_BUTTON_RIGHT) - button = SDL_BUTTON_MIDDLE; - else if(button == SDL_BUTTON_MIDDLE) - button = SDL_BUTTON_RIGHT; - - //MyGUI's buttons are 0 indexed - return MyGUI::MouseButton::Enum(button - 1); - } - void InputManager::setPlayer (MWWorld::Player* player) { mPlayer = player; diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index d2278483d3..1e5c89cda2 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -39,11 +39,6 @@ namespace ICS class InputControlSystem; } -namespace MyGUI -{ - struct MouseButton; -} - namespace Files { struct ConfigurationManager; @@ -230,11 +225,6 @@ namespace MWInput void convertMousePosForMyGUI(int& x, int& y); - MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button); - - virtual std::string sdlControllerAxisToString(int axis); - virtual std::string sdlControllerButtonToString(int button); - void resetIdleTime(); void updateIdleTime(float dt); diff --git a/apps/openmw/mwinput/sdlmappings.cpp b/apps/openmw/mwinput/sdlmappings.cpp new file mode 100644 index 0000000000..53c9e77fe4 --- /dev/null +++ b/apps/openmw/mwinput/sdlmappings.cpp @@ -0,0 +1,81 @@ +#include "sdlmappings.hpp" + +#include + +#include +#include + +namespace MWInput +{ + std::string sdlControllerButtonToString(int button) + { + switch(button) + { + case SDL_CONTROLLER_BUTTON_A: + return "A Button"; + case SDL_CONTROLLER_BUTTON_B: + return "B Button"; + case SDL_CONTROLLER_BUTTON_BACK: + return "Back Button"; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + return "DPad Down"; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + return "DPad Left"; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + return "DPad Right"; + case SDL_CONTROLLER_BUTTON_DPAD_UP: + return "DPad Up"; + case SDL_CONTROLLER_BUTTON_GUIDE: + return "Guide Button"; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + return "Left Shoulder"; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + return "Left Stick Button"; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + return "Right Shoulder"; + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: + return "Right Stick Button"; + case SDL_CONTROLLER_BUTTON_START: + return "Start Button"; + case SDL_CONTROLLER_BUTTON_X: + return "X Button"; + case SDL_CONTROLLER_BUTTON_Y: + return "Y Button"; + default: + return "Button " + std::to_string(button); + } + } + + std::string sdlControllerAxisToString(int axis) + { + switch(axis) + { + case SDL_CONTROLLER_AXIS_LEFTX: + return "Left Stick X"; + case SDL_CONTROLLER_AXIS_LEFTY: + return "Left Stick Y"; + case SDL_CONTROLLER_AXIS_RIGHTX: + return "Right Stick X"; + case SDL_CONTROLLER_AXIS_RIGHTY: + return "Right Stick Y"; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + return "Left Trigger"; + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + return "Right Trigger"; + default: + return "Axis " + std::to_string(axis); + } + } + + MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button) + { + //The right button is the second button, according to MyGUI + if(button == SDL_BUTTON_RIGHT) + button = SDL_BUTTON_MIDDLE; + else if(button == SDL_BUTTON_MIDDLE) + button = SDL_BUTTON_RIGHT; + + //MyGUI's buttons are 0 indexed + return MyGUI::MouseButton::Enum(button - 1); + } +} diff --git a/apps/openmw/mwinput/sdlmappings.hpp b/apps/openmw/mwinput/sdlmappings.hpp new file mode 100644 index 0000000000..dd6d750cb2 --- /dev/null +++ b/apps/openmw/mwinput/sdlmappings.hpp @@ -0,0 +1,21 @@ +#ifndef MWINPUT_SDLMAPPINGS_H +#define MWINPUT_SDLMAPPINGS_H + +#include + +#include + +namespace MyGUI +{ + struct MouseButton; +} + +namespace MWInput +{ + std::string sdlControllerButtonToString(int button); + + std::string sdlControllerAxisToString(int axis); + + MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button); +} +#endif From fcac7d3ab770c07468169b506c65660a1a84e435 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 14:48:23 +0400 Subject: [PATCH 04/23] Split mouse handling to the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwbase/inputmanager.hpp | 6 + apps/openmw/mwinput/inputmanagerimp.cpp | 185 +++---------------- apps/openmw/mwinput/inputmanagerimp.hpp | 23 +-- apps/openmw/mwinput/mousemanager.cpp | 231 ++++++++++++++++++++++++ apps/openmw/mwinput/mousemanager.hpp | 70 +++++++ 6 files changed, 339 insertions(+), 178 deletions(-) create mode 100644 apps/openmw/mwinput/mousemanager.cpp create mode 100644 apps/openmw/mwinput/mousemanager.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index ff24b880f8..b5ea4fabf8 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - actions inputmanagerimp sdlmappings sensormanager + actions inputmanagerimp mousemanager sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index bb2ff99985..29c876e2bf 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -47,6 +47,7 @@ namespace MWBase virtual void processChangedSettings(const std::set< std::pair >& changed) = 0; virtual void setDragDrop(bool dragDrop) = 0; + virtual void setGamepadGuiCursorEnabled(bool enabled) = 0; virtual void toggleControlSwitch (const std::string& sw, bool value) = 0; virtual bool getControlSwitch (const std::string& sw) = 0; @@ -67,10 +68,15 @@ namespace MWBase /// Returns if the last used input device was a joystick or a keyboard /// @return true if joystick, false otherwise virtual bool joystickLastUsed() = 0; + virtual void setJoystickLastUsed(bool enabled) = 0; virtual int countSavedGameRecords() const = 0; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; + + virtual void setPlayerControlsEnabled(bool enabled) = 0; + + virtual void resetIdleTime() = 0; }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 5326c2d5c5..e79ec145a3 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -31,6 +30,7 @@ #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "mousemanager.hpp" #include "sdlmappings.hpp" #include "sensormanager.hpp" @@ -60,18 +60,12 @@ namespace MWInput , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mControlsDisabled(false) , mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input")) - , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) - , mCameraYMultiplier (Settings::Manager::getFloat("camera y multiplier", "Input")) , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) - , mMouseLookEnabled(false) , mGuiCursorEnabled(true) , mGamepadGuiCursorEnabled(true) , mDetectingKeyboard(false) , mOverencumberedMessageDelay(0.f) - , mGuiCursorX(0) - , mGuiCursorY(0) - , mMouseWheel(0) , mGamepadZoom(0) , mUserFileExists(userFileExists) , mAlwaysRunActive(Settings::Manager::getBool("always run", "Input")) @@ -80,12 +74,10 @@ namespace MWInput , mSneakGamepadShortcut(false) , mSneaking(false) , mAttemptJump(false) - , mInvUiScalingFactor(1.f) , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) , mFakeDeviceID(1) { mInputManager = new SDLUtil::InputWrapper(window, viewer, grab); - mInputManager->setMouseEventCallback (this); mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); mInputManager->setControllerEventCallback(this); @@ -145,15 +137,8 @@ namespace MWInput mSensorManager = new SensorManager(); mInputManager->setSensorEventCallback (mSensorManager); - float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); - if (uiScale != 0.f) - mInvUiScalingFactor = 1.f / uiScale; - - int w,h; - SDL_GetWindowSize(window, &w, &h); - - mGuiCursorX = mInvUiScalingFactor * w / 2.f; - mGuiCursorY = mInvUiScalingFactor * h / 2.f; + mMouseManager = new MouseManager(mInputBinder, mInputManager, window); + mInputManager->setMouseEventCallback (mMouseManager); } void InputManager::clear() @@ -163,6 +148,7 @@ namespace MWInput it->second = true; mSensorManager->clear(); + mMouseManager->clear(); } InputManager::~InputManager() @@ -529,9 +515,9 @@ namespace MWInput //we switched to non-relative mode, move our cursor to where the in-game //cursor is - if( !is_relative && was_relative != is_relative ) + if(!is_relative && was_relative != is_relative) { - mInputManager->warpMouse(static_cast(mGuiCursorX/mInvUiScalingFactor), static_cast(mGuiCursorY/mInvUiScalingFactor)); + mMouseManager->warpMouse(); } } @@ -571,50 +557,26 @@ namespace MWInput float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue()*2.0f-1.0f; float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue()*2.0f-1.0f; float zAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; - const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); // 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 xmove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; - float ymove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; - if (xmove != 0|| ymove != 0 || zAxis != 0) + float xMove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; + float yMove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; + if (xMove != 0|| yMove != 0 || zAxis != 0) { - mGuiCursorX += xmove; - mGuiCursorY += ymove; - mMouseWheel -= static_cast(zAxis * dt * 1500.0f); + int mouseWheelMove = static_cast(-zAxis * dt * 1500.0f); - mGuiCursorX = std::max(0.f, std::min(mGuiCursorX, float(viewSize.width-1))); - mGuiCursorY = std::max(0.f, std::min(mGuiCursorY, float(viewSize.height-1))); - - MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); - mInputManager->warpMouse(static_cast(mGuiCursorX/mInvUiScalingFactor), static_cast(mGuiCursorY/mInvUiScalingFactor)); + mMouseManager->injectMouseMove(xMove, yMove, mouseWheelMove); + mMouseManager->warpMouse(); MWBase::Environment::get().getWindowManager()->setCursorActive(true); } } - if (mMouseLookEnabled) - { - float xAxis = mInputBinder->getChannel(A_LookLeftRight)->getValue()*2.0f-1.0f; - float yAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; - if (xAxis != 0 || yAxis != 0) - { - resetIdleTime(); - float rot[3]; - rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; - rot[1] = 0.0f; - rot[2] = xAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); - - // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && mControlSwitch["playerlooking"]) - { - mPlayer->yaw(rot[2]); - mPlayer->pitch(rot[0]); - } - } - } + if (mMouseManager->update(dt, disableControls)) + resetIdleTime(); if (mSensorManager->update(dt, mGuiCursorEnabled, mControlSwitch["playerlooking"])) resetIdleTime(); @@ -788,10 +750,16 @@ namespace MWInput mDragDrop = dragDrop; } + void InputManager::setGamepadGuiCursorEnabled(bool enabled) + { + mGamepadGuiCursorEnabled = enabled; + } + void InputManager::changeInputMode(bool guiMode) { mGuiCursorEnabled = guiMode; - mMouseLookEnabled = !guiMode; + mMouseManager->setGuiCursorEnabled(guiMode); + mMouseManager->setMouseLookEnabled(!guiMode); if (guiMode) MWBase::Environment::get().getWindowManager()->showCrosshair(false); MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mJoystickLastUsed || mGamepadGuiCursorEnabled)); @@ -811,9 +779,6 @@ namespace MWInput if (it->first == "Input" && it->second == "invert y axis") mInvertY = Settings::Manager::getBool("invert y axis", "Input"); - if (it->first == "Input" && it->second == "camera sensitivity") - mCameraSensitivity = Settings::Manager::getFloat("camera sensitivity", "Input"); - if (it->first == "Input" && it->second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); @@ -916,110 +881,6 @@ namespace MWInput mInputBinder->keyReleased (arg); } - void InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) - { - mJoystickLastUsed = false; - bool guiMode = false; - - if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events - { - guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); - guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; - if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) - { - MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); - if (b && b->getEnabled() && id == SDL_BUTTON_LEFT) - { - MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); - } - } - MWBase::Environment::get().getWindowManager()->setCursorActive(true); - } - - setPlayerControlsEnabled(!guiMode); - - // Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible - if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings) - mInputBinder->mousePressed (arg, id); - } - - void InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) - { - mJoystickLastUsed = false; - - if(mInputBinder->detectingBindingState()) - { - mInputBinder->mouseReleased (arg, id); - } else { - bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); - guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; - - if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind - - setPlayerControlsEnabled(!guiMode); - mInputBinder->mouseReleased (arg, id); - } - } - - void InputManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) - { - if (mInputBinder->detectingBindingState() || !mControlsDisabled) - mInputBinder->mouseWheelMoved(arg); - - mJoystickLastUsed = false; - } - - void InputManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg ) - { - mInputBinder->mouseMoved (arg); - - mJoystickLastUsed = false; - resetIdleTime (); - - if (mGuiCursorEnabled) - { - if (!mGamepadGuiCursorEnabled) - mGamepadGuiCursorEnabled = true; - // 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 - mGuiCursorX = static_cast(arg.x) * mInvUiScalingFactor; - mGuiCursorY = static_cast(arg.y) * mInvUiScalingFactor; - - mMouseWheel = int(arg.z); - - MyGUI::InputManager::getInstance().injectMouseMove( int(mGuiCursorX), int(mGuiCursorY), mMouseWheel); - // FIXME: inject twice to force updating focused widget states (tooltips) resulting from changing the viewport by scroll wheel - MyGUI::InputManager::getInstance().injectMouseMove( int(mGuiCursorX), int(mGuiCursorY), mMouseWheel); - - MWBase::Environment::get().getWindowManager()->setCursorActive(true); - } - - if (mMouseLookEnabled && !mControlsDisabled) - { - resetIdleTime(); - - float x = arg.xrel * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); - float y = arg.yrel * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; - - float rot[3]; - rot[0] = -y; - rot[1] = 0.0f; - rot[2] = -x; - - // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && mControlSwitch["playerlooking"]) - { - mPlayer->yaw(x); - mPlayer->pitch(y); - } - - if (arg.zrel && mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"]) //Check to make sure you are allowed to zoomout and there is a change - { - MWBase::Environment::get().getWorld()->changeVanityModeScale(static_cast(arg.zrel)); - } - } - } - void InputManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg ) { if (!mJoystickEnabled || mInputBinder->detectingBindingState()) @@ -1035,7 +896,7 @@ namespace MWInput // Temporary mouse binding until keyboard controls are available: if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. { - bool mousePressSuccess = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(SDL_BUTTON_LEFT)); + bool mousePressSuccess = mMouseManager->injectMouseButtonPress(SDL_BUTTON_LEFT); if (MyGUI::InputManager::getInstance().getMouseFocusWidget()) { MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); @@ -1076,7 +937,7 @@ namespace MWInput // Temporary mouse binding until keyboard controls are available: if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. { - bool mousePressSuccess = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(SDL_BUTTON_LEFT)); + bool mousePressSuccess = mMouseManager->injectMouseButtonRelease(SDL_BUTTON_LEFT); if (mInputBinder->detectingBindingState()) // If the player just triggered binding, don't let button release bind. return; diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 1e5c89cda2..f73aa7f3d1 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -21,6 +21,7 @@ namespace MWInput { + class MouseManager; class SensorManager; } @@ -68,7 +69,6 @@ namespace MWInput class InputManager : public MWBase::InputManager, public SDLUtil::KeyListener, - public SDLUtil::MouseListener, public SDLUtil::WindowListener, public SDLUtil::ControllerListener, public ICS::ChannelListener, @@ -100,6 +100,7 @@ namespace MWInput virtual void processChangedSettings(const Settings::CategorySettingVector& changed); virtual void setDragDrop(bool dragDrop); + virtual void setGamepadGuiCursorEnabled(bool enabled); virtual void toggleControlSwitch (const std::string& sw, bool value); virtual bool getControlSwitch (const std::string& sw); @@ -114,18 +115,13 @@ namespace MWInput virtual void resetToDefaultKeyBindings(); virtual void resetToDefaultControllerBindings(); + virtual void setJoystickLastUsed(bool enabled) { mJoystickLastUsed = enabled; } virtual bool joystickLastUsed() {return mJoystickLastUsed;} virtual void keyPressed(const SDL_KeyboardEvent &arg ); virtual void keyReleased( const SDL_KeyboardEvent &arg ); virtual void textInput (const SDL_TextInputEvent &arg); - virtual void mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ); - virtual void mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); - virtual void mouseMoved( const SDLUtil::MouseMotionEvent &arg ); - - virtual void mouseWheelMoved( const SDL_MouseWheelEvent &arg); - virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); @@ -164,6 +160,10 @@ namespace MWInput virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress); virtual void readRecord(ESM::ESMReader& reader, uint32_t type); + virtual void setPlayerControlsEnabled(bool enabled); + + virtual void resetIdleTime(); + private: SDL_Window* mWindow; bool mWindowVisible; @@ -191,12 +191,9 @@ namespace MWInput bool mControlsDisabled; bool mJoystickEnabled; - float mCameraSensitivity; - float mCameraYMultiplier; float mPreviewPOVDelay; float mTimeIdle; - bool mMouseLookEnabled; bool mGuiCursorEnabled; bool mGamepadGuiCursorEnabled; @@ -204,9 +201,6 @@ namespace MWInput float mOverencumberedMessageDelay; - float mGuiCursorX; - float mGuiCursorY; - int mMouseWheel; float mGamepadZoom; bool mUserFileExists; bool mAlwaysRunActive; @@ -221,14 +215,13 @@ namespace MWInput float mInvUiScalingFactor; float mGamepadCursorSpeed; + MouseManager* mMouseManager; SensorManager* mSensorManager; void convertMousePosForMyGUI(int& x, int& y); - void resetIdleTime(); void updateIdleTime(float dt); - void setPlayerControlsEnabled(bool enabled); void handleGuiArrowKey(int action); // Return true if GUI consumes input. bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg); diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp new file mode 100644 index 0000000000..b341247738 --- /dev/null +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -0,0 +1,231 @@ +#include "mousemanager.hpp" + +#include +#include +#include +#include + +#include +#include + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include "actions.hpp" +#include "sdlmappings.hpp" + +namespace MWInput +{ + MouseManager::MouseManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window) + : mInvertX(Settings::Manager::getBool("invert x axis", "Input")) + , mInvertY(Settings::Manager::getBool("invert y axis", "Input")) + , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) + , mCameraYMultiplier (Settings::Manager::getFloat("camera y multiplier", "Input")) + , mInputBinder(inputBinder) + , mInputWrapper(inputWrapper) + , mInvUiScalingFactor(1.f) + , mGuiCursorX(0) + , mGuiCursorY(0) + , mMouseWheel(0) + , mMouseLookEnabled(false) + , mControlsDisabled(false) + , mGuiCursorEnabled(true) + { + float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); + if (uiScale != 0.f) + mInvUiScalingFactor = 1.f / uiScale; + + int w,h; + SDL_GetWindowSize(window, &w, &h); + + mGuiCursorX = mInvUiScalingFactor * w / 2.f; + mGuiCursorY = mInvUiScalingFactor * h / 2.f; + } + + void MouseManager::clear() + { + } + + void MouseManager::processChangedSettings(const Settings::CategorySettingVector& changed) + { + for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + { + if (it->first == "Input" && it->second == "invert x axis") + mInvertX = Settings::Manager::getBool("invert x axis", "Input"); + + if (it->first == "Input" && it->second == "invert y axis") + mInvertY = Settings::Manager::getBool("invert y axis", "Input"); + + if (it->first == "Input" && it->second == "camera sensitivity") + mCameraSensitivity = Settings::Manager::getFloat("camera sensitivity", "Input"); + } + } + + void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg) + { + mInputBinder->mouseMoved (arg); + + MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); + input->setJoystickLastUsed(false); + input->resetIdleTime(); + + if (mGuiCursorEnabled) + { + input->setGamepadGuiCursorEnabled(true); + + // 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 + mGuiCursorX = static_cast(arg.x) * mInvUiScalingFactor; + mGuiCursorY = static_cast(arg.y) * mInvUiScalingFactor; + + mMouseWheel = static_cast(arg.z); + + MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); + // FIXME: inject twice to force updating focused widget states (tooltips) resulting from changing the viewport by scroll wheel + MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); + + MWBase::Environment::get().getWindowManager()->setCursorActive(true); + } + + if (mMouseLookEnabled && !mControlsDisabled) + { + float x = arg.xrel * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); + float y = arg.yrel * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; + + float rot[3]; + rot[0] = -y; + rot[1] = 0.0f; + rot[2] = -x; + + // Only actually turn player when we're not in vanity mode + if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && input->getControlSwitch("playerlooking")) + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + player.yaw(x); + player.pitch(y); + } + + if (arg.zrel && input->getControlSwitch("playerviewswitch") && input->getControlSwitch("playercontrols")) //Check to make sure you are allowed to zoomout and there is a change + { + MWBase::Environment::get().getWorld()->changeVanityModeScale(static_cast(arg.zrel)); + } + } + } + + void MouseManager::mouseReleased(const SDL_MouseButtonEvent &arg, Uint8 id) + { + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); + + if(mInputBinder->detectingBindingState()) + { + mInputBinder->mouseReleased (arg, id); + } + else + { + bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); + guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; + + if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind + + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!guiMode); + mInputBinder->mouseReleased (arg, id); + } + } + + void MouseManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) + { + if (mInputBinder->detectingBindingState() || !mControlsDisabled) + mInputBinder->mouseWheelMoved(arg); + + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); + } + + void MouseManager::mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id) + { + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); + bool guiMode = false; + + if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events + { + guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); + guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; + if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) + { + MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); + if (b && b->getEnabled() && id == SDL_BUTTON_LEFT) + { + MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); + } + } + MWBase::Environment::get().getWindowManager()->setCursorActive(true); + } + + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!guiMode); + + // Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible + if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings) + mInputBinder->mousePressed (arg, id); + } + + bool MouseManager::update(float dt, bool disableControls) + { + mControlsDisabled = disableControls; + + if (!mMouseLookEnabled) + return false; + + float xAxis = mInputBinder->getChannel(A_LookLeftRight)->getValue()*2.0f-1.0f; + float yAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; + if (xAxis == 0 && yAxis == 0) + return false; + + float rot[3]; + rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; + rot[1] = 0.0f; + rot[2] = xAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); + + // Only actually turn player when we're not in vanity mode + if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + player.yaw(rot[2]); + player.pitch(rot[0]); + } + + return true; + } + + bool MouseManager::injectMouseButtonPress(Uint8 button) + { + return MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(button)); + } + + bool MouseManager::injectMouseButtonRelease(Uint8 button) + { + return MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(button)); + } + + void MouseManager::injectMouseMove(int xMove, int yMove, int mouseWheelMove) + { + mGuiCursorX += xMove; + mGuiCursorY += yMove; + mMouseWheel += mouseWheelMove; + + const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); + mGuiCursorX = std::max(0.f, std::min(mGuiCursorX, float(viewSize.width-1))); + mGuiCursorY = std::max(0.f, std::min(mGuiCursorY, float(viewSize.height-1))); + + MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); + } + + void MouseManager::warpMouse() + { + mInputWrapper->warpMouse(static_cast(mGuiCursorX/mInvUiScalingFactor), static_cast(mGuiCursorY/mInvUiScalingFactor)); + } +} diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp new file mode 100644 index 0000000000..c0a9408c68 --- /dev/null +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -0,0 +1,70 @@ +#ifndef MWINPUT_MWMOUSEMANAGER_H +#define MWINPUT_MWMOUSEMANAGER_H + +#include + +#include +#include + +namespace SDLUtil +{ + class InputWrapper; +} + +namespace MWWorld +{ + class Player; +} + +namespace ICS +{ + class InputControlSystem; +} + +namespace MWInput +{ + class MouseManager : public SDLUtil::MouseListener + { + public: + MouseManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window); + + virtual ~MouseManager() = default; + + void clear(); + + bool update(float dt, bool disableControls); + + virtual void mouseMoved(const SDLUtil::MouseMotionEvent &arg); + virtual void mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id); + virtual void mouseReleased(const SDL_MouseButtonEvent &arg, Uint8 id); + virtual void mouseWheelMoved(const SDL_MouseWheelEvent &arg); + + void processChangedSettings(const Settings::CategorySettingVector& changed); + + bool injectMouseButtonPress(Uint8 button); + bool injectMouseButtonRelease(Uint8 button); + void injectMouseMove(int xMove, int yMove, int mouseWheelMove); + void warpMouse(); + + void setMouseLookEnabled(bool enabled) { mMouseLookEnabled = enabled; } + void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } + + private: + bool mInvertX; + bool mInvertY; + float mCameraSensitivity; + float mCameraYMultiplier; + + ICS::InputControlSystem* mInputBinder; + SDLUtil::InputWrapper* mInputWrapper; + float mInvUiScalingFactor; + + float mGuiCursorX; + float mGuiCursorY; + int mMouseWheel; + bool mMouseLookEnabled; + bool mControlsDisabled; + bool mGuiCursorEnabled; + }; +} +#endif From ce40294124964c1298858d52a7a87659d83f42e7 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 19:33:07 +0400 Subject: [PATCH 05/23] Move input actions handling to the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwinput/actionmanager.cpp | 484 ++++++++++++++++++++++++ apps/openmw/mwinput/actionmanager.hpp | 68 ++++ apps/openmw/mwinput/inputmanagerimp.cpp | 459 +--------------------- apps/openmw/mwinput/inputmanagerimp.hpp | 36 +- 5 files changed, 572 insertions(+), 477 deletions(-) create mode 100644 apps/openmw/mwinput/actionmanager.cpp create mode 100644 apps/openmw/mwinput/actionmanager.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index b5ea4fabf8..255bbbec1a 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - actions inputmanagerimp mousemanager sdlmappings sensormanager + actions actionmanager inputmanagerimp mousemanager sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp new file mode 100644 index 0000000000..22c7d96a6f --- /dev/null +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -0,0 +1,484 @@ +#include "actionmanager.hpp" + +#include + +#include + +#include + +#include + +#include "../mwbase/inputmanager.hpp" +#include "../mwbase/statemanager.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/mechanicsmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" +#include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" +#include "../mwworld/esmstore.hpp" + +#include "../mwmechanics/npcstats.hpp" +#include "../mwmechanics/actorutil.hpp" + +#include "actions.hpp" + +namespace MWInput +{ + const float ZOOM_SCALE = 120.f; /// Used for scrolling camera in and out + const int fakeDeviceID = 1; + + ActionManager::ActionManager(ICS::InputControlSystem* inputBinder, + osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, + osg::ref_ptr viewer, + osg::ref_ptr screenCaptureHandler) + : mInputBinder(inputBinder) + , mViewer(viewer) + , mScreenCaptureHandler(screenCaptureHandler) + , mScreenCaptureOperation(screenCaptureOperation) + , mAlwaysRunActive(Settings::Manager::getBool("always run", "Input")) + , mSneaking(false) + { + } + + void ActionManager::executeAction(int action) + { + // trigger action activated + switch (action) + { + case A_GameMenu: + toggleMainMenu (); + break; + case A_Screenshot: + screenshot(); + break; + case A_Inventory: + toggleInventory (); + break; + case A_Console: + toggleConsole (); + break; + case A_Activate: + MWBase::Environment::get().getInputManager()->resetIdleTime(); + activate(); + break; + case A_MoveLeft: + case A_MoveRight: + case A_MoveForward: + case A_MoveBackward: + handleGuiArrowKey(action); + break; + case A_Journal: + toggleJournal (); + break; + case A_AutoMove: + toggleAutoMove (); + break; + case A_AlwaysRun: + toggleWalking (); + break; + case A_ToggleWeapon: + toggleWeapon (); + break; + case A_Rest: + rest(); + break; + case A_ToggleSpell: + toggleSpell (); + break; + case A_QuickKey1: + quickKey(1); + break; + case A_QuickKey2: + quickKey(2); + break; + case A_QuickKey3: + quickKey(3); + break; + case A_QuickKey4: + quickKey(4); + break; + case A_QuickKey5: + quickKey(5); + break; + case A_QuickKey6: + quickKey(6); + break; + case A_QuickKey7: + quickKey(7); + break; + case A_QuickKey8: + quickKey(8); + break; + case A_QuickKey9: + quickKey(9); + break; + case A_QuickKey10: + quickKey(10); + break; + case A_QuickKeysMenu: + showQuickKeysMenu(); + break; + case A_ToggleHUD: + MWBase::Environment::get().getWindowManager()->toggleHud(); + break; + case A_ToggleDebug: + MWBase::Environment::get().getWindowManager()->toggleDebugWindow(); + break; + case A_ZoomIn: + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch") && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") && !MWBase::Environment::get().getWindowManager()->isGuiMode()) + MWBase::Environment::get().getWorld()->setCameraDistance(ZOOM_SCALE, true, true); + break; + case A_ZoomOut: + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch") && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") && !MWBase::Environment::get().getWindowManager()->isGuiMode()) + MWBase::Environment::get().getWorld()->setCameraDistance(-ZOOM_SCALE, true, true); + break; + case A_QuickSave: + quickSave(); + break; + case A_QuickLoad: + quickLoad(); + break; + case A_CycleSpellLeft: + if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic)) + MWBase::Environment::get().getWindowManager()->cycleSpell(false); + break; + case A_CycleSpellRight: + if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic)) + MWBase::Environment::get().getWindowManager()->cycleSpell(true); + break; + case A_CycleWeaponLeft: + if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) + MWBase::Environment::get().getWindowManager()->cycleWeapon(false); + break; + case A_CycleWeaponRight: + if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) + MWBase::Environment::get().getWindowManager()->cycleWeapon(true); + break; + case A_Sneak: + static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); + if (isToggleSneak) + { + toggleSneaking(); + } + break; + } + } + + bool isLeftOrRightButton(int action, ICS::InputControlSystem* ics, int deviceId, bool joystick) + { + int mouseBinding = ics->getMouseButtonBinding(ics->getControl(action), ICS::Control::INCREASE); + if (mouseBinding != ICS_MAX_DEVICE_BUTTONS) + return true; + int buttonBinding = ics->getJoystickButtonBinding(ics->getControl(action), deviceId, ICS::Control::INCREASE); + if (joystick && (buttonBinding == 0 || buttonBinding == 1)) + return true; + return false; + } + + bool ActionManager::checkAllowedToUseItems() const + { + MWWorld::Ptr player = MWMechanics::getPlayer(); + if (player.getClass().getNpcStats(player).isWerewolf()) + { + // Cannot use items or spells while in werewolf form + MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}"); + return false; + } + return true; + } + + void ActionManager::screenshot() + { + bool regularScreenshot = true; + + std::string settingStr; + + settingStr = Settings::Manager::getString("screenshot type","Video"); + regularScreenshot = settingStr.size() == 0 || settingStr.compare("regular") == 0; + + if (regularScreenshot) + { + mScreenCaptureHandler->setFramesToCapture(1); + mScreenCaptureHandler->captureNextFrame(*mViewer); + } + else + { + osg::ref_ptr screenshot (new osg::Image); + + if (MWBase::Environment::get().getWorld()->screenshot360(screenshot.get(),settingStr)) + { + (*mScreenCaptureOperation) (*(screenshot.get()),0); + // FIXME: mScreenCaptureHandler->getCaptureOperation() causes crash for some reason + } + } + } + + void ActionManager::toggleMainMenu() + { + if (MyGUI::InputManager::getInstance().isModalAny()) + { + MWBase::Environment::get().getWindowManager()->exitCurrentModal(); + return; + } + + if (MWBase::Environment::get().getWindowManager()->isConsoleMode()) + { + MWBase::Environment::get().getWindowManager()->toggleConsole(); + return; + } + + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) //No open GUIs, open up the MainMenu + { + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + } + else //Close current GUI + { + MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); + } + } + + void ActionManager::toggleSpell() + { + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + + // Not allowed before the magic window is accessible + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playermagic") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + return; + + if (!checkAllowedToUseItems()) + return; + + // Not allowed if no spell selected + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + MWWorld::InventoryStore& inventory = player.getPlayer().getClass().getInventoryStore(player.getPlayer()); + if (MWBase::Environment::get().getWindowManager()->getSelectedSpell().empty() && + inventory.getSelectedEnchantItem() == inventory.end()) + return; + + if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player.getPlayer())) + return; + + MWMechanics::DrawState_ state = player.getDrawState(); + if (state == MWMechanics::DrawState_Weapon || state == MWMechanics::DrawState_Nothing) + player.setDrawState(MWMechanics::DrawState_Spell); + else + player.setDrawState(MWMechanics::DrawState_Nothing); + } + + void ActionManager::quickLoad() + { + if (!MyGUI::InputManager::getInstance().isModalAny()) + MWBase::Environment::get().getStateManager()->quickLoad(); + } + + void ActionManager::quickSave() + { + if (!MyGUI::InputManager::getInstance().isModalAny()) + MWBase::Environment::get().getStateManager()->quickSave(); + } + + void ActionManager::toggleWeapon() + { + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + + // Not allowed before the inventory window is accessible + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playerfighting") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + return; + + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + // We want to interrupt animation only if attack is preparing, but still is not triggered + // Otherwise we will get a "speedshooting" exploit, when player can skip reload animation by hitting "Toggle Weapon" key twice + if (MWBase::Environment::get().getMechanicsManager()->isAttackPreparing(player.getPlayer())) + player.setAttackingOrSpell(false); + else if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player.getPlayer())) + return; + + MWMechanics::DrawState_ state = player.getDrawState(); + if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) + player.setDrawState(MWMechanics::DrawState_Weapon); + else + player.setDrawState(MWMechanics::DrawState_Nothing); + } + + void ActionManager::rest() + { + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + return; + + if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ()) + return; + + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_Rest); //Open rest GUI + } + + void ActionManager::toggleInventory() + { + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + return; + + if (MyGUI::InputManager::getInstance().isModalAny()) + return; + + if (MWBase::Environment::get().getWindowManager()->isConsoleMode()) + return; + + // Toggle between game mode and inventory mode + if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Inventory); + else + { + MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode(); + if(mode == MWGui::GM_Inventory || mode == MWGui::GM_Container) + MWBase::Environment::get().getWindowManager()->popGuiMode(); + } + + // .. but don't touch any other mode, except container. + } + + void ActionManager::toggleConsole() + { + if (MyGUI::InputManager::getInstance ().isModalAny()) + return; + + MWBase::Environment::get().getWindowManager()->toggleConsole(); + } + + void ActionManager::toggleJournal() + { + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + return; + if (MyGUI::InputManager::getInstance ().isModalAny()) + return; + + if(MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Journal + && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_MainMenu + && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings + && MWBase::Environment::get().getWindowManager ()->getJournalAllowed()) + { + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Journal); + } + else if(MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Journal)) + { + MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Journal); + } + } + + void ActionManager::quickKey (int index) + { + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playerfighting") || !MWBase::Environment::get().getInputManager()->getControlSwitch("playermagic")) + return; + if (!checkAllowedToUseItems()) + return; + + if (MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")!=-1) + return; + + if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) + MWBase::Environment::get().getWindowManager()->activateQuickKey (index); + } + + void ActionManager::showQuickKeysMenu() + { + if (!MWBase::Environment::get().getWindowManager()->isGuiMode () + && MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")==-1) + { + if (!checkAllowedToUseItems()) + return; + + MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_QuickKeysMenu); + } + else if (MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_QuickKeysMenu) + { + while(MyGUI::InputManager::getInstance().isModalAny()) + { //Handle any open Modal windows + MWBase::Environment::get().getWindowManager()->exitCurrentModal(); + } + MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); //And handle the actual main window + } + } + + void ActionManager::activate() + { + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); + if (!SDL_IsTextInputActive() && !isLeftOrRightButton(A_Activate, mInputBinder, fakeDeviceID, joystickUsed)) + MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0, false); + } + else if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + player.activate(); + } + } + + void ActionManager::toggleAutoMove() + { + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + player.setAutoMove (!player.getAutoMove()); + } + } + + void ActionManager::toggleWalking() + { + if (MWBase::Environment::get().getWindowManager()->isGuiMode() || SDL_IsTextInputActive()) return; + mAlwaysRunActive = !mAlwaysRunActive; + + Settings::Manager::setBool("always run", "Input", mAlwaysRunActive); + } + + void ActionManager::toggleSneaking() + { + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; + mSneaking = !mSneaking; + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + player.setSneak(mSneaking); + } + + void ActionManager::clear() + { + } + + void ActionManager::handleGuiArrowKey(int action) + { + bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); + // This is currently keyboard-specific code + // TODO: see if GUI controls can be refactored into a single function + if (joystickUsed) + return; + + if (SDL_IsTextInputActive()) + return; + + if (isLeftOrRightButton(action, mInputBinder, fakeDeviceID, joystickUsed)) + return; + + MyGUI::KeyCode key; + switch (action) + { + case A_MoveLeft: + key = MyGUI::KeyCode::ArrowLeft; + break; + case A_MoveRight: + key = MyGUI::KeyCode::ArrowRight; + break; + case A_MoveForward: + key = MyGUI::KeyCode::ArrowUp; + break; + case A_MoveBackward: + default: + key = MyGUI::KeyCode::ArrowDown; + break; + } + + MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false); + } +} diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp new file mode 100644 index 0000000000..7c1fe3f702 --- /dev/null +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -0,0 +1,68 @@ +#ifndef MWINPUT_ACTIONMANAGER_H +#define MWINPUT_ACTIONMANAGER_H + +#include +#include + +namespace ICS +{ + class InputControlSystem; +} + +namespace osgViewer +{ + class Viewer; + class ScreenCaptureHandler; +} + +namespace MWInput +{ + class ActionManager + { + public: + + ActionManager(ICS::InputControlSystem* inputBinder, + osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, + osg::ref_ptr viewer, + osg::ref_ptr screenCaptureHandler); + + void clear(); + + void executeAction(int action); + + bool checkAllowedToUseItems() const; + + void toggleMainMenu(); + void toggleSpell(); + void toggleWeapon(); + void toggleInventory(); + void toggleConsole(); + void screenshot(); + void toggleJournal(); + void activate(); + void toggleWalking(); + void toggleSneaking(); + void toggleAutoMove(); + void rest(); + void quickLoad(); + void quickSave(); + + void quickKey (int index); + void showQuickKeysMenu(); + + bool isAlwaysRunActive() const { return mAlwaysRunActive; }; + bool isSneaking() const { return mSneaking; }; + + private: + void handleGuiArrowKey(int action); + + ICS::InputControlSystem* mInputBinder; + osg::ref_ptr mViewer; + osg::ref_ptr mScreenCaptureHandler; + osgViewer::ScreenCaptureHandler::CaptureOperation* mScreenCaptureOperation; + + bool mAlwaysRunActive; + bool mSneaking; + }; +} +#endif diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index e79ec145a3..f332b03af5 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -30,6 +30,7 @@ #include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/actorutil.hpp" +#include "actionmanager.hpp" #include "mousemanager.hpp" #include "sdlmappings.hpp" #include "sensormanager.hpp" @@ -41,14 +42,10 @@ namespace MWInput osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler, osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, - const std::string& userFile, bool userFileExists, - const std::string& userControllerBindingsFile, + const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile, bool grab) : mWindow(window) , mWindowVisible(true) - , mViewer(viewer) - , mScreenCaptureHandler(screenCaptureHandler) - , mScreenCaptureOperation(screenCaptureOperation) , mJoystickLastUsed(false) , mPlayer(nullptr) , mInputManager(nullptr) @@ -56,8 +53,6 @@ namespace MWInput , mUserFile(userFile) , mDragDrop(false) , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) - , mInvertX (Settings::Manager::getBool("invert x axis", "Input")) - , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mControlsDisabled(false) , mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input")) , mPreviewPOVDelay(0.f) @@ -67,12 +62,8 @@ namespace MWInput , mDetectingKeyboard(false) , mOverencumberedMessageDelay(0.f) , mGamepadZoom(0) - , mUserFileExists(userFileExists) - , mAlwaysRunActive(Settings::Manager::getBool("always run", "Input")) - , mSneakToggles(Settings::Manager::getBool("toggle sneak", "Input")) , mSneakToggleShortcutTimer(0.f) , mSneakGamepadShortcut(false) - , mSneaking(false) , mAttemptJump(false) , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) , mFakeDeviceID(1) @@ -139,6 +130,8 @@ namespace MWInput mMouseManager = new MouseManager(mInputBinder, mInputManager, window); mInputManager->setMouseEventCallback (mMouseManager); + + mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); } void InputManager::clear() @@ -147,6 +140,7 @@ namespace MWInput for (std::map::iterator it = mControlSwitch.begin(); it != mControlSwitch.end(); ++it) it->second = true; + mActionManager->clear(); mSensorManager->clear(); mMouseManager->clear(); } @@ -155,6 +149,8 @@ namespace MWInput { mInputBinder->save (mUserFile); + delete mActionManager; + delete mMouseManager; delete mSensorManager; delete mInputBinder; @@ -183,51 +179,6 @@ namespace MWInput } } - bool isLeftOrRightButton(int action, ICS::InputControlSystem* ics, int deviceId, bool joystick) - { - int mouseBinding = ics->getMouseButtonBinding(ics->getControl(action), ICS::Control::INCREASE); - if (mouseBinding != ICS_MAX_DEVICE_BUTTONS) - return true; - int buttonBinding = ics->getJoystickButtonBinding(ics->getControl(action), deviceId, ICS::Control::INCREASE); - if (joystick && (buttonBinding == 0 || buttonBinding == 1)) - return true; - return false; - } - - void InputManager::handleGuiArrowKey(int action) - { - // This is currently keyboard-specific code - // TODO: see if GUI controls can be refactored into a single function - if (mJoystickLastUsed) - return; - - if (SDL_IsTextInputActive()) - return; - - if (isLeftOrRightButton(action, mInputBinder, mFakeDeviceID, mJoystickLastUsed)) - return; - - MyGUI::KeyCode key; - switch (action) - { - case A_MoveLeft: - key = MyGUI::KeyCode::ArrowLeft; - break; - case A_MoveRight: - key = MyGUI::KeyCode::ArrowRight; - break; - case A_MoveForward: - key = MyGUI::KeyCode::ArrowUp; - break; - case A_MoveBackward: - default: - key = MyGUI::KeyCode::ArrowDown; - break; - } - - MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false); - } - bool InputManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg) { // Presumption of GUI mode will be removed in the future. @@ -375,127 +326,7 @@ namespace MWInput } if (currentValue == 1) - { - // trigger action activated - switch (action) - { - case A_GameMenu: - toggleMainMenu (); - break; - case A_Screenshot: - screenshot(); - break; - case A_Inventory: - toggleInventory (); - break; - case A_Console: - toggleConsole (); - break; - case A_Activate: - resetIdleTime(); - activate(); - break; - case A_MoveLeft: - case A_MoveRight: - case A_MoveForward: - case A_MoveBackward: - handleGuiArrowKey(action); - break; - case A_Journal: - toggleJournal (); - break; - case A_AutoMove: - toggleAutoMove (); - break; - case A_AlwaysRun: - toggleWalking (); - break; - case A_ToggleWeapon: - toggleWeapon (); - break; - case A_Rest: - rest(); - break; - case A_ToggleSpell: - toggleSpell (); - break; - case A_QuickKey1: - quickKey(1); - break; - case A_QuickKey2: - quickKey(2); - break; - case A_QuickKey3: - quickKey(3); - break; - case A_QuickKey4: - quickKey(4); - break; - case A_QuickKey5: - quickKey(5); - break; - case A_QuickKey6: - quickKey(6); - break; - case A_QuickKey7: - quickKey(7); - break; - case A_QuickKey8: - quickKey(8); - break; - case A_QuickKey9: - quickKey(9); - break; - case A_QuickKey10: - quickKey(10); - break; - case A_QuickKeysMenu: - showQuickKeysMenu(); - break; - case A_ToggleHUD: - MWBase::Environment::get().getWindowManager()->toggleHud(); - break; - case A_ToggleDebug: - MWBase::Environment::get().getWindowManager()->toggleDebugWindow(); - break; - case A_ZoomIn: - if (mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"] && !MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWorld()->setCameraDistance(ZOOM_SCALE, true, true); - break; - case A_ZoomOut: - if (mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"] && !MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWorld()->setCameraDistance(-ZOOM_SCALE, true, true); - break; - case A_QuickSave: - quickSave(); - break; - case A_QuickLoad: - quickLoad(); - break; - case A_CycleSpellLeft: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic)) - MWBase::Environment::get().getWindowManager()->cycleSpell(false); - break; - case A_CycleSpellRight: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic)) - MWBase::Environment::get().getWindowManager()->cycleSpell(true); - break; - case A_CycleWeaponLeft: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) - MWBase::Environment::get().getWindowManager()->cycleWeapon(false); - break; - case A_CycleWeaponRight: - if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory)) - MWBase::Environment::get().getWindowManager()->cycleWeapon(true); - break; - case A_Sneak: - if (mSneakToggles) - { - toggleSneaking(); - } - break; - } - } + mActionManager->executeAction(action); } void InputManager::updateCursorMode() @@ -521,18 +352,6 @@ namespace MWInput } } - bool InputManager::checkAllowedToUseItems() const - { - MWWorld::Ptr player = MWMechanics::getPlayer(); - if (player.getClass().getNpcStats(player).isWerewolf()) - { - // Cannot use items or spells while in werewolf form - MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}"); - return false; - } - return true; - } - void InputManager::update(float dt, bool disableControls, bool disableEvents) { mControlsDisabled = disableControls; @@ -638,7 +457,8 @@ namespace MWInput mPlayer->setForwardBackward (1); } - if (!mSneakToggles) + static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); + if (!isToggleSneak) { if(mJoystickLastUsed) { @@ -649,20 +469,20 @@ namespace MWInput if(mSneakToggleShortcutTimer <= 0.3f) { mSneakGamepadShortcut = true; - toggleSneaking(); + mActionManager->toggleSneaking(); } else mSneakGamepadShortcut = false; } - if(!mSneaking) - toggleSneaking(); + if(!mActionManager->isSneaking()) + mActionManager->toggleSneaking(); mSneakToggleShortcutTimer = 0.f; } else { - if(!mSneakGamepadShortcut && mSneaking) - toggleSneaking(); + if(!mSneakGamepadShortcut && mActionManager->isSneaking()) + mActionManager->toggleSneaking(); if(mSneakToggleShortcutTimer <= 0.3f) mSneakToggleShortcutTimer += dt; } @@ -678,7 +498,7 @@ namespace MWInput mOverencumberedMessageDelay = 0.f; } - if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning) + if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning) mPlayer->setRunState(!actionIsActive(A_Run)); else mPlayer->setRunState(actionIsActive(A_Run)); @@ -773,12 +593,6 @@ namespace MWInput for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { - if (it->first == "Input" && it->second == "invert x axis") - mInvertX = Settings::Manager::getBool("invert x axis", "Input"); - - if (it->first == "Input" && it->second == "invert y axis") - mInvertY = Settings::Manager::getBool("invert y axis", "Input"); - if (it->first == "Input" && it->second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); @@ -808,6 +622,7 @@ namespace MWInput Settings::Manager::getBool("window border", "Video")); } + mMouseManager->processChangedSettings(changed); mSensorManager->processChangedSettings(changed); } @@ -1022,246 +837,6 @@ namespace MWInput MWBase::Environment::get().getStateManager()->requestQuit(); } - void InputManager::toggleMainMenu() - { - if (MyGUI::InputManager::getInstance().isModalAny()) - { - MWBase::Environment::get().getWindowManager()->exitCurrentModal(); - return; - } - - if (MWBase::Environment::get().getWindowManager()->isConsoleMode()) - { - MWBase::Environment::get().getWindowManager()->toggleConsole(); - return; - } - - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) //No open GUIs, open up the MainMenu - { - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); - } - else //Close current GUI - { - MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); - } - } - - void InputManager::quickLoad() { - if (!MyGUI::InputManager::getInstance().isModalAny()) - MWBase::Environment::get().getStateManager()->quickLoad(); - } - - void InputManager::quickSave() { - if (!MyGUI::InputManager::getInstance().isModalAny()) - MWBase::Environment::get().getStateManager()->quickSave(); - } - void InputManager::toggleSpell() - { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - - // Not allowed before the magic window is accessible - if (!mControlSwitch["playermagic"] || !mControlSwitch["playercontrols"]) - return; - - if (!checkAllowedToUseItems()) - return; - - // Not allowed if no spell selected - MWWorld::InventoryStore& inventory = mPlayer->getPlayer().getClass().getInventoryStore(mPlayer->getPlayer()); - if (MWBase::Environment::get().getWindowManager()->getSelectedSpell().empty() && - inventory.getSelectedEnchantItem() == inventory.end()) - return; - - if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(mPlayer->getPlayer())) - return; - - MWMechanics::DrawState_ state = mPlayer->getDrawState(); - if (state == MWMechanics::DrawState_Weapon || state == MWMechanics::DrawState_Nothing) - mPlayer->setDrawState(MWMechanics::DrawState_Spell); - else - mPlayer->setDrawState(MWMechanics::DrawState_Nothing); - } - - void InputManager::toggleWeapon() - { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - - // Not allowed before the inventory window is accessible - if (!mControlSwitch["playerfighting"] || !mControlSwitch["playercontrols"]) - return; - - // We want to interrupt animation only if attack is preparing, but still is not triggered - // Otherwise we will get a "speedshooting" exploit, when player can skip reload animation by hitting "Toggle Weapon" key twice - if (MWBase::Environment::get().getMechanicsManager()->isAttackPreparing(mPlayer->getPlayer())) - mPlayer->setAttackingOrSpell(false); - else if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(mPlayer->getPlayer())) - return; - - MWMechanics::DrawState_ state = mPlayer->getDrawState(); - if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing) - mPlayer->setDrawState(MWMechanics::DrawState_Weapon); - else - mPlayer->setDrawState(MWMechanics::DrawState_Nothing); - } - - void InputManager::rest() - { - if (!mControlSwitch["playercontrols"]) - return; - - if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ()) - return; - - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_Rest); //Open rest GUI - - } - - void InputManager::screenshot() - { - bool regularScreenshot = true; - - std::string settingStr; - - settingStr = Settings::Manager::getString("screenshot type","Video"); - regularScreenshot = settingStr.size() == 0 || settingStr.compare("regular") == 0; - - if (regularScreenshot) - { - mScreenCaptureHandler->setFramesToCapture(1); - mScreenCaptureHandler->captureNextFrame(*mViewer); - } - else - { - osg::ref_ptr screenshot (new osg::Image); - - if (MWBase::Environment::get().getWorld()->screenshot360(screenshot.get(),settingStr)) - { - (*mScreenCaptureOperation) (*(screenshot.get()),0); - // FIXME: mScreenCaptureHandler->getCaptureOperation() causes crash for some reason - } - } - } - - void InputManager::toggleInventory() - { - if (!mControlSwitch["playercontrols"]) - return; - - if (MyGUI::InputManager::getInstance ().isModalAny()) - return; - - if (MWBase::Environment::get().getWindowManager()->isConsoleMode()) - return; - - // Toggle between game mode and inventory mode - if(!MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Inventory); - else - { - MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode(); - if(mode == MWGui::GM_Inventory || mode == MWGui::GM_Container) - MWBase::Environment::get().getWindowManager()->popGuiMode(); - } - - // .. but don't touch any other mode, except container. - } - - void InputManager::toggleConsole() - { - if (MyGUI::InputManager::getInstance ().isModalAny()) - return; - - MWBase::Environment::get().getWindowManager()->toggleConsole(); - } - - void InputManager::toggleJournal() - { - if (!mControlSwitch["playercontrols"]) - return; - if (MyGUI::InputManager::getInstance ().isModalAny()) - return; - - if(MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Journal - && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_MainMenu - && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings - && MWBase::Environment::get().getWindowManager ()->getJournalAllowed()) - { - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Journal); - } - else if(MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Journal)) - { - MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Journal); - } - } - - void InputManager::quickKey (int index) - { - if (!mControlSwitch["playercontrols"] || !mControlSwitch["playerfighting"] || !mControlSwitch["playermagic"]) - return; - if (!checkAllowedToUseItems()) - return; - - if (MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")!=-1) - return; - - if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) - MWBase::Environment::get().getWindowManager()->activateQuickKey (index); - } - - void InputManager::showQuickKeysMenu() - { - if (!MWBase::Environment::get().getWindowManager()->isGuiMode () - && MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")==-1) - { - if (!checkAllowedToUseItems()) - return; - - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_QuickKeysMenu); - - } - else if (MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_QuickKeysMenu) { - while(MyGUI::InputManager::getInstance().isModalAny()) { //Handle any open Modal windows - MWBase::Environment::get().getWindowManager()->exitCurrentModal(); - } - MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); //And handle the actual main window - } - } - - void InputManager::activate() - { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - if (!SDL_IsTextInputActive() && !isLeftOrRightButton(A_Activate, mInputBinder, mFakeDeviceID, mJoystickLastUsed)) - MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0, false); - } - else if (mControlSwitch["playercontrols"]) - mPlayer->activate(); - } - - void InputManager::toggleAutoMove() - { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - - if (mControlSwitch["playercontrols"]) - mPlayer->setAutoMove (!mPlayer->getAutoMove()); - } - - void InputManager::toggleWalking() - { - if (MWBase::Environment::get().getWindowManager()->isGuiMode() || SDL_IsTextInputActive()) return; - mAlwaysRunActive = !mAlwaysRunActive; - - Settings::Manager::setBool("always run", "Input", mAlwaysRunActive); - } - - void InputManager::toggleSneaking() - { - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - if (!mControlSwitch["playercontrols"]) return; - mSneaking = !mSneaking; - mPlayer->setSneak(mSneaking); - } - void InputManager::resetIdleTime() { if (mTimeIdle < 0) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index f73aa7f3d1..761180f12d 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -21,6 +21,7 @@ namespace MWInput { + class ActionManager; class MouseManager; class SensorManager; } @@ -51,18 +52,10 @@ namespace SDLUtil class VideoWrapper; } -namespace osgViewer -{ - class Viewer; - class ScreenCaptureHandler; -} - struct SDL_Window; namespace MWInput { - const float ZOOM_SCALE = 120.f; /// Used for scrolling camera in and out - /** * @brief Class that handles all input and key bindings for OpenMW. */ @@ -167,9 +160,6 @@ namespace MWInput private: SDL_Window* mWindow; bool mWindowVisible; - osg::ref_ptr mViewer; - osg::ref_ptr mScreenCaptureHandler; - osgViewer::ScreenCaptureHandler::CaptureOperation *mScreenCaptureOperation; bool mJoystickLastUsed; MWWorld::Player* mPlayer; @@ -185,9 +175,6 @@ namespace MWInput bool mGrabCursor; - bool mInvertX; - bool mInvertY; - bool mControlsDisabled; bool mJoystickEnabled; @@ -202,12 +189,9 @@ namespace MWInput float mOverencumberedMessageDelay; float mGamepadZoom; - bool mUserFileExists; - bool mAlwaysRunActive; bool mSneakToggles; float mSneakToggleShortcutTimer; bool mSneakGamepadShortcut; - bool mSneaking; bool mAttemptJump; std::map mControlSwitch; @@ -215,6 +199,7 @@ namespace MWInput float mInvUiScalingFactor; float mGamepadCursorSpeed; + ActionManager* mActionManager; MouseManager* mMouseManager; SensorManager* mSensorManager; @@ -229,23 +214,6 @@ namespace MWInput void updateCursorMode(); - bool checkAllowedToUseItems() const; - - void toggleMainMenu(); - void toggleSpell(); - void toggleWeapon(); - void toggleInventory(); - void toggleConsole(); - void screenshot(); - void toggleJournal(); - void activate(); - void toggleWalking(); - void toggleSneaking(); - void toggleAutoMove(); - void rest(); - void quickLoad(); - void quickSave(); - void quickKey (int index); void showQuickKeysMenu(); From f9d6137a29c0c4b396ba51f27aaaf2b9103b5806 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 19:42:25 +0400 Subject: [PATCH 06/23] Do not store player reference in the InputManager --- apps/openmw/engine.cpp | 1 - apps/openmw/mwinput/inputmanagerimp.cpp | 72 +++++++++++++------------ apps/openmw/mwinput/inputmanagerimp.hpp | 2 - 3 files changed, 39 insertions(+), 36 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 7d63487896..efb3c01a35 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -561,7 +561,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mFileCollections, mContentFiles, mEncoder, mActivationDistanceOverride, mCellName, mStartupScript, mResDir.string(), mCfgMgr.getUserDataPath().string())); mEnvironment.getWorld()->setupPlayer(); - input->setPlayer(&mEnvironment.getWorld()->getPlayer()); window->setStore(mEnvironment.getWorld()->getStore()); window->initUI(); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index f332b03af5..4376951b5c 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -47,7 +47,6 @@ namespace MWInput : mWindow(window) , mWindowVisible(true) , mJoystickLastUsed(false) - , mPlayer(nullptr) , mInputManager(nullptr) , mVideoWrapper(nullptr) , mUserFile(userFile) @@ -308,8 +307,9 @@ namespace MWInput else { - MWMechanics::DrawState_ state = MWBase::Environment::get().getWorld()->getPlayer().getDrawState(); - mPlayer->setAttackingOrSpell(currentValue != 0 && state != MWMechanics::DrawState_Nothing); + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + MWMechanics::DrawState_ state = player.getDrawState(); + player.setAttackingOrSpell(currentValue != 0 && state != MWMechanics::DrawState_Nothing); } } else if (action == A_Jump) @@ -408,6 +408,8 @@ namespace MWInput // be done in the physics system. if (mControlSwitch["playercontrols"]) { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + bool triedToMove = false; bool isRunning = false; bool alwaysRunAllowed = false; @@ -418,14 +420,14 @@ namespace MWInput if (xAxis != .5) { triedToMove = true; - mPlayer->setLeftRight((xAxis - 0.5f) * 2); + player.setLeftRight((xAxis - 0.5f) * 2); } if (yAxis != .5) { triedToMove = true; - mPlayer->setAutoMove (false); - mPlayer->setForwardBackward((yAxis - 0.5f) * 2 * -1); + player.setAutoMove (false); + player.setForwardBackward((yAxis - 0.5f) * 2 * -1); } if (triedToMove) @@ -439,22 +441,22 @@ namespace MWInput { alwaysRunAllowed = true; triedToMove = true; - mPlayer->setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); + player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); } if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) { alwaysRunAllowed = true; triedToMove = true; - mPlayer->setAutoMove (false); - mPlayer->setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); + player.setAutoMove (false); + player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); } - if (mPlayer->getAutoMove()) + if (player.getAutoMove()) { alwaysRunAllowed = true; triedToMove = true; - mPlayer->setForwardBackward (1); + player.setForwardBackward (1); } static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); @@ -488,29 +490,29 @@ namespace MWInput } } else - mPlayer->setSneak(actionIsActive(A_Sneak)); + player.setSneak(actionIsActive(A_Sneak)); } if (mAttemptJump && mControlSwitch["playerjumping"]) { - mPlayer->setUpDown (1); + player.setUpDown (1); triedToMove = true; mOverencumberedMessageDelay = 0.f; } if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning) - mPlayer->setRunState(!actionIsActive(A_Run)); + player.setRunState(!actionIsActive(A_Run)); else - mPlayer->setRunState(actionIsActive(A_Run)); + player.setRunState(actionIsActive(A_Run)); // if player tried to start moving, but can't (due to being overencumbered), display a notification. if (triedToMove) { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); mOverencumberedMessageDelay -= dt; - if (player.getClass().getEncumbrance(player) > player.getClass().getCapacity(player)) + if (playerPtr.getClass().getEncumbrance(playerPtr) > playerPtr.getClass().getCapacity(playerPtr)) { - mPlayer->setAutoMove (false); + player.setAutoMove (false); if (mOverencumberedMessageDelay <= 0) { MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}"); @@ -633,19 +635,28 @@ namespace MWInput void InputManager::toggleControlSwitch (const std::string& sw, bool value) { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + /// \note 7 switches at all, if-else is relevant - if (sw == "playercontrols" && !value) { - mPlayer->setLeftRight(0); - mPlayer->setForwardBackward(0); - mPlayer->setAutoMove(false); - mPlayer->setUpDown(0); - } else if (sw == "playerjumping" && !value) { + if (sw == "playercontrols" && !value) + { + player.setLeftRight(0); + player.setForwardBackward(0); + player.setAutoMove(false); + player.setUpDown(0); + } + else if (sw == "playerjumping" && !value) + { /// \fixme maybe crouching at this time - mPlayer->setUpDown(0); - } else if (sw == "vanitymode") { + player.setUpDown(0); + } + else if (sw == "vanitymode") + { MWBase::Environment::get().getWorld()->allowVanityMode(value); - } else if (sw == "playerlooking" && !value) { - MWBase::Environment::get().getWorld()->rotateObject(mPlayer->getPlayer(), 0.f, 0.f, 0.f); + } + else if (sw == "playerlooking" && !value) + { + MWBase::Environment::get().getWorld()->rotateObject(player.getPlayer(), 0.f, 0.f, 0.f); } mControlSwitch[sw] = value; } @@ -1387,9 +1398,4 @@ namespace MWInput { loadControllerDefaults(true); } - - void InputManager::setPlayer (MWWorld::Player* player) - { - mPlayer = player; - } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 761180f12d..da7075e4e0 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -86,8 +86,6 @@ namespace MWInput virtual void update(float dt, bool disableControls=false, bool disableEvents=false); - void setPlayer (MWWorld::Player* player); - virtual void changeInputMode(bool guiMode); virtual void processChangedSettings(const Settings::CategorySettingVector& changed); From e353647d15c122e23eff2ecf55f6e62d5ba9eff8 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 22:02:53 +0400 Subject: [PATCH 07/23] Move gamepads handling to the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwinput/controllermanager.cpp | 409 ++++++++++++++++++++++ apps/openmw/mwinput/controllermanager.hpp | 77 ++++ apps/openmw/mwinput/inputmanagerimp.cpp | 364 ++----------------- apps/openmw/mwinput/inputmanagerimp.hpp | 28 +- apps/openmw/mwinput/mousemanager.hpp | 2 - 6 files changed, 525 insertions(+), 357 deletions(-) create mode 100644 apps/openmw/mwinput/controllermanager.cpp create mode 100644 apps/openmw/mwinput/controllermanager.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 255bbbec1a..4053208814 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - actions actionmanager inputmanagerimp mousemanager sdlmappings sensormanager + actions actionmanager controllermanager inputmanagerimp mousemanager sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp new file mode 100644 index 0000000000..ec687ed7b1 --- /dev/null +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -0,0 +1,409 @@ +#include "controllermanager.hpp" + +#include +#include +#include + +#include + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" +#include "../mwbase/statemanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include "actions.hpp" +#include "actionmanager.hpp" +#include "mousemanager.hpp" + +namespace MWInput +{ + static const int sFakeDeviceID = 1; + + ControllerManager::ControllerManager(ICS::InputControlSystem* inputBinder, + SDLUtil::InputWrapper* inputWrapper, + ActionManager* actionManager, + MouseManager* mouseManager, + const std::string& userControllerBindingsFile, + const std::string& controllerBindingsFile) + : mInputBinder(inputBinder) + , mInputWrapper(inputWrapper) + , mActionManager(actionManager) + , mMouseManager(mouseManager) + , mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input")) + , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) + , mInvUiScalingFactor(1.f) + , mSneakToggleShortcutTimer(0.f) + , mGamepadZoom(0) + , mGamepadGuiCursorEnabled(true) + , mControlsDisabled(false) + , mJoystickLastUsed(false) + , mSneakGamepadShortcut(false) + , mGamepadPreviewMode(false) + { + if(!controllerBindingsFile.empty()) + { + SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str()); + } + if(!userControllerBindingsFile.empty()) + { + SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str()); + } + + // Open all presently connected sticks + int numSticks = SDL_NumJoysticks(); + for(int i = 0; i < numSticks; i++) + { + if(SDL_IsGameController(i)) + { + SDL_ControllerDeviceEvent evt; + evt.which = i; + controllerAdded(sFakeDeviceID, evt); + Log(Debug::Info) << "Detected game controller: " << SDL_GameControllerNameForIndex(i); + } + else + { + Log(Debug::Info) << "Detected unusable controller: " << SDL_JoystickNameForIndex(i); + } + } + + float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); + if (uiScale != 0.f) + mInvUiScalingFactor = 1.f / uiScale; + } + + void ControllerManager::clear() + { + } + + void ControllerManager::processChangedSettings(const Settings::CategorySettingVector& changed) + { + for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + { + if (it->first == "Input" && it->second == "enable controller") + mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input"); + } + } + + bool ControllerManager::actionIsActive (int id) + { + return (mInputBinder->getChannel (id)->getValue ()==1.0); + } + + void ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode) + { + mControlsDisabled = disableControls; + mGamepadPreviewMode = gamepadPreviewMode; + + if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) + { + float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue()*2.0f-1.0f; + float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue()*2.0f-1.0f; + float zAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; + + xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); + yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); + + // 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 xMove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; + float yMove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; + if (xMove != 0 || yMove != 0 || zAxis != 0) + { + int mouseWheelMove = static_cast(-zAxis * dt * 1500.0f); + + mMouseManager->injectMouseMove(xMove, yMove, mouseWheelMove); + mMouseManager->warpMouse(); + MWBase::Environment::get().getWindowManager()->setCursorActive(true); + } + } + + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + + // Disable movement in Gui mode + if (MWBase::Environment::get().getWindowManager()->isGuiMode() + || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) + { + mGamepadZoom = 0; + return; + } + + // Configure player movement according to keyboard input. Actual movement will + // be done in the physics system. + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + bool triedToMove = false; + + // joystick movement + float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); + float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + if (xAxis != .5) + { + triedToMove = true; + player.setLeftRight((xAxis - 0.5f) * 2); + } + + if (yAxis != .5) + { + triedToMove = true; + player.setAutoMove (false); + player.setForwardBackward((yAxis - 0.5f) * 2 * -1); + } + + if (triedToMove) + mJoystickLastUsed = true; + + if(triedToMove) MWBase::Environment::get().getInputManager()->resetIdleTime(); + + static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); + if (!isToggleSneak) + { + if(mJoystickLastUsed) + { + if(actionIsActive(A_Sneak)) + { + if(mSneakToggleShortcutTimer) // New Sneak Button Press + { + if(mSneakToggleShortcutTimer <= 0.3f) + { + mSneakGamepadShortcut = true; + mActionManager->toggleSneaking(); + } + else + mSneakGamepadShortcut = false; + } + + if(!mActionManager->isSneaking()) + mActionManager->toggleSneaking(); + mSneakToggleShortcutTimer = 0.f; + } + else + { + if(!mSneakGamepadShortcut && mActionManager->isSneaking()) + mActionManager->toggleSneaking(); + if(mSneakToggleShortcutTimer <= 0.3f) + mSneakToggleShortcutTimer += dt; + } + } + else + player.setSneak(actionIsActive(A_Sneak)); + } + } + + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch")) + { + if (!actionIsActive(A_TogglePOV)) + mGamepadZoom = 0; + + if(mGamepadZoom) + { + MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom); + MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true); + } + } + } + + void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg ) + { + if (!mJoystickEnabled || mInputBinder->detectingBindingState()) + return; + + mJoystickLastUsed = true; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + if (gamepadToGuiControl(arg)) + return; + if (mGamepadGuiCursorEnabled) + { + // Temporary mouse binding until keyboard controls are available: + if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. + { + bool mousePressSuccess = mMouseManager->injectMouseButtonPress(SDL_BUTTON_LEFT); + if (MyGUI::InputManager::getInstance().getMouseFocusWidget()) + { + MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); + if (b && b->getEnabled()) + MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); + } + + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess); + } + } + } + else + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(true); + + //esc, to leave initial movie screen + auto kc = mInputWrapper->sdl2OISKeyCode(SDLK_ESCAPE); + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0)); + + if (!mControlsDisabled) + mInputBinder->buttonPressed(deviceID, arg); + } + + void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg ) + { + if(mInputBinder->detectingBindingState()) + { + mInputBinder->buttonReleased(deviceID, arg); + return; + } + if (!mJoystickEnabled || mControlsDisabled) + return; + + mJoystickLastUsed = true; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + if (mGamepadGuiCursorEnabled) + { + // Temporary mouse binding until keyboard controls are available: + if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. + { + bool mousePressSuccess = mMouseManager->injectMouseButtonRelease(SDL_BUTTON_LEFT); + if (mInputBinder->detectingBindingState()) // If the player just triggered binding, don't let button release bind. + return; + + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess); + } + } + } + else + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(true); + + //esc, to leave initial movie screen + auto kc = mInputWrapper->sdl2OISKeyCode(SDLK_ESCAPE); + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); + + mInputBinder->buttonReleased(deviceID, arg); + } + + void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) + { + if(!mJoystickEnabled || mControlsDisabled) + return; + + mJoystickLastUsed = true; + if (MWBase::Environment::get().getWindowManager()->isGuiMode()) + { + gamepadToGuiControl(arg); + } + else + { + if(mGamepadPreviewMode && arg.value) // Preview Mode Gamepad Zooming + { + if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + { + mGamepadZoom = arg.value * 0.85f / 1000.f; + return; // Do not propagate event. + } + else if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) + { + mGamepadZoom = -arg.value * 0.85f / 1000.f; + return; // Do not propagate event. + } + } + } + mInputBinder->axisMoved(deviceID, arg); + } + + void ControllerManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) + { + mInputBinder->controllerAdded(deviceID, arg); + } + + void ControllerManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) + { + mInputBinder->controllerRemoved(arg); + } + + bool ControllerManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg) + { + // Presumption of GUI mode will be removed in the future. + // MyGUI KeyCodes *may* change. + + MyGUI::KeyCode key = MyGUI::KeyCode::None; + switch (arg.button) + { + case SDL_CONTROLLER_BUTTON_DPAD_UP: + key = MyGUI::KeyCode::ArrowUp; + break; + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + key = MyGUI::KeyCode::ArrowRight; + break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + key = MyGUI::KeyCode::ArrowDown; + break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + key = MyGUI::KeyCode::ArrowLeft; + break; + case SDL_CONTROLLER_BUTTON_A: + // If we are using the joystick as a GUI mouse, A must be handled via mouse. + if (mGamepadGuiCursorEnabled) + return false; + key = MyGUI::KeyCode::Space; + break; + case SDL_CONTROLLER_BUTTON_B: + if (MyGUI::InputManager::getInstance().isModalAny()) + MWBase::Environment::get().getWindowManager()->exitCurrentModal(); + else + MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); + return true; + case SDL_CONTROLLER_BUTTON_X: + key = MyGUI::KeyCode::Semicolon; + break; + case SDL_CONTROLLER_BUTTON_Y: + key = MyGUI::KeyCode::Apostrophe; + break; + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + key = MyGUI::KeyCode::Period; + break; + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + key = MyGUI::KeyCode::Slash; + break; + case SDL_CONTROLLER_BUTTON_LEFTSTICK: + mGamepadGuiCursorEnabled = !mGamepadGuiCursorEnabled; + MWBase::Environment::get().getWindowManager()->setCursorActive(mGamepadGuiCursorEnabled); + return true; + default: + return false; + } + + // Some keys will work even when Text Input windows/modals are in focus. + if (SDL_IsTextInputActive()) + return false; + + MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false); + return true; + } + + bool ControllerManager::gamepadToGuiControl(const SDL_ControllerAxisEvent &arg) + { + switch (arg.axis) + { + case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: + if (arg.value == 32767) // Treat like a button. + MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Minus, 0, false); + break; + case SDL_CONTROLLER_AXIS_TRIGGERLEFT: + if (arg.value == 32767) // Treat like a button. + MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Equals, 0, false); + break; + case SDL_CONTROLLER_AXIS_LEFTX: + case SDL_CONTROLLER_AXIS_LEFTY: + case SDL_CONTROLLER_AXIS_RIGHTX: + case SDL_CONTROLLER_AXIS_RIGHTY: + // If we are using the joystick as a GUI mouse, process mouse movement elsewhere. + if (mGamepadGuiCursorEnabled) + return false; + break; + default: + return false; + } + + return true; + } +} diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp new file mode 100644 index 0000000000..2343cab397 --- /dev/null +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -0,0 +1,77 @@ +#ifndef MWINPUT_MWCONTROLLERMANAGER_H +#define MWINPUT_MWCONTROLLERMANAGER_H + +#include + +#include +#include +#include + +namespace ICS +{ + class InputControlSystem; +} + +namespace MWInput +{ + class ActionManager; + class MouseManager; + + class ControllerManager : public SDLUtil::ControllerListener + { + public: + ControllerManager(ICS::InputControlSystem* inputBinder, + SDLUtil::InputWrapper* inputWrapper, + ActionManager* actionManager, + MouseManager* mouseManager, + const std::string& userControllerBindingsFile, + const std::string& controllerBindingsFile); + + virtual ~ControllerManager() = default; + + void clear(); + + void update(float dt, bool disableControls, bool gamepadPreviewMode); + + virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); + virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); + virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); + virtual void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg); + virtual void controllerRemoved(const SDL_ControllerDeviceEvent &arg); + + void processChangedSettings(const Settings::CategorySettingVector& changed); + + void setJoystickLastUsed(bool enabled) { mJoystickLastUsed = enabled; } + bool joystickLastUsed() { return mJoystickLastUsed; } + + void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } + + void setGamepadGuiCursorEnabled(bool enabled) { mGamepadGuiCursorEnabled = enabled; } + bool gamepadGuiCursorEnabled() { return mGamepadGuiCursorEnabled; } + + private: + // Return true if GUI consumes input. + bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg); + bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg); + + bool actionIsActive(int id); + + ICS::InputControlSystem* mInputBinder; + SDLUtil::InputWrapper* mInputWrapper; + ActionManager* mActionManager; + MouseManager* mMouseManager; + + bool mJoystickEnabled; + float mGamepadCursorSpeed; + float mInvUiScalingFactor; + float mSneakToggleShortcutTimer; + float mGamepadZoom; + bool mGamepadGuiCursorEnabled; + bool mControlsDisabled; + bool mJoystickLastUsed; + bool mGuiCursorEnabled; + bool mSneakGamepadShortcut; + bool mGamepadPreviewMode; + }; +} +#endif diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 4376951b5c..a647aac20e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -31,6 +31,7 @@ #include "../mwmechanics/actorutil.hpp" #include "actionmanager.hpp" +#include "controllermanager.hpp" #include "mousemanager.hpp" #include "sdlmappings.hpp" #include "sensormanager.hpp" @@ -46,31 +47,23 @@ namespace MWInput const std::string& controllerBindingsFile, bool grab) : mWindow(window) , mWindowVisible(true) - , mJoystickLastUsed(false) , mInputManager(nullptr) , mVideoWrapper(nullptr) , mUserFile(userFile) , mDragDrop(false) , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) , mControlsDisabled(false) - , mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input")) , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) , mGuiCursorEnabled(true) - , mGamepadGuiCursorEnabled(true) , mDetectingKeyboard(false) , mOverencumberedMessageDelay(0.f) - , mGamepadZoom(0) - , mSneakToggleShortcutTimer(0.f) - , mSneakGamepadShortcut(false) , mAttemptJump(false) - , mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input")) , mFakeDeviceID(1) { mInputManager = new SDLUtil::InputWrapper(window, viewer, grab); mInputManager->setKeyboardEventCallback (this); mInputManager->setWindowEventCallback(this); - mInputManager->setControllerEventCallback(this); mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer); mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), @@ -95,42 +88,16 @@ namespace MWInput mControlSwitch["playerviewswitch"] = true; mControlSwitch["vanitymode"] = true; - /* Joystick Init */ - - // Load controller mappings - if(!controllerBindingsFile.empty()) - { - SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str()); - } - if(!userControllerBindingsFile.empty()) - { - SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str()); - } - - // Open all presently connected sticks - int numSticks = SDL_NumJoysticks(); - for(int i = 0; i < numSticks; i++) - { - if(SDL_IsGameController(i)) - { - SDL_ControllerDeviceEvent evt; - evt.which = i; - controllerAdded(mFakeDeviceID, evt); - Log(Debug::Info) << "Detected game controller: " << SDL_GameControllerNameForIndex(i); - } - else - { - Log(Debug::Info) << "Detected unusable controller: " << SDL_JoystickNameForIndex(i); - } - } - - mSensorManager = new SensorManager(); - mInputManager->setSensorEventCallback (mSensorManager); + mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); mMouseManager = new MouseManager(mInputBinder, mInputManager, window); mInputManager->setMouseEventCallback (mMouseManager); - mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); + mControllerManager = new ControllerManager(mInputBinder, mInputManager, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); + mInputManager->setControllerEventCallback(mControllerManager); + + mSensorManager = new SensorManager(); + mInputManager->setSensorEventCallback (mSensorManager); } void InputManager::clear() @@ -140,6 +107,7 @@ namespace MWInput it->second = true; mActionManager->clear(); + mControllerManager->clear(); mSensorManager->clear(); mMouseManager->clear(); } @@ -149,6 +117,7 @@ namespace MWInput mInputBinder->save (mUserFile); delete mActionManager; + delete mControllerManager; delete mMouseManager; delete mSensorManager; @@ -178,93 +147,6 @@ namespace MWInput } } - bool InputManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg) - { - // Presumption of GUI mode will be removed in the future. - // MyGUI KeyCodes *may* change. - - MyGUI::KeyCode key = MyGUI::KeyCode::None; - switch (arg.button) - { - case SDL_CONTROLLER_BUTTON_DPAD_UP: - key = MyGUI::KeyCode::ArrowUp; - break; - case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: - key = MyGUI::KeyCode::ArrowRight; - break; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: - key = MyGUI::KeyCode::ArrowDown; - break; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: - key = MyGUI::KeyCode::ArrowLeft; - break; - case SDL_CONTROLLER_BUTTON_A: - // If we are using the joystick as a GUI mouse, A must be handled via mouse. - if (mGamepadGuiCursorEnabled) - return false; - key = MyGUI::KeyCode::Space; - break; - case SDL_CONTROLLER_BUTTON_B: - if (MyGUI::InputManager::getInstance().isModalAny()) - MWBase::Environment::get().getWindowManager()->exitCurrentModal(); - else - MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); - return true; - case SDL_CONTROLLER_BUTTON_X: - key = MyGUI::KeyCode::Semicolon; - break; - case SDL_CONTROLLER_BUTTON_Y: - key = MyGUI::KeyCode::Apostrophe; - break; - case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: - key = MyGUI::KeyCode::Period; - break; - case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: - key = MyGUI::KeyCode::Slash; - break; - case SDL_CONTROLLER_BUTTON_LEFTSTICK: - mGamepadGuiCursorEnabled = !mGamepadGuiCursorEnabled; - MWBase::Environment::get().getWindowManager()->setCursorActive(mGamepadGuiCursorEnabled); - return true; - default: - return false; - } - - // Some keys will work even when Text Input windows/modals are in focus. - if (SDL_IsTextInputActive()) - return false; - - MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false); - return true; - } - - bool InputManager::gamepadToGuiControl(const SDL_ControllerAxisEvent &arg) - { - switch (arg.axis) - { - case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - if (arg.value == 32767) // Treat like a button. - MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Minus, 0, false); - break; - case SDL_CONTROLLER_AXIS_TRIGGERLEFT: - if (arg.value == 32767) // Treat like a button. - MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Equals, 0, false); - break; - case SDL_CONTROLLER_AXIS_LEFTX: - case SDL_CONTROLLER_AXIS_LEFTY: - case SDL_CONTROLLER_AXIS_RIGHTX: - case SDL_CONTROLLER_AXIS_RIGHTY: - // If we are using the joystick as a GUI mouse, process mouse movement elsewhere. - if (mGamepadGuiCursorEnabled) - return false; - break; - default: - return false; - } - - return true; - } - void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) { resetIdleTime (); @@ -297,12 +179,13 @@ namespace MWInput if (mControlSwitch["playercontrols"]) { + bool joystickUsed = mControllerManager->joystickLastUsed(); if (action == A_Use) { - if(mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) action = A_CycleWeaponRight; - else if (mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) + else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) action = A_CycleSpellRight; else @@ -314,10 +197,10 @@ namespace MWInput } else if (action == A_Jump) { - if(mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) action = A_CycleWeaponLeft; - else if (mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) + else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) action = A_CycleSpellLeft; else @@ -371,28 +254,7 @@ namespace MWInput updateCursorMode(); - if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) - { - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue()*2.0f-1.0f; - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue()*2.0f-1.0f; - float zAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; - - xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); - yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); - - // 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 xMove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; - float yMove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed; - if (xMove != 0|| yMove != 0 || zAxis != 0) - { - int mouseWheelMove = static_cast(-zAxis * dt * 1500.0f); - - mMouseManager->injectMouseMove(xMove, yMove, mouseWheelMove); - mMouseManager->warpMouse(); - MWBase::Environment::get().getWindowManager()->setCursorActive(true); - } - } + mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f); if (mMouseManager->update(dt, disableControls)) resetIdleTime(); @@ -414,28 +276,10 @@ namespace MWInput bool isRunning = false; bool alwaysRunAllowed = false; - // joystick movement + // keyboard movement float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); - if (xAxis != .5) - { - triedToMove = true; - player.setLeftRight((xAxis - 0.5f) * 2); - } - - if (yAxis != .5) - { - triedToMove = true; - player.setAutoMove (false); - player.setForwardBackward((yAxis - 0.5f) * 2 * -1); - } - - if (triedToMove) - mJoystickLastUsed = true; - - // keyboard movement isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; - if(triedToMove) resetIdleTime(); if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) { @@ -462,34 +306,7 @@ namespace MWInput static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); if (!isToggleSneak) { - if(mJoystickLastUsed) - { - if(actionIsActive(A_Sneak)) - { - if(mSneakToggleShortcutTimer) // New Sneak Button Press - { - if(mSneakToggleShortcutTimer <= 0.3f) - { - mSneakGamepadShortcut = true; - mActionManager->toggleSneaking(); - } - else - mSneakGamepadShortcut = false; - } - - if(!mActionManager->isSneaking()) - mActionManager->toggleSneaking(); - mSneakToggleShortcutTimer = 0.f; - } - else - { - if(!mSneakGamepadShortcut && mActionManager->isSneaking()) - mActionManager->toggleSneaking(); - if(mSneakToggleShortcutTimer <= 0.3f) - mSneakToggleShortcutTimer += dt; - } - } - else + if(!mControllerManager->joystickLastUsed()) player.setSneak(actionIsActive(A_Sneak)); } @@ -537,13 +354,6 @@ namespace MWInput MWBase::Environment::get().getWorld()->togglePOV(); } mPreviewPOVDelay = 0.f; - mGamepadZoom = 0; - } - - if(mGamepadZoom) - { - MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom); - MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true); } } } @@ -562,8 +372,6 @@ namespace MWInput updateIdleTime(dt); } } - else - mGamepadZoom = 0; mAttemptJump = false; // Can only jump on first frame input is on } @@ -574,17 +382,18 @@ namespace MWInput void InputManager::setGamepadGuiCursorEnabled(bool enabled) { - mGamepadGuiCursorEnabled = enabled; + mControllerManager->setGamepadGuiCursorEnabled(enabled); } void InputManager::changeInputMode(bool guiMode) { mGuiCursorEnabled = guiMode; - mMouseManager->setGuiCursorEnabled(guiMode); - mMouseManager->setMouseLookEnabled(!guiMode); + mControllerManager->setGuiCursorEnabled(mGuiCursorEnabled); + mMouseManager->setGuiCursorEnabled(mGuiCursorEnabled); + mMouseManager->setMouseLookEnabled(!mGuiCursorEnabled); if (guiMode) MWBase::Environment::get().getWindowManager()->showCrosshair(false); - MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mJoystickLastUsed || mGamepadGuiCursorEnabled)); + MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mControllerManager->joystickLastUsed() || mControllerManager->gamepadGuiCursorEnabled())); // if not in gui mode, the camera decides whether to show crosshair or not. } @@ -598,9 +407,6 @@ namespace MWInput if (it->first == "Input" && it->second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); - if (it->first == "Input" && it->second == "enable controller") - mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input"); - if (it->first == "Video" && ( it->second == "resolution x" || it->second == "resolution y" @@ -686,7 +492,7 @@ namespace MWInput if (!mControlsDisabled && !consumed) mInputBinder->keyPressed (arg); - mJoystickLastUsed = false; + mControllerManager->setJoystickLastUsed(false); } void InputManager::textInput(const SDL_TextInputEvent &arg) @@ -699,7 +505,7 @@ namespace MWInput void InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { - mJoystickLastUsed = false; + mControllerManager->setJoystickLastUsed(false); OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); if (!mInputBinder->detectingBindingState()) @@ -707,118 +513,6 @@ namespace MWInput mInputBinder->keyReleased (arg); } - void InputManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg ) - { - if (!mJoystickEnabled || mInputBinder->detectingBindingState()) - return; - - mJoystickLastUsed = true; - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - if (gamepadToGuiControl(arg)) - return; - if (mGamepadGuiCursorEnabled) - { - // Temporary mouse binding until keyboard controls are available: - if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. - { - bool mousePressSuccess = mMouseManager->injectMouseButtonPress(SDL_BUTTON_LEFT); - if (MyGUI::InputManager::getInstance().getMouseFocusWidget()) - { - MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); - if (b && b->getEnabled()) - MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); - } - - setPlayerControlsEnabled(!mousePressSuccess); - } - } - } - else - setPlayerControlsEnabled(true); - - //esc, to leave initial movie screen - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE); - setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0)); - - if (!mControlsDisabled) - mInputBinder->buttonPressed(deviceID, arg); - } - - void InputManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg ) - { - if(mInputBinder->detectingBindingState()) - { - mInputBinder->buttonReleased(deviceID, arg); - return; - } - if (!mJoystickEnabled || mControlsDisabled) - return; - - mJoystickLastUsed = true; - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - if (mGamepadGuiCursorEnabled) - { - // Temporary mouse binding until keyboard controls are available: - if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. - { - bool mousePressSuccess = mMouseManager->injectMouseButtonRelease(SDL_BUTTON_LEFT); - if (mInputBinder->detectingBindingState()) // If the player just triggered binding, don't let button release bind. - return; - - setPlayerControlsEnabled(!mousePressSuccess); - } - } - } - else - setPlayerControlsEnabled(true); - - //esc, to leave initial movie screen - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE); - setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); - - mInputBinder->buttonReleased(deviceID, arg); - } - - void InputManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg ) - { - if(!mJoystickEnabled || mControlsDisabled) - return; - - mJoystickLastUsed = true; - if (MWBase::Environment::get().getWindowManager()->isGuiMode()) - { - gamepadToGuiControl(arg); - } - else - { - if(mPreviewPOVDelay == 1.f && arg.value) // Preview Mode Gamepad Zooming - { - if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) - { - mGamepadZoom = arg.value * 0.85f / 1000.f; - return; // Do not propagate event. - } - else if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) - { - mGamepadZoom = -arg.value * 0.85f / 1000.f; - return; // Do not propagate event. - } - } - } - mInputBinder->axisMoved(deviceID, arg); - } - - void InputManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) - { - mInputBinder->controllerAdded(deviceID, arg); - } - void InputManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) - { - mInputBinder->controllerRemoved(arg); - } - void InputManager::windowFocusChange(bool have_focus) { } @@ -1398,4 +1092,14 @@ namespace MWInput { loadControllerDefaults(true); } + + void InputManager::setJoystickLastUsed(bool enabled) + { + mControllerManager->setJoystickLastUsed(enabled); + } + + bool InputManager::joystickLastUsed() + { + return mControllerManager->joystickLastUsed(); + } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index da7075e4e0..93bcf13ee2 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -22,6 +22,7 @@ namespace MWInput { class ActionManager; + class ControllerManager; class MouseManager; class SensorManager; } @@ -63,7 +64,6 @@ namespace MWInput public MWBase::InputManager, public SDLUtil::KeyListener, public SDLUtil::WindowListener, - public SDLUtil::ControllerListener, public ICS::ChannelListener, public ICS::DetectingBindingListener { @@ -106,19 +106,13 @@ namespace MWInput virtual void resetToDefaultKeyBindings(); virtual void resetToDefaultControllerBindings(); - virtual void setJoystickLastUsed(bool enabled) { mJoystickLastUsed = enabled; } - virtual bool joystickLastUsed() {return mJoystickLastUsed;} + virtual void setJoystickLastUsed(bool enabled); + virtual bool joystickLastUsed(); virtual void keyPressed(const SDL_KeyboardEvent &arg ); virtual void keyReleased( const SDL_KeyboardEvent &arg ); virtual void textInput (const SDL_TextInputEvent &arg); - virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); - virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); - virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); - virtual void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg); - virtual void controllerRemoved(const SDL_ControllerDeviceEvent &arg); - virtual void windowVisibilityChange( bool visible ); virtual void windowFocusChange( bool have_focus ); virtual void windowResized (int x, int y); @@ -159,9 +153,6 @@ namespace MWInput SDL_Window* mWindow; bool mWindowVisible; - bool mJoystickLastUsed; - MWWorld::Player* mPlayer; - ICS::InputControlSystem* mInputBinder; SDLUtil::InputWrapper* mInputManager; @@ -174,30 +165,22 @@ namespace MWInput bool mGrabCursor; bool mControlsDisabled; - bool mJoystickEnabled; float mPreviewPOVDelay; float mTimeIdle; bool mGuiCursorEnabled; - bool mGamepadGuiCursorEnabled; bool mDetectingKeyboard; float mOverencumberedMessageDelay; - float mGamepadZoom; - bool mSneakToggles; - float mSneakToggleShortcutTimer; - bool mSneakGamepadShortcut; bool mAttemptJump; std::map mControlSwitch; - float mInvUiScalingFactor; - float mGamepadCursorSpeed; - ActionManager* mActionManager; + ControllerManager* mControllerManager; MouseManager* mMouseManager; SensorManager* mSensorManager; @@ -206,9 +189,6 @@ namespace MWInput void updateIdleTime(float dt); void handleGuiArrowKey(int action); - // Return true if GUI consumes input. - bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg); - bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg); void updateCursorMode(); diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index c0a9408c68..f4517da47d 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -1,8 +1,6 @@ #ifndef MWINPUT_MWMOUSEMANAGER_H #define MWINPUT_MWMOUSEMANAGER_H -#include - #include #include From c368250e6a9bbb907f973d52069e5af04fb0cf29 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 15 Apr 2020 12:48:18 +0400 Subject: [PATCH 08/23] Rename misleading mInputManager variable --- apps/openmw/mwinput/inputmanagerimp.cpp | 35 ++++++++++++------------- apps/openmw/mwinput/inputmanagerimp.hpp | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index a647aac20e..ca07f66451 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -47,7 +47,7 @@ namespace MWInput const std::string& controllerBindingsFile, bool grab) : mWindow(window) , mWindowVisible(true) - , mInputManager(nullptr) + , mInputWrapper(nullptr) , mVideoWrapper(nullptr) , mUserFile(userFile) , mDragDrop(false) @@ -61,9 +61,9 @@ namespace MWInput , mAttemptJump(false) , mFakeDeviceID(1) { - mInputManager = new SDLUtil::InputWrapper(window, viewer, grab); - mInputManager->setKeyboardEventCallback (this); - mInputManager->setWindowEventCallback(this); + mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); + mInputWrapper->setKeyboardEventCallback (this); + mInputWrapper->setWindowEventCallback(this); mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer); mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), @@ -90,14 +90,14 @@ namespace MWInput mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); - mMouseManager = new MouseManager(mInputBinder, mInputManager, window); - mInputManager->setMouseEventCallback (mMouseManager); + mMouseManager = new MouseManager(mInputBinder, mInputWrapper, window); + mInputWrapper->setMouseEventCallback (mMouseManager); - mControllerManager = new ControllerManager(mInputBinder, mInputManager, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); - mInputManager->setControllerEventCallback(mControllerManager); + mControllerManager = new ControllerManager(mInputBinder, mInputWrapper, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); + mInputWrapper->setControllerEventCallback(mControllerManager); mSensorManager = new SensorManager(); - mInputManager->setSensorEventCallback (mSensorManager); + mInputWrapper->setSensorEventCallback (mSensorManager); } void InputManager::clear() @@ -123,8 +123,7 @@ namespace MWInput delete mInputBinder; - delete mInputManager; - + delete mInputWrapper; delete mVideoWrapper; } @@ -217,15 +216,15 @@ namespace MWInput bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) && !MWBase::Environment::get().getWindowManager()->isConsoleMode(); - bool was_relative = mInputManager->getMouseRelative(); + bool was_relative = mInputWrapper->getMouseRelative(); bool is_relative = !MWBase::Environment::get().getWindowManager()->isGuiMode(); // don't keep the pointer away from the window edge in gui mode // stop using raw mouse motions and switch to system cursor movements - mInputManager->setMouseRelative(is_relative); + mInputWrapper->setMouseRelative(is_relative); //we let the mouse escape in the main menu - mInputManager->setGrabPointer(grab && (mGrabCursor || is_relative)); + mInputWrapper->setGrabPointer(grab && (mGrabCursor || is_relative)); //we switched to non-relative mode, move our cursor to where the in-game //cursor is @@ -239,9 +238,9 @@ namespace MWInput { mControlsDisabled = disableControls; - mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible()); + mInputWrapper->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible()); - mInputManager->capture(disableEvents); + mInputWrapper->capture(disableEvents); if (mControlsDisabled) { @@ -472,7 +471,7 @@ namespace MWInput // HACK: to make Morrowind's default keybinding for the console work without printing an extra "^" upon closing // This assumes that SDL_TextInput events always come *after* the key event // (which is somewhat reasonable, and hopefully true for all SDL platforms) - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); + OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE) == arg.keysym.scancode && MWBase::Environment::get().getWindowManager()->isConsoleMode()) @@ -506,7 +505,7 @@ namespace MWInput void InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { mControllerManager->setJoystickLastUsed(false); - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); + OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); if (!mInputBinder->detectingBindingState()) setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 93bcf13ee2..e6c084a644 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -155,7 +155,7 @@ namespace MWInput ICS::InputControlSystem* mInputBinder; - SDLUtil::InputWrapper* mInputManager; + SDLUtil::InputWrapper* mInputWrapper; SDLUtil::VideoWrapper* mVideoWrapper; std::string mUserFile; From d3a9f893c839f05b699d6e7782cf01da90e887a5 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 16 Apr 2020 11:03:34 +0400 Subject: [PATCH 09/23] Move keyboard-specific code to the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwinput/controllermanager.cpp | 19 +-- apps/openmw/mwinput/controllermanager.hpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 118 +++-------------- apps/openmw/mwinput/inputmanagerimp.hpp | 9 +- apps/openmw/mwinput/keyboardmanager.cpp | 146 ++++++++++++++++++++++ apps/openmw/mwinput/keyboardmanager.hpp | 45 +++++++ apps/openmw/mwinput/sensormanager.hpp | 12 +- 8 files changed, 224 insertions(+), 129 deletions(-) create mode 100644 apps/openmw/mwinput/keyboardmanager.cpp create mode 100644 apps/openmw/mwinput/keyboardmanager.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 4053208814..97cc9b035f 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - actions actionmanager controllermanager inputmanagerimp mousemanager sdlmappings sensormanager + actions actionmanager controllermanager inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index ec687ed7b1..209800bd67 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -94,7 +94,7 @@ namespace MWInput return (mInputBinder->getChannel (id)->getValue ()==1.0); } - void ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode) + bool ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode) { mControlsDisabled = disableControls; mGamepadPreviewMode = gamepadPreviewMode; @@ -122,23 +122,21 @@ namespace MWInput } } - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - // Disable movement in Gui mode if (MWBase::Environment::get().getWindowManager()->isGuiMode() || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) { mGamepadZoom = 0; - return; + return false; } - // Configure player movement according to keyboard input. Actual movement will + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + bool triedToMove = false; + + // Configure player movement according to controller input. Actual movement will // be done in the physics system. if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) { - bool triedToMove = false; - - // joystick movement float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); if (xAxis != .5) @@ -157,7 +155,8 @@ namespace MWInput if (triedToMove) mJoystickLastUsed = true; - if(triedToMove) MWBase::Environment::get().getInputManager()->resetIdleTime(); + if (triedToMove) + MWBase::Environment::get().getInputManager()->resetIdleTime(); static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); if (!isToggleSneak) @@ -205,6 +204,8 @@ namespace MWInput MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true); } } + + return triedToMove; } void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg ) diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 2343cab397..77b68be54f 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -31,7 +31,7 @@ namespace MWInput void clear(); - void update(float dt, bool disableControls, bool gamepadPreviewMode); + bool update(float dt, bool disableControls, bool gamepadPreviewMode); virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index ca07f66451..d176ba480f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -32,6 +32,7 @@ #include "actionmanager.hpp" #include "controllermanager.hpp" +#include "keyboardmanager.hpp" #include "mousemanager.hpp" #include "sdlmappings.hpp" #include "sensormanager.hpp" @@ -47,12 +48,9 @@ namespace MWInput const std::string& controllerBindingsFile, bool grab) : mWindow(window) , mWindowVisible(true) - , mInputWrapper(nullptr) - , mVideoWrapper(nullptr) , mUserFile(userFile) , mDragDrop(false) , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) - , mControlsDisabled(false) , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) , mGuiCursorEnabled(true) @@ -62,7 +60,6 @@ namespace MWInput , mFakeDeviceID(1) { mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); - mInputWrapper->setKeyboardEventCallback (this); mInputWrapper->setWindowEventCallback(this); mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer); @@ -90,14 +87,17 @@ namespace MWInput mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); + mKeyboardManager = new KeyboardManager(mInputBinder, mInputWrapper, mActionManager); + mInputWrapper->setKeyboardEventCallback(mKeyboardManager); + mMouseManager = new MouseManager(mInputBinder, mInputWrapper, window); - mInputWrapper->setMouseEventCallback (mMouseManager); + mInputWrapper->setMouseEventCallback(mMouseManager); mControllerManager = new ControllerManager(mInputBinder, mInputWrapper, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); mInputWrapper->setControllerEventCallback(mControllerManager); mSensorManager = new SensorManager(); - mInputWrapper->setSensorEventCallback (mSensorManager); + mInputWrapper->setSensorEventCallback(mSensorManager); } void InputManager::clear() @@ -118,6 +118,7 @@ namespace MWInput delete mActionManager; delete mControllerManager; + delete mKeyboardManager; delete mMouseManager; delete mSensorManager; @@ -236,13 +237,11 @@ namespace MWInput void InputManager::update(float dt, bool disableControls, bool disableEvents) { - mControlsDisabled = disableControls; - mInputWrapper->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible()); mInputWrapper->capture(disableEvents); - if (mControlsDisabled) + if (disableControls) { updateCursorMode(); return; @@ -253,7 +252,8 @@ namespace MWInput updateCursorMode(); - mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f); + bool controllerMove = mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f); + bool keyboardMove = mKeyboardManager->update(dt, disableControls); if (mMouseManager->update(dt, disableControls)) resetIdleTime(); @@ -265,64 +265,20 @@ namespace MWInput if (!(MWBase::Environment::get().getWindowManager()->isGuiMode() || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)) { - // Configure player movement according to keyboard input. Actual movement will - // be done in the physics system. if (mControlSwitch["playercontrols"]) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - bool triedToMove = false; - bool isRunning = false; - bool alwaysRunAllowed = false; - - // keyboard movement - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); - isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; - - if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); - } - - if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setAutoMove (false); - player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); - } - - if (player.getAutoMove()) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setForwardBackward (1); - } - - static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); - if (!isToggleSneak) - { - if(!mControllerManager->joystickLastUsed()) - player.setSneak(actionIsActive(A_Sneak)); - } - + bool attemptToJump = false; if (mAttemptJump && mControlSwitch["playerjumping"]) { - player.setUpDown (1); - triedToMove = true; + player.setUpDown(1); + attemptToJump = true; mOverencumberedMessageDelay = 0.f; } - if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning) - player.setRunState(!actionIsActive(A_Run)); - else - player.setRunState(actionIsActive(A_Run)); - // if player tried to start moving, but can't (due to being overencumbered), display a notification. - if (triedToMove) + if (controllerMove || keyboardMove || attemptToJump) { MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); mOverencumberedMessageDelay -= dt; @@ -466,52 +422,6 @@ namespace MWInput mControlSwitch[sw] = value; } - void InputManager::keyPressed( const SDL_KeyboardEvent &arg ) - { - // HACK: to make Morrowind's default keybinding for the console work without printing an extra "^" upon closing - // This assumes that SDL_TextInput events always come *after* the key event - // (which is somewhat reasonable, and hopefully true for all SDL platforms) - OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); - if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE) - == arg.keysym.scancode - && MWBase::Environment::get().getWindowManager()->isConsoleMode()) - SDL_StopTextInput(); - - bool consumed = false; - if (kc != OIS::KC_UNASSIGNED && !mInputBinder->detectingBindingState()) - { - consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Enum(kc), 0, arg.repeat); - if (SDL_IsTextInputActive() && // Little trick to check if key is printable - ( !(SDLK_SCANCODE_MASK & arg.keysym.sym) && std::isprint(arg.keysym.sym))) - consumed = true; - setPlayerControlsEnabled(!consumed); - } - if (arg.repeat) - return; - - if (!mControlsDisabled && !consumed) - mInputBinder->keyPressed (arg); - mControllerManager->setJoystickLastUsed(false); - } - - void InputManager::textInput(const SDL_TextInputEvent &arg) - { - MyGUI::UString ustring(&arg.text[0]); - MyGUI::UString::utf32string utf32string = ustring.asUTF32(); - for (MyGUI::UString::utf32string::const_iterator it = utf32string.begin(); it != utf32string.end(); ++it) - MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it); - } - - void InputManager::keyReleased(const SDL_KeyboardEvent &arg ) - { - mControllerManager->setJoystickLastUsed(false); - OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); - - if (!mInputBinder->detectingBindingState()) - setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); - mInputBinder->keyReleased (arg); - } - void InputManager::windowFocusChange(bool have_focus) { } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index e6c084a644..ff0c43a82f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -23,6 +23,7 @@ namespace MWInput { class ActionManager; class ControllerManager; + class KeyboardManager; class MouseManager; class SensorManager; } @@ -62,7 +63,6 @@ namespace MWInput */ class InputManager : public MWBase::InputManager, - public SDLUtil::KeyListener, public SDLUtil::WindowListener, public ICS::ChannelListener, public ICS::DetectingBindingListener @@ -109,10 +109,6 @@ namespace MWInput virtual void setJoystickLastUsed(bool enabled); virtual bool joystickLastUsed(); - virtual void keyPressed(const SDL_KeyboardEvent &arg ); - virtual void keyReleased( const SDL_KeyboardEvent &arg ); - virtual void textInput (const SDL_TextInputEvent &arg); - virtual void windowVisibilityChange( bool visible ); virtual void windowFocusChange( bool have_focus ); virtual void windowResized (int x, int y); @@ -164,8 +160,6 @@ namespace MWInput bool mGrabCursor; - bool mControlsDisabled; - float mPreviewPOVDelay; float mTimeIdle; @@ -181,6 +175,7 @@ namespace MWInput ActionManager* mActionManager; ControllerManager* mControllerManager; + KeyboardManager* mKeyboardManager; MouseManager* mMouseManager; SensorManager* mSensorManager; diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp new file mode 100644 index 0000000000..f562467168 --- /dev/null +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -0,0 +1,146 @@ +#include "keyboardmanager.hpp" + +#include + +#include + +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" +#include "../mwbase/statemanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include "actionmanager.hpp" +#include "actions.hpp" + +namespace MWInput +{ + KeyboardManager::KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager) + : mInputBinder(inputBinder) + , mInputWrapper(inputWrapper) + , mActionManager(actionManager) + , mControlsDisabled(false) + { + } + + bool KeyboardManager::update(float dt, bool disableControls) + { + mControlsDisabled = disableControls; + + // Disable movement in Gui mode + if (MWBase::Environment::get().getWindowManager()->isGuiMode() + || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) + { + return false; + } + + // Configure player movement according to keyboard input. Actual movement will + // be done in the physics system. + if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + return false; + } + + bool triedToMove = false; + bool alwaysRunAllowed = false; + + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + + if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); + } + + if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setAutoMove (false); + player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); + } + + if (player.getAutoMove()) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setForwardBackward (1); + } + + if (triedToMove) + MWBase::Environment::get().getInputManager()->resetIdleTime(); + + static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); + if (!isToggleSneak) + { + if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) + player.setSneak(actionIsActive(A_Sneak)); + } + + float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); + float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; + if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning) + player.setRunState(!actionIsActive(A_Run)); + else + player.setRunState(actionIsActive(A_Run)); + + return triedToMove; + } + + bool KeyboardManager::actionIsActive (int id) + { + return (mInputBinder->getChannel(id)->getValue ()==1.0); + } + + void KeyboardManager::textInput(const SDL_TextInputEvent &arg) + { + MyGUI::UString ustring(&arg.text[0]); + MyGUI::UString::utf32string utf32string = ustring.asUTF32(); + for (MyGUI::UString::utf32string::const_iterator it = utf32string.begin(); it != utf32string.end(); ++it) + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it); + } + + void KeyboardManager::keyPressed(const SDL_KeyboardEvent &arg) + { + // HACK: to make Morrowind's default keybinding for the console work without printing an extra "^" upon closing + // This assumes that SDL_TextInput events always come *after* the key event + // (which is somewhat reasonable, and hopefully true for all SDL platforms) + OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); + if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE) + == arg.keysym.scancode + && MWBase::Environment::get().getWindowManager()->isConsoleMode()) + SDL_StopTextInput(); + + bool consumed = false; + if (kc != OIS::KC_UNASSIGNED && !mInputBinder->detectingBindingState()) + { + consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Enum(kc), 0, arg.repeat); + if (SDL_IsTextInputActive() && // Little trick to check if key is printable + ( !(SDLK_SCANCODE_MASK & arg.keysym.sym) && std::isprint(arg.keysym.sym))) + consumed = true; + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(!consumed); + } + if (arg.repeat) + return; + + if (!mControlsDisabled && !consumed) + mInputBinder->keyPressed(arg); + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); + } + + void KeyboardManager::keyReleased(const SDL_KeyboardEvent &arg) + { + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); + OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); + + if (!mInputBinder->detectingBindingState()) + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); + mInputBinder->keyReleased(arg); + } +} diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp new file mode 100644 index 0000000000..590241bc70 --- /dev/null +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -0,0 +1,45 @@ +#ifndef MWINPUT_MWKEYBOARDMANAGER_H +#define MWINPUT_MWKEYBOARDMANAGER_H + +#include +#include + +namespace SDLUtil +{ + class InputWrapper; +} + +namespace ICS +{ + class InputControlSystem; +} + +namespace MWInput +{ + class ActionManager; + + class KeyboardManager : public SDLUtil::KeyListener + { + public: + KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager); + + virtual ~KeyboardManager() = default; + + bool update(float dt, bool disableControls); + + virtual void textInput(const SDL_TextInputEvent &arg); + virtual void keyPressed(const SDL_KeyboardEvent &arg); + virtual void keyReleased(const SDL_KeyboardEvent &arg); + + private: + bool actionIsActive(int id); + + ICS::InputControlSystem* mInputBinder; + SDLUtil::InputWrapper* mInputWrapper; + + ActionManager* mActionManager; + + bool mControlsDisabled; + }; +} +#endif diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp index d655e9c078..51225e381c 100644 --- a/apps/openmw/mwinput/sensormanager.hpp +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -31,7 +31,6 @@ namespace MWInput bool update(float dt, bool isCursorEnabled, bool isTurningEnabled); - public: virtual void sensorUpdated(const SDL_SensorEvent &arg); virtual void displayOrientationChanged(); void processChangedSettings(const Settings::CategorySettingVector& changed); @@ -48,6 +47,11 @@ namespace MWInput Minus_Z = -3 }; + void updateSensors(); + void correctGyroscopeAxes(); + GyroscopeAxis mapGyroscopeAxis(const std::string& axis); + float getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const; + bool mInvertX; bool mInvertY; @@ -61,12 +65,6 @@ namespace MWInput GyroscopeAxis mGyroVAxis; float mGyroInputThreshold; - private: - - void updateSensors(); - void correctGyroscopeAxes(); - GyroscopeAxis mapGyroscopeAxis(const std::string& axis); - float getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const; SDL_Sensor* mGyroscope; }; } From 13b7c5b5196ae4e57cec6a587982714b25f3c1a1 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 16 Apr 2020 16:36:32 +0400 Subject: [PATCH 10/23] Rework actions update --- apps/openmw/mwinput/actionmanager.cpp | 154 ++++++++++++++++++++++ apps/openmw/mwinput/actionmanager.hpp | 17 +++ apps/openmw/mwinput/controllermanager.cpp | 10 +- apps/openmw/mwinput/controllermanager.hpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 108 ++------------- apps/openmw/mwinput/inputmanagerimp.hpp | 10 -- apps/openmw/mwinput/keyboardmanager.cpp | 63 +-------- apps/openmw/mwinput/keyboardmanager.hpp | 2 +- apps/openmw/mwinput/mousemanager.cpp | 8 +- apps/openmw/mwinput/mousemanager.hpp | 2 +- apps/openmw/mwinput/sensormanager.cpp | 13 +- apps/openmw/mwinput/sensormanager.hpp | 2 +- 12 files changed, 200 insertions(+), 191 deletions(-) diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index 22c7d96a6f..2240e75565 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -40,9 +40,163 @@ namespace MWInput , mScreenCaptureOperation(screenCaptureOperation) , mAlwaysRunActive(Settings::Manager::getBool("always run", "Input")) , mSneaking(false) + , mAttemptJump(false) + , mOverencumberedMessageDelay(0.f) + , mPreviewPOVDelay(0.f) + , mTimeIdle(0.f) { } + void ActionManager::update(float dt, bool triedToMove) + { + // Disable movement in Gui mode + if (MWBase::Environment::get().getWindowManager()->isGuiMode() + || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) + { + mAttemptJump = false; + return; + } + + // Configure player movement according to keyboard input. Actual movement will + // be done in the physics system. + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + bool alwaysRunAllowed = false; + + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + + if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); + } + + if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setAutoMove (false); + player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); + } + + if (player.getAutoMove()) + { + alwaysRunAllowed = true; + triedToMove = true; + player.setForwardBackward (1); + } + + if (mAttemptJump && MWBase::Environment::get().getInputManager()->getControlSwitch("playerjumping")) + { + player.setUpDown(1); + triedToMove = true; + mOverencumberedMessageDelay = 0.f; + } + + // if player tried to start moving, but can't (due to being overencumbered), display a notification. + if (triedToMove) + { + MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + mOverencumberedMessageDelay -= dt; + if (playerPtr.getClass().getEncumbrance(playerPtr) > playerPtr.getClass().getCapacity(playerPtr)) + { + player.setAutoMove (false); + if (mOverencumberedMessageDelay <= 0) + { + MWBase::Environment::get().getWindowManager()->messageBox("#{sNotifyMessage59}"); + mOverencumberedMessageDelay = 1.0; + } + } + } + + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch")) + { + if (actionIsActive(A_TogglePOV)) + { + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += dt) > 0.5) + { + mPreviewPOVDelay = 1.f; + MWBase::Environment::get().getWorld()->togglePreviewMode(true); + } + } + else + { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5) + { + MWBase::Environment::get().getWorld()->togglePOV(); + } + mPreviewPOVDelay = 0.f; + } + } + + if (triedToMove) + MWBase::Environment::get().getInputManager()->resetIdleTime(); + + static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); + if (!isToggleSneak) + { + if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) + player.setSneak(actionIsActive(A_Sneak)); + } + + float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); + float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; + if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning) + player.setRunState(!actionIsActive(A_Run)); + else + player.setRunState(actionIsActive(A_Run)); + } + + if (actionIsActive(A_MoveForward) || + actionIsActive(A_MoveBackward) || + actionIsActive(A_MoveLeft) || + actionIsActive(A_MoveRight) || + actionIsActive(A_Jump) || + actionIsActive(A_Sneak) || + actionIsActive(A_TogglePOV) || + actionIsActive(A_ZoomIn) || + actionIsActive(A_ZoomOut)) + { + resetIdleTime(); + } + else + { + updateIdleTime(dt); + } + + mAttemptJump = false; + } + + void ActionManager::resetIdleTime() + { + if (mTimeIdle < 0) + MWBase::Environment::get().getWorld()->toggleVanityMode(false); + mTimeIdle = 0.f; + } + + void ActionManager::updateIdleTime(float dt) + { + static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get() + .find("fVanityDelay")->mValue.getFloat(); + if (mTimeIdle >= 0.f) + mTimeIdle += dt; + if (mTimeIdle > vanityDelay) + { + MWBase::Environment::get().getWorld()->toggleVanityMode(true); + mTimeIdle = -1.f; + } + } + + bool ActionManager::actionIsActive(int id) + { + return (mInputBinder->getChannel(id)->getValue ()==1.0); + } + void ActionManager::executeAction(int action) { // trigger action activated diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp index 7c1fe3f702..399cb318c5 100644 --- a/apps/openmw/mwinput/actionmanager.hpp +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -28,6 +28,8 @@ namespace MWInput void clear(); + void update(float dt, bool triedToMove); + void executeAction(int action); bool checkAllowedToUseItems() const; @@ -50,12 +52,22 @@ namespace MWInput void quickKey (int index); void showQuickKeysMenu(); + void resetIdleTime(); + bool isAlwaysRunActive() const { return mAlwaysRunActive; }; bool isSneaking() const { return mSneaking; }; + void setAttemptJump(bool enabled) { mAttemptJump = enabled; } + + float getPreviewDelay() const { return mPreviewPOVDelay; }; + private: void handleGuiArrowKey(int action); + bool actionIsActive(int id); + + void updateIdleTime(float dt); + ICS::InputControlSystem* mInputBinder; osg::ref_ptr mViewer; osg::ref_ptr mScreenCaptureHandler; @@ -63,6 +75,11 @@ namespace MWInput bool mAlwaysRunActive; bool mSneaking; + bool mAttemptJump; + + float mOverencumberedMessageDelay; + float mPreviewPOVDelay; + float mTimeIdle; }; } #endif diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index 209800bd67..697d3ab91d 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -94,10 +94,10 @@ namespace MWInput return (mInputBinder->getChannel (id)->getValue ()==1.0); } - bool ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode) + bool ControllerManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; - mGamepadPreviewMode = gamepadPreviewMode; + mGamepadPreviewMode = mActionManager->getPreviewDelay() == 1.f; if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) { @@ -153,10 +153,10 @@ namespace MWInput } if (triedToMove) + { mJoystickLastUsed = true; - - if (triedToMove) MWBase::Environment::get().getInputManager()->resetIdleTime(); + } static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); if (!isToggleSneak) @@ -208,7 +208,7 @@ namespace MWInput return triedToMove; } - void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg ) + void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) { if (!mJoystickEnabled || mInputBinder->detectingBindingState()) return; diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 77b68be54f..1ab6ea76d8 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -31,7 +31,7 @@ namespace MWInput void clear(); - bool update(float dt, bool disableControls, bool gamepadPreviewMode); + bool update(float dt, bool disableControls); virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index d176ba480f..815283ba85 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -46,17 +46,12 @@ namespace MWInput osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile, bool grab) - : mWindow(window) - , mWindowVisible(true) + : mWindowVisible(true) , mUserFile(userFile) , mDragDrop(false) - , mGrabCursor (Settings::Manager::getBool("grab cursor", "Input")) - , mPreviewPOVDelay(0.f) - , mTimeIdle(0.f) + , mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) , mGuiCursorEnabled(true) , mDetectingKeyboard(false) - , mOverencumberedMessageDelay(0.f) - , mAttemptJump(false) , mFakeDeviceID(1) { mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); @@ -204,7 +199,7 @@ namespace MWInput action = A_CycleSpellLeft; else - mAttemptJump = (currentValue == 1.0 && previousValue == 0.0); + mActionManager->setAttemptJump(currentValue == 1.0 && previousValue == 0.0); } } @@ -252,82 +247,11 @@ namespace MWInput updateCursorMode(); - bool controllerMove = mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f); - bool keyboardMove = mKeyboardManager->update(dt, disableControls); - - if (mMouseManager->update(dt, disableControls)) - resetIdleTime(); - - if (mSensorManager->update(dt, mGuiCursorEnabled, mControlSwitch["playerlooking"])) - resetIdleTime(); - - // Disable movement in Gui mode - if (!(MWBase::Environment::get().getWindowManager()->isGuiMode() - || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)) - { - if (mControlSwitch["playercontrols"]) - { - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - - bool attemptToJump = false; - if (mAttemptJump && mControlSwitch["playerjumping"]) - { - player.setUpDown(1); - attemptToJump = true; - mOverencumberedMessageDelay = 0.f; - } - - // if player tried to start moving, but can't (due to being overencumbered), display a notification. - if (controllerMove || keyboardMove || attemptToJump) - { - MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - mOverencumberedMessageDelay -= dt; - if (playerPtr.getClass().getEncumbrance(playerPtr) > playerPtr.getClass().getCapacity(playerPtr)) - { - player.setAutoMove (false); - if (mOverencumberedMessageDelay <= 0) - { - MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}"); - mOverencumberedMessageDelay = 1.0; - } - } - } - - if (mControlSwitch["playerviewswitch"]) { - - if (actionIsActive(A_TogglePOV)) { - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += dt) > 0.5) - { - mPreviewPOVDelay = 1.f; - MWBase::Environment::get().getWorld()->togglePreviewMode(true); - } - } else { - //disable preview mode - MWBase::Environment::get().getWorld()->togglePreviewMode(false); - if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5) { - MWBase::Environment::get().getWorld()->togglePOV(); - } - mPreviewPOVDelay = 0.f; - } - } - } - if (actionIsActive(A_MoveForward) || - actionIsActive(A_MoveBackward) || - actionIsActive(A_MoveLeft) || - actionIsActive(A_MoveRight) || - actionIsActive(A_Jump) || - actionIsActive(A_Sneak) || - actionIsActive(A_TogglePOV) || - actionIsActive(A_ZoomIn) || - actionIsActive(A_ZoomOut) ) - { - resetIdleTime(); - } else { - updateIdleTime(dt); - } - } - mAttemptJump = false; // Can only jump on first frame input is on + bool controllerMove = mControllerManager->update(dt, disableControls); + mKeyboardManager->update(dt, disableControls); + mMouseManager->update(dt, disableControls); + mSensorManager->update(dt, mGuiCursorEnabled); + mActionManager->update(dt, controllerMove); } void InputManager::setDragDrop(bool dragDrop) @@ -453,21 +377,7 @@ namespace MWInput void InputManager::resetIdleTime() { - if (mTimeIdle < 0) - MWBase::Environment::get().getWorld()->toggleVanityMode(false); - mTimeIdle = 0.f; - } - - void InputManager::updateIdleTime(float dt) - { - static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get() - .find("fVanityDelay")->mValue.getFloat(); - if (mTimeIdle >= 0.f) - mTimeIdle += dt; - if (mTimeIdle > vanityDelay) { - MWBase::Environment::get().getWorld()->toggleVanityMode(true); - mTimeIdle = -1.f; - } + mActionManager->resetIdleTime(); } bool InputManager::actionIsActive (int id) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index ff0c43a82f..fc01fecab8 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -146,7 +146,6 @@ namespace MWInput virtual void resetIdleTime(); private: - SDL_Window* mWindow; bool mWindowVisible; ICS::InputControlSystem* mInputBinder; @@ -160,17 +159,10 @@ namespace MWInput bool mGrabCursor; - float mPreviewPOVDelay; - float mTimeIdle; - bool mGuiCursorEnabled; bool mDetectingKeyboard; - float mOverencumberedMessageDelay; - - bool mAttemptJump; - std::map mControlSwitch; ActionManager* mActionManager; @@ -181,8 +173,6 @@ namespace MWInput void convertMousePosForMyGUI(int& x, int& y); - void updateIdleTime(float dt); - void handleGuiArrowKey(int action); void updateCursorMode(); diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index f562467168..d043f81377 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -27,70 +27,9 @@ namespace MWInput { } - bool KeyboardManager::update(float dt, bool disableControls) + void KeyboardManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; - - // Disable movement in Gui mode - if (MWBase::Environment::get().getWindowManager()->isGuiMode() - || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) - { - return false; - } - - // Configure player movement according to keyboard input. Actual movement will - // be done in the physics system. - if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) - { - return false; - } - - bool triedToMove = false; - bool alwaysRunAllowed = false; - - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - - if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); - } - - if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setAutoMove (false); - player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); - } - - if (player.getAutoMove()) - { - alwaysRunAllowed = true; - triedToMove = true; - player.setForwardBackward (1); - } - - if (triedToMove) - MWBase::Environment::get().getInputManager()->resetIdleTime(); - - static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); - if (!isToggleSneak) - { - if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) - player.setSneak(actionIsActive(A_Sneak)); - } - - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); - bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; - if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning) - player.setRunState(!actionIsActive(A_Run)); - else - player.setRunState(actionIsActive(A_Run)); - - return triedToMove; } bool KeyboardManager::actionIsActive (int id) diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index 590241bc70..55b91bac44 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -25,7 +25,7 @@ namespace MWInput virtual ~KeyboardManager() = default; - bool update(float dt, bool disableControls); + void update(float dt, bool disableControls); virtual void textInput(const SDL_TextInputEvent &arg); virtual void keyPressed(const SDL_KeyboardEvent &arg); diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index b341247738..3fbfc78139 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -173,17 +173,17 @@ namespace MWInput mInputBinder->mousePressed (arg, id); } - bool MouseManager::update(float dt, bool disableControls) + void MouseManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; if (!mMouseLookEnabled) - return false; + return; float xAxis = mInputBinder->getChannel(A_LookLeftRight)->getValue()*2.0f-1.0f; float yAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; if (xAxis == 0 && yAxis == 0) - return false; + return; float rot[3]; rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; @@ -198,7 +198,7 @@ namespace MWInput player.pitch(rot[0]); } - return true; + MWBase::Environment::get().getInputManager()->resetIdleTime(); } bool MouseManager::injectMouseButtonPress(Uint8 button) diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index f4517da47d..6e59a639b7 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -30,7 +30,7 @@ namespace MWInput void clear(); - bool update(float dt, bool disableControls); + void update(float dt, bool disableControls); virtual void mouseMoved(const SDLUtil::MouseMotionEvent &arg); virtual void mousePressed(const SDL_MouseButtonEvent &arg, Uint8 id); diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index 55a0882f5d..27879d2141 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -3,6 +3,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" #include "../mwbase/world.hpp" #include "../mwworld/player.hpp" @@ -234,10 +235,10 @@ namespace MWInput } } - bool SensorManager::update(float dt, bool isCursorEnabled, bool isTurningEnabled) + void SensorManager::update(float dt, bool isCursorEnabled) { if (mGyroXSpeed == 0.f && mGyroYSpeed == 0.f) - return false; + return; if (mGyroUpdateTimer > 0.5f) { @@ -246,7 +247,7 @@ namespace MWInput // Reset current rotation speed and wait for update. clear(); mGyroUpdateTimer = 0.f; - return false; + return; } mGyroUpdateTimer += dt; @@ -259,16 +260,14 @@ namespace MWInput rot[2] = mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1); // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && isTurningEnabled) + if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking")) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); player.yaw(rot[2]); player.pitch(rot[0]); } - return true; + MWBase::Environment::get().getInputManager()->resetIdleTime(); } - - return false; } } diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp index 51225e381c..283a53c1f5 100644 --- a/apps/openmw/mwinput/sensormanager.hpp +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -29,7 +29,7 @@ namespace MWInput void clear(); - bool update(float dt, bool isCursorEnabled, bool isTurningEnabled); + void update(float dt, bool isCursorEnabled); virtual void sensorUpdated(const SDL_SensorEvent &arg); virtual void displayOrientationChanged(); From f990150c497483a099adfcf44192076e31d72d37 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 16 Apr 2020 17:31:20 +0400 Subject: [PATCH 11/23] Move video wrapper to the WindowsManager --- apps/openmw/engine.cpp | 10 ++-- apps/openmw/mwbase/inputmanager.hpp | 2 - apps/openmw/mwbase/windowmanager.hpp | 11 ++-- apps/openmw/mwgui/windowmanagerimp.cpp | 59 ++++++++++++++++++-- apps/openmw/mwgui/windowmanagerimp.hpp | 14 ++++- apps/openmw/mwinput/inputmanagerimp.cpp | 72 ++----------------------- apps/openmw/mwinput/inputmanagerimp.hpp | 12 ----- components/sdlutil/events.hpp | 3 -- components/sdlutil/sdlinputwrapper.cpp | 5 -- 9 files changed, 84 insertions(+), 104 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index efb3c01a35..0fd6a1cb5f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -96,7 +96,7 @@ bool OMW::Engine::frame(float frametime) // When the window is minimized, pause the game. Currently this *has* to be here to work around a MyGUI bug. // If we are not currently rendering, then RenderItems will not be reused resulting in a memory leak upon changing widget textures (fixed in MyGUI 3.3.2), // and destroyed widgets will not be deleted (not fixed yet, https://github.com/MyGUI/mygui/issues/21) - if (!mEnvironment.getInputManager()->isWindowVisible()) + if (!mEnvironment.getWindowManager()->isWindowVisible()) { mEnvironment.getSoundManager()->pausePlayback(); return false; @@ -532,20 +532,20 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) else gameControllerdb = ""; //if it doesn't exist, pass in an empty string - MWInput::InputManager* input = new MWInput::InputManager (mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab); - mEnvironment.setInputManager (input); - std::string myguiResources = (mResDir / "mygui").string(); osg::ref_ptr guiRoot = new osg::Group; guiRoot->setName("GUI Root"); guiRoot->setNodeMask(MWRender::Mask_GUI); rootNode->addChild(guiRoot); - MWGui::WindowManager* window = new MWGui::WindowManager(mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), + MWGui::WindowManager* window = new MWGui::WindowManager(mWindow, mViewer, guiRoot, mResourceSystem.get(), mWorkQueue.get(), mCfgMgr.getLogPath().string() + std::string("/"), myguiResources, mScriptConsoleMode, mTranslationDataStorage, mEncoding, mExportFonts, Version::getOpenmwVersionDescription(mResDir.string()), mCfgMgr.getUserConfigPath().string()); mEnvironment.setWindowManager (window); + MWInput::InputManager* input = new MWInput::InputManager (mWindow, mViewer, mScreenCaptureHandler, mScreenCaptureOperation, keybinderUser, keybinderUserExists, userGameControllerdb, gameControllerdb, mGrab); + mEnvironment.setInputManager (input); + // Create sound system mEnvironment.setSoundManager (new MWSound::SoundManager(mVFS.get(), mUseSound)); diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 29c876e2bf..601dd90e52 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -38,8 +38,6 @@ namespace MWBase virtual ~InputManager() {} - virtual bool isWindowVisible() = 0; - virtual void update(float dt, bool disableControls, bool disableEvents=false) = 0; virtual void changeInputMode(bool guiMode) = 0; diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index e8ae61fe59..2639fe5905 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -11,6 +11,8 @@ #include "../mwgui/mode.hpp" +#include + namespace Loading { class Listener; @@ -86,7 +88,7 @@ namespace SFO namespace MWBase { /// \brief Interface for widnow manager (implemented in MWGui) - class WindowManager + class WindowManager : public SDLUtil::WindowListener { WindowManager (const WindowManager&); ///< not implemented @@ -268,8 +270,6 @@ namespace MWBase virtual void processChangedSettings(const std::set< std::pair >& changed) = 0; - virtual void windowResized(int x, int y) = 0; - virtual void executeInConsole (const std::string& path) = 0; virtual void enableRest() = 0; @@ -360,6 +360,11 @@ namespace MWBase virtual bool injectKeyPress(MyGUI::KeyCode key, unsigned int text, bool repeat) = 0; virtual bool injectKeyRelease(MyGUI::KeyCode key) = 0; + + virtual void windowVisibilityChange(bool visible) = 0; + virtual void windowResized(int x, int y) = 0; + virtual void windowClosed() = 0; + virtual bool isWindowVisible() = 0; }; } diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 28521ac6fa..21e84613c4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include @@ -127,7 +128,7 @@ namespace MWGui { WindowManager::WindowManager( - osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, + SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, const std::string& resourcePath, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& userDataPath) : mOldUpdateMask(0) @@ -196,6 +197,7 @@ namespace MWGui , mEncoding(encoding) , mFontHeight(16) , mVersionDescription(versionDescription) + , mWindowVisible(true) { float uiScale = Settings::Manager::getFloat("scaling factor", "GUI"); mGuiPlatform = new osgMyGUI::Platform(viewer, guiRoot, resourceSystem->getImageManager(), uiScale); @@ -288,6 +290,10 @@ namespace MWGui MyGUI::ClipboardManager::getInstance().eventClipboardRequested += MyGUI::newDelegate(this, &WindowManager::onClipboardRequested); mShowOwned = Settings::Manager::getInt("show owned", "Game"); + + mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer); + mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), + Settings::Manager::getFloat("contrast", "Video")); } void WindowManager::loadFontDelegate(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version) @@ -653,6 +659,7 @@ namespace MWGui mGuiPlatform->shutdown(); delete mGuiPlatform; + delete mVideoWrapper; } catch(const MyGUI::Exception& e) { @@ -916,7 +923,7 @@ namespace MWGui mMessageBoxManager->onFrame(dt); MWBase::Environment::get().getInputManager()->update(dt, true, false); - if (!MWBase::Environment::get().getInputManager()->isWindowVisible()) + if (!mWindowVisible) OpenThreads::Thread::microSleep(5000); else { @@ -1241,6 +1248,7 @@ namespace MWGui { mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); + bool changeRes = false; for (const auto& setting : changed) { if (setting.first == "HUD" && setting.second == "crosshair") @@ -1249,11 +1257,38 @@ namespace MWGui mSubtitlesEnabled = Settings::Manager::getBool ("subtitles", "GUI"); else if (setting.first == "GUI" && setting.second == "menu transparency") setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); + else if (setting.first == "Video" && ( + setting.second == "resolution x" + || setting.second == "resolution y" + || setting.second == "fullscreen" + || setting.second == "window border")) + changeRes = true; + + else if (setting.first == "Video" && setting.second == "vsync") + mVideoWrapper->setSyncToVBlank(Settings::Manager::getBool("vsync", "Video")); + else if (setting.first == "Video" && (setting.second == "gamma" || setting.second == "contrast")) + mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), + Settings::Manager::getFloat("contrast", "Video")); + } + + if (changeRes) + { + mVideoWrapper->setVideoMode(Settings::Manager::getInt("resolution x", "Video"), + Settings::Manager::getInt("resolution y", "Video"), + Settings::Manager::getBool("fullscreen", "Video"), + Settings::Manager::getBool("window border", "Video")); } } void WindowManager::windowResized(int x, int y) { + // Note: this is a side effect of resolution change or window resize. + // There is no need to track these changes. + Settings::Manager::setInt("resolution x", "Video", x); + Settings::Manager::setInt("resolution y", "Video", y); + Settings::Manager::resetPendingChange("resolution x", "Video"); + Settings::Manager::resetPendingChange("resolution y", "Video"); + mGuiPlatform->getRenderManagerPtr()->setViewSize(x, y); // scaled size @@ -1283,9 +1318,27 @@ namespace MWGui for (WindowBase* window : mWindows) window->onResChange(x, y); + // We should reload TrueType fonts to fit new resolution + loadUserFonts(); + // TODO: check if any windows are now off-screen and move them back if so } + bool WindowManager::isWindowVisible() + { + return mWindowVisible; + } + + void WindowManager::windowVisibilityChange(bool visible) + { + mWindowVisible = visible; + } + + void WindowManager::windowClosed() + { + MWBase::Environment::get().getStateManager()->requestQuit(); + } + void WindowManager::onCursorChange(const std::string &name) { mCursorManager->cursorChanged(name); @@ -1925,7 +1978,7 @@ namespace MWGui MWBase::Environment::get().getInputManager()->update(dt, true, false); - if (!MWBase::Environment::get().getInputManager()->isWindowVisible()) + if (!mWindowVisible) { mVideoWidget->pause(); OpenThreads::Thread::microSleep(5000); diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 4e90f2e930..8b16cf25f4 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -15,6 +15,7 @@ #include "../mwworld/ptr.hpp" +#include #include #include @@ -70,6 +71,7 @@ namespace SceneUtil namespace SDLUtil { class SDLCursorManager; + class VideoWrapper; } namespace osgMyGUI @@ -124,13 +126,14 @@ namespace MWGui class JailScreen; class KeyboardNavigation; - class WindowManager : public MWBase::WindowManager + class WindowManager : + public MWBase::WindowManager { public: typedef std::pair Faction; typedef std::vector FactionList; - WindowManager(osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, + WindowManager(SDL_Window* window, osgViewer::Viewer* viewer, osg::Group* guiRoot, Resource::ResourceSystem* resourceSystem, SceneUtil::WorkQueue* workQueue, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage, ToUTF8::FromType encoding, bool exportFonts, const std::string& versionDescription, const std::string& localPath); virtual ~WindowManager(); @@ -296,7 +299,10 @@ namespace MWGui virtual void processChangedSettings(const Settings::CategorySettingVector& changed); + virtual void windowVisibilityChange(bool visible); virtual void windowResized(int x, int y); + virtual void windowClosed(); + virtual bool isWindowVisible(); virtual void executeInConsole (const std::string& path); @@ -529,10 +535,14 @@ namespace MWGui std::string mVersionDescription; + bool mWindowVisible; + MWGui::TextColours mTextColours; std::unique_ptr mKeyboardNavigation; + SDLUtil::VideoWrapper* mVideoWrapper; + /** * Called when MyGUI tries to retrieve a tag's value. Tags must be denoted in #{tag} notation and will be replaced upon setting a user visible text/property. * Supported syntax: diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 815283ba85..96806845e7 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -46,8 +45,7 @@ namespace MWInput osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile, bool grab) - : mWindowVisible(true) - , mUserFile(userFile) + : mUserFile(userFile) , mDragDrop(false) , mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) , mGuiCursorEnabled(true) @@ -55,11 +53,7 @@ namespace MWInput , mFakeDeviceID(1) { mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); - mInputWrapper->setWindowEventCallback(this); - - mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer); - mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), - Settings::Manager::getFloat("contrast", "Video")); + mInputWrapper->setWindowEventCallback(MWBase::Environment::get().getWindowManager()); std::string file = userFileExists ? userFile : ""; mInputBinder = new ICS::InputControlSystem(file, true, this, nullptr, A_Last); @@ -109,23 +103,16 @@ namespace MWInput InputManager::~InputManager() { - mInputBinder->save (mUserFile); - delete mActionManager; delete mControllerManager; delete mKeyboardManager; delete mMouseManager; delete mSensorManager; + mInputBinder->save(mUserFile); delete mInputBinder; delete mInputWrapper; - delete mVideoWrapper; - } - - bool InputManager::isWindowVisible() - { - return mWindowVisible; } void InputManager::setPlayerControlsEnabled(bool enabled) @@ -278,35 +265,11 @@ namespace MWInput void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - bool changeRes = false; - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { if (it->first == "Input" && it->second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); - - if (it->first == "Video" && ( - it->second == "resolution x" - || it->second == "resolution y" - || it->second == "fullscreen" - || it->second == "window border")) - changeRes = true; - - if (it->first == "Video" && it->second == "vsync") - mVideoWrapper->setSyncToVBlank(Settings::Manager::getBool("vsync", "Video")); - - if (it->first == "Video" && (it->second == "gamma" || it->second == "contrast")) - mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"), - Settings::Manager::getFloat("contrast", "Video")); - } - - if (changeRes) - { - mVideoWrapper->setVideoMode(Settings::Manager::getInt("resolution x", "Video"), - Settings::Manager::getInt("resolution y", "Video"), - Settings::Manager::getBool("fullscreen", "Video"), - Settings::Manager::getBool("window border", "Video")); } mMouseManager->processChangedSettings(changed); @@ -346,35 +309,6 @@ namespace MWInput mControlSwitch[sw] = value; } - void InputManager::windowFocusChange(bool have_focus) - { - } - - void InputManager::windowVisibilityChange(bool visible) - { - mWindowVisible = visible; - } - - void InputManager::windowResized(int x, int y) - { - // Note: this is a side effect of resolution change or window resize. - // There is no need to track these changes. - Settings::Manager::setInt("resolution x", "Video", x); - Settings::Manager::setInt("resolution y", "Video", y); - Settings::Manager::resetPendingChange("resolution x", "Video"); - Settings::Manager::resetPendingChange("resolution y", "Video"); - - MWBase::Environment::get().getWindowManager()->windowResized(x, y); - - // We should reload TrueType fonts to fit new resolution - MWBase::Environment::get().getWindowManager()->loadUserFonts(); - } - - void InputManager::windowClosed() - { - MWBase::Environment::get().getStateManager()->requestQuit(); - } - void InputManager::resetIdleTime() { mActionManager->resetIdleTime(); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index fc01fecab8..51561feac9 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -51,7 +51,6 @@ namespace Files namespace SDLUtil { class InputWrapper; - class VideoWrapper; } struct SDL_Window; @@ -63,7 +62,6 @@ namespace MWInput */ class InputManager : public MWBase::InputManager, - public SDLUtil::WindowListener, public ICS::ChannelListener, public ICS::DetectingBindingListener { @@ -79,8 +77,6 @@ namespace MWInput virtual ~InputManager(); - virtual bool isWindowVisible(); - /// Clear all savegame-specific data virtual void clear(); @@ -109,11 +105,6 @@ namespace MWInput virtual void setJoystickLastUsed(bool enabled); virtual bool joystickLastUsed(); - virtual void windowVisibilityChange( bool visible ); - virtual void windowFocusChange( bool have_focus ); - virtual void windowResized (int x, int y); - virtual void windowClosed (); - virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue); virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control @@ -146,12 +137,9 @@ namespace MWInput virtual void resetIdleTime(); private: - bool mWindowVisible; - ICS::InputControlSystem* mInputBinder; SDLUtil::InputWrapper* mInputWrapper; - SDLUtil::VideoWrapper* mVideoWrapper; std::string mUserFile; diff --git a/components/sdlutil/events.hpp b/components/sdlutil/events.hpp index 4d400e5b8d..a0dd11acec 100644 --- a/components/sdlutil/events.hpp +++ b/components/sdlutil/events.hpp @@ -79,9 +79,6 @@ public: /** @remarks The window's visibility changed */ virtual void windowVisibilityChange( bool visible ) {} - /** @remarks The window got / lost input focus */ - virtual void windowFocusChange( bool have_focus ) {} - virtual void windowClosed () {} virtual void windowResized (int x, int y) {} diff --git a/components/sdlutil/sdlinputwrapper.cpp b/components/sdlutil/sdlinputwrapper.cpp index 60997d281f..3ea11c6d03 100644 --- a/components/sdlutil/sdlinputwrapper.cpp +++ b/components/sdlutil/sdlinputwrapper.cpp @@ -231,15 +231,10 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr v case SDL_WINDOWEVENT_FOCUS_GAINED: mWindowHasFocus = true; updateMouseSettings(); - if (mWindowListener) - mWindowListener->windowFocusChange(true); - break; case SDL_WINDOWEVENT_FOCUS_LOST: mWindowHasFocus = false; updateMouseSettings(); - if (mWindowListener) - mWindowListener->windowFocusChange(false); break; case SDL_WINDOWEVENT_CLOSE: break; From 8512133bb1df6388b730c6f9ee518a67d9cafc8f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 16 Apr 2020 18:08:55 +0400 Subject: [PATCH 12/23] Move control switches to the separate file --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwinput/controlswitch.cpp | 58 +++++++++++++++++++++++++ apps/openmw/mwinput/controlswitch.hpp | 21 +++++++++ apps/openmw/mwinput/inputmanagerimp.cpp | 43 ++++-------------- apps/openmw/mwinput/inputmanagerimp.hpp | 3 +- 5 files changed, 90 insertions(+), 37 deletions(-) create mode 100644 apps/openmw/mwinput/controlswitch.cpp create mode 100644 apps/openmw/mwinput/controlswitch.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 97cc9b035f..d907091bda 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - actions actionmanager controllermanager inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager + actions actionmanager controllermanager controlswitch inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwinput/controlswitch.cpp b/apps/openmw/mwinput/controlswitch.cpp new file mode 100644 index 0000000000..6ea51064fc --- /dev/null +++ b/apps/openmw/mwinput/controlswitch.cpp @@ -0,0 +1,58 @@ +#include "controlswitch.hpp" + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +namespace MWInput +{ + ControlSwitch::ControlSwitch() + { + clear(); + } + + void ControlSwitch::clear() + { + mSwitches["playercontrols"] = true; + mSwitches["playerfighting"] = true; + mSwitches["playerjumping"] = true; + mSwitches["playerlooking"] = true; + mSwitches["playermagic"] = true; + mSwitches["playerviewswitch"] = true; + mSwitches["vanitymode"] = true; + } + + bool ControlSwitch::get(const std::string& key) + { + return mSwitches[key]; + } + + void ControlSwitch::set(const std::string& key, bool value) + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + + /// \note 7 switches at all, if-else is relevant + if (key == "playercontrols" && !value) + { + player.setLeftRight(0); + player.setForwardBackward(0); + player.setAutoMove(false); + player.setUpDown(0); + } + else if (key == "playerjumping" && !value) + { + /// \fixme maybe crouching at this time + player.setUpDown(0); + } + else if (key == "vanitymode") + { + MWBase::Environment::get().getWorld()->allowVanityMode(value); + } + else if (key == "playerlooking" && !value) + { + MWBase::Environment::get().getWorld()->rotateObject(player.getPlayer(), 0.f, 0.f, 0.f); + } + mSwitches[key] = value; + } +} diff --git a/apps/openmw/mwinput/controlswitch.hpp b/apps/openmw/mwinput/controlswitch.hpp new file mode 100644 index 0000000000..5fa475e770 --- /dev/null +++ b/apps/openmw/mwinput/controlswitch.hpp @@ -0,0 +1,21 @@ +#ifndef MWINPUT_CONTROLSWITCH_H +#define MWINPUT_CONTROLSWITCH_H + +#include + +namespace MWInput +{ + class ControlSwitch + { + public: + ControlSwitch(); + + bool get(const std::string& key); + void set(const std::string& key, bool value); + void clear(); + + private: + std::map mSwitches; + }; +} +#endif diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 96806845e7..b9b9ecf62f 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -31,6 +31,7 @@ #include "actionmanager.hpp" #include "controllermanager.hpp" +#include "controlswitch.hpp" #include "keyboardmanager.hpp" #include "mousemanager.hpp" #include "sdlmappings.hpp" @@ -66,13 +67,7 @@ namespace MWInput mInputBinder->getChannel (i)->addListener (this); } - mControlSwitch["playercontrols"] = true; - mControlSwitch["playerfighting"] = true; - mControlSwitch["playerjumping"] = true; - mControlSwitch["playerlooking"] = true; - mControlSwitch["playermagic"] = true; - mControlSwitch["playerviewswitch"] = true; - mControlSwitch["vanitymode"] = true; + mControlSwitch = new ControlSwitch(); mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); @@ -92,8 +87,7 @@ namespace MWInput void InputManager::clear() { // Enable all controls - for (std::map::iterator it = mControlSwitch.begin(); it != mControlSwitch.end(); ++it) - it->second = true; + mControlSwitch->clear(); mActionManager->clear(); mControllerManager->clear(); @@ -109,6 +103,8 @@ namespace MWInput delete mMouseManager; delete mSensorManager; + delete mControlSwitch; + mInputBinder->save(mUserFile); delete mInputBinder; @@ -159,7 +155,7 @@ namespace MWInput return; } - if (mControlSwitch["playercontrols"]) + if (mControlSwitch->get("playercontrols")) { bool joystickUsed = mControllerManager->joystickLastUsed(); if (action == A_Use) @@ -278,35 +274,12 @@ namespace MWInput bool InputManager::getControlSwitch (const std::string& sw) { - return mControlSwitch[sw]; + return mControlSwitch->get(sw); } void InputManager::toggleControlSwitch (const std::string& sw, bool value) { - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - - /// \note 7 switches at all, if-else is relevant - if (sw == "playercontrols" && !value) - { - player.setLeftRight(0); - player.setForwardBackward(0); - player.setAutoMove(false); - player.setUpDown(0); - } - else if (sw == "playerjumping" && !value) - { - /// \fixme maybe crouching at this time - player.setUpDown(0); - } - else if (sw == "vanitymode") - { - MWBase::Environment::get().getWorld()->allowVanityMode(value); - } - else if (sw == "playerlooking" && !value) - { - MWBase::Environment::get().getWorld()->rotateObject(player.getPlayer(), 0.f, 0.f, 0.f); - } - mControlSwitch[sw] = value; + mControlSwitch->set(sw, value); } void InputManager::resetIdleTime() diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 51561feac9..ac056809e4 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -21,6 +21,7 @@ namespace MWInput { + class ControlSwitch; class ActionManager; class ControllerManager; class KeyboardManager; @@ -151,7 +152,7 @@ namespace MWInput bool mDetectingKeyboard; - std::map mControlSwitch; + ControlSwitch* mControlSwitch; ActionManager* mActionManager; ControllerManager* mControllerManager; From 2f2b3173e35b190c1696856ec4ce685adf5e7444 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 16 Apr 2020 18:59:48 +0400 Subject: [PATCH 13/23] Fix copy-paste error --- apps/openmw/mwinput/keyboardmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index d043f81377..9cca004412 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -63,7 +63,7 @@ namespace MWInput if (SDL_IsTextInputActive() && // Little trick to check if key is printable ( !(SDLK_SCANCODE_MASK & arg.keysym.sym) && std::isprint(arg.keysym.sym))) consumed = true; - MWBase::Environment::get().getInputManager()->setJoystickLastUsed(!consumed); + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!consumed); } if (arg.repeat) return; @@ -79,7 +79,7 @@ namespace MWInput OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); if (!mInputBinder->detectingBindingState()) - MWBase::Environment::get().getInputManager()->setJoystickLastUsed(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); + MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); mInputBinder->keyReleased(arg); } } From 0eb24da2e78b68d174ec7e51d1058f2ae6762f91 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 16 Apr 2020 19:41:55 +0400 Subject: [PATCH 14/23] Fix controls disabling --- apps/openmw/mwinput/inputmanagerimp.cpp | 3 +-- apps/openmw/mwinput/keyboardmanager.cpp | 5 ----- apps/openmw/mwinput/keyboardmanager.hpp | 4 ++-- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index b9b9ecf62f..f7f32b9a93 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -216,9 +216,9 @@ namespace MWInput void InputManager::update(float dt, bool disableControls, bool disableEvents) { mInputWrapper->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible()); - mInputWrapper->capture(disableEvents); + mKeyboardManager->setControlsDisabled(disableControls); if (disableControls) { updateCursorMode(); @@ -231,7 +231,6 @@ namespace MWInput updateCursorMode(); bool controllerMove = mControllerManager->update(dt, disableControls); - mKeyboardManager->update(dt, disableControls); mMouseManager->update(dt, disableControls); mSensorManager->update(dt, mGuiCursorEnabled); mActionManager->update(dt, controllerMove); diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index 9cca004412..773ea4028f 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -27,11 +27,6 @@ namespace MWInput { } - void KeyboardManager::update(float dt, bool disableControls) - { - mControlsDisabled = disableControls; - } - bool KeyboardManager::actionIsActive (int id) { return (mInputBinder->getChannel(id)->getValue ()==1.0); diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index 55b91bac44..9d1c0b4fd6 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -25,12 +25,12 @@ namespace MWInput virtual ~KeyboardManager() = default; - void update(float dt, bool disableControls); - virtual void textInput(const SDL_TextInputEvent &arg); virtual void keyPressed(const SDL_KeyboardEvent &arg); virtual void keyReleased(const SDL_KeyboardEvent &arg); + void setControlsDisabled(bool disabled) { mControlsDisabled = disabled; } + private: bool actionIsActive(int id); From b33c4c920cd92fe105786d91f02e6569c7ae1296 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 17 Apr 2020 15:21:23 +0400 Subject: [PATCH 15/23] Move all OICS handling to the separate file --- apps/openmw/CMakeLists.txt | 3 +- apps/openmw/mwbase/inputmanager.hpp | 5 +- apps/openmw/mwinput/actionmanager.cpp | 66 +- apps/openmw/mwinput/actionmanager.hpp | 13 +- apps/openmw/mwinput/bindingsmanager.cpp | 738 ++++++++++++++++++++++ apps/openmw/mwinput/bindingsmanager.hpp | 73 +++ apps/openmw/mwinput/controllermanager.cpp | 80 ++- apps/openmw/mwinput/controllermanager.hpp | 15 +- apps/openmw/mwinput/inputmanagerimp.cpp | 606 +----------------- apps/openmw/mwinput/inputmanagerimp.hpp | 56 +- apps/openmw/mwinput/keyboardmanager.cpp | 41 +- apps/openmw/mwinput/keyboardmanager.hpp | 13 +- apps/openmw/mwinput/mousemanager.cpp | 39 +- apps/openmw/mwinput/mousemanager.hpp | 16 +- apps/openmw/mwinput/sdlmappings.cpp | 140 ++++ apps/openmw/mwinput/sdlmappings.hpp | 6 +- apps/openmw/mwinput/sensormanager.cpp | 18 +- components/CMakeLists.txt | 2 +- components/sdlutil/OISCompat.hpp | 159 ----- components/sdlutil/sdlinputwrapper.cpp | 137 ---- components/sdlutil/sdlinputwrapper.hpp | 8 - 21 files changed, 1121 insertions(+), 1113 deletions(-) create mode 100644 apps/openmw/mwinput/bindingsmanager.cpp create mode 100644 apps/openmw/mwinput/bindingsmanager.hpp delete mode 100644 components/sdlutil/OISCompat.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index d907091bda..34824ea331 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,8 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - actions actionmanager controllermanager controlswitch inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager + actions actionmanager bindingsmanager controllermanager controlswitch + inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 601dd90e52..932463e974 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -46,6 +46,7 @@ namespace MWBase virtual void setDragDrop(bool dragDrop) = 0; virtual void setGamepadGuiCursorEnabled(bool enabled) = 0; + virtual void setAttemptJump(bool jumping) = 0; virtual void toggleControlSwitch (const std::string& sw, bool value) = 0; virtual bool getControlSwitch (const std::string& sw) = 0; @@ -72,9 +73,9 @@ namespace MWBase virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; - virtual void setPlayerControlsEnabled(bool enabled) = 0; - virtual void resetIdleTime() = 0; + + virtual void executeAction(int action) = 0; }; } diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index 2240e75565..e90a4ddaf5 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -4,8 +4,6 @@ #include -#include - #include #include "../mwbase/inputmanager.hpp" @@ -24,17 +22,17 @@ #include "../mwmechanics/actorutil.hpp" #include "actions.hpp" +#include "bindingsmanager.hpp" namespace MWInput { const float ZOOM_SCALE = 120.f; /// Used for scrolling camera in and out - const int fakeDeviceID = 1; - ActionManager::ActionManager(ICS::InputControlSystem* inputBinder, + ActionManager::ActionManager(BindingsManager* bindingsManager, osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler) - : mInputBinder(inputBinder) + : mBindingsManager(bindingsManager) , mViewer(viewer) , mScreenCaptureHandler(screenCaptureHandler) , mScreenCaptureOperation(screenCaptureOperation) @@ -65,19 +63,19 @@ namespace MWInput MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) + if (mBindingsManager->actionIsActive(A_MoveLeft) != mBindingsManager->actionIsActive(A_MoveRight)) { alwaysRunAllowed = true; triedToMove = true; - player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); + player.setLeftRight(mBindingsManager->actionIsActive(A_MoveRight) ? 1 : -1); } - if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) + if (mBindingsManager->actionIsActive(A_MoveForward) != mBindingsManager->actionIsActive(A_MoveBackward)) { alwaysRunAllowed = true; triedToMove = true; player.setAutoMove (false); - player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); + player.setForwardBackward(mBindingsManager->actionIsActive(A_MoveForward) ? 1 : -1); } if (player.getAutoMove()) @@ -112,7 +110,7 @@ namespace MWInput if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch")) { - if (actionIsActive(A_TogglePOV)) + if (mBindingsManager->actionIsActive(A_TogglePOV)) { if (mPreviewPOVDelay <= 0.5 && (mPreviewPOVDelay += dt) > 0.5) @@ -140,27 +138,27 @@ namespace MWInput if (!isToggleSneak) { if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) - player.setSneak(actionIsActive(A_Sneak)); + player.setSneak(mBindingsManager->actionIsActive(A_Sneak)); } - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight); + float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward); bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning) - player.setRunState(!actionIsActive(A_Run)); + player.setRunState(!mBindingsManager->actionIsActive(A_Run)); else - player.setRunState(actionIsActive(A_Run)); + player.setRunState(mBindingsManager->actionIsActive(A_Run)); } - if (actionIsActive(A_MoveForward) || - actionIsActive(A_MoveBackward) || - actionIsActive(A_MoveLeft) || - actionIsActive(A_MoveRight) || - actionIsActive(A_Jump) || - actionIsActive(A_Sneak) || - actionIsActive(A_TogglePOV) || - actionIsActive(A_ZoomIn) || - actionIsActive(A_ZoomOut)) + if (mBindingsManager->actionIsActive(A_MoveForward) || + mBindingsManager->actionIsActive(A_MoveBackward) || + mBindingsManager->actionIsActive(A_MoveLeft) || + mBindingsManager->actionIsActive(A_MoveRight) || + mBindingsManager->actionIsActive(A_Jump) || + mBindingsManager->actionIsActive(A_Sneak) || + mBindingsManager->actionIsActive(A_TogglePOV) || + mBindingsManager->actionIsActive(A_ZoomIn) || + mBindingsManager->actionIsActive(A_ZoomOut)) { resetIdleTime(); } @@ -192,11 +190,6 @@ namespace MWInput } } - bool ActionManager::actionIsActive(int id) - { - return (mInputBinder->getChannel(id)->getValue ()==1.0); - } - void ActionManager::executeAction(int action) { // trigger action activated @@ -321,17 +314,6 @@ namespace MWInput } } - bool isLeftOrRightButton(int action, ICS::InputControlSystem* ics, int deviceId, bool joystick) - { - int mouseBinding = ics->getMouseButtonBinding(ics->getControl(action), ICS::Control::INCREASE); - if (mouseBinding != ICS_MAX_DEVICE_BUTTONS) - return true; - int buttonBinding = ics->getJoystickButtonBinding(ics->getControl(action), deviceId, ICS::Control::INCREASE); - if (joystick && (buttonBinding == 0 || buttonBinding == 1)) - return true; - return false; - } - bool ActionManager::checkAllowedToUseItems() const { MWWorld::Ptr player = MWMechanics::getPlayer(); @@ -559,7 +541,7 @@ namespace MWInput if (MWBase::Environment::get().getWindowManager()->isGuiMode()) { bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); - if (!SDL_IsTextInputActive() && !isLeftOrRightButton(A_Activate, mInputBinder, fakeDeviceID, joystickUsed)) + if (!SDL_IsTextInputActive() && !mBindingsManager->isLeftOrRightButton(A_Activate, joystickUsed)) MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0, false); } else if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) @@ -612,7 +594,7 @@ namespace MWInput if (SDL_IsTextInputActive()) return; - if (isLeftOrRightButton(action, mInputBinder, fakeDeviceID, joystickUsed)) + if (mBindingsManager->isLeftOrRightButton(action, joystickUsed)) return; MyGUI::KeyCode key; diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp index 399cb318c5..31fd993c95 100644 --- a/apps/openmw/mwinput/actionmanager.hpp +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -4,11 +4,6 @@ #include #include -namespace ICS -{ - class InputControlSystem; -} - namespace osgViewer { class Viewer; @@ -17,11 +12,13 @@ namespace osgViewer namespace MWInput { + class BindingsManager; + class ActionManager { public: - ActionManager(ICS::InputControlSystem* inputBinder, + ActionManager(BindingsManager* bindingsManager, osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler); @@ -64,11 +61,9 @@ namespace MWInput private: void handleGuiArrowKey(int action); - bool actionIsActive(int id); - void updateIdleTime(float dt); - ICS::InputControlSystem* mInputBinder; + BindingsManager* mBindingsManager; osg::ref_ptr mViewer; osg::ref_ptr mScreenCaptureHandler; osgViewer::ScreenCaptureHandler::CaptureOperation* mScreenCaptureOperation; diff --git a/apps/openmw/mwinput/bindingsmanager.cpp b/apps/openmw/mwinput/bindingsmanager.cpp new file mode 100644 index 0000000000..f871f0c511 --- /dev/null +++ b/apps/openmw/mwinput/bindingsmanager.cpp @@ -0,0 +1,738 @@ +#include "bindingsmanager.hpp" + +#include + +#include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include "actions.hpp" +#include "sdlmappings.hpp" + +namespace MWInput +{ + static const int sFakeDeviceId = 1; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers + + void clearAllKeyBindings(ICS::InputControlSystem* inputBinder, ICS::Control* control) + { + // right now we don't really need multiple bindings for the same action, so remove all others first + if (inputBinder->getKeyBinding(control, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) + inputBinder->removeKeyBinding(inputBinder->getKeyBinding(control, ICS::Control::INCREASE)); + if (inputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + inputBinder->removeMouseButtonBinding(inputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE)); + if (inputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) + inputBinder->removeMouseWheelBinding(inputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE)); + } + + void clearAllControllerBindings(ICS::InputControlSystem* inputBinder, ICS::Control* control) + { + // right now we don't really need multiple bindings for the same action, so remove all others first + if (inputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) + inputBinder->removeJoystickAxisBinding(sFakeDeviceId, inputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); + if (inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + inputBinder->removeJoystickButtonBinding(sFakeDeviceId, inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); + } + + class InputControlSystem : public ICS::InputControlSystem + { + public: + InputControlSystem(const std::string& bindingsFile) + : ICS::InputControlSystem(bindingsFile, true, nullptr, nullptr, A_Last) + { + } + }; + + class BindingsListener : + public ICS::ChannelListener, + public ICS::DetectingBindingListener + { + public: + BindingsListener(ICS::InputControlSystem* inputBinder, BindingsManager* bindingsManager) + : mInputBinder(inputBinder) + , mBindingsManager(bindingsManager) + , mDetectingKeyboard(false) + { + } + + virtual ~BindingsListener() = default; + + virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue) + { + int action = channel->getNumber(); + mBindingsManager->actionValueChanged(action, currentValue, previousValue); + } + + virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) + { + //Disallow binding escape key + if(key==SDL_SCANCODE_ESCAPE) + { + //Stop binding if esc pressed + mInputBinder->cancelDetectingBindingState(); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + return; + } + + // Disallow binding reserved keys + if (key == SDL_SCANCODE_F3 || key == SDL_SCANCODE_F4 || key == SDL_SCANCODE_F10) + return; + + #ifndef __APPLE__ + // Disallow binding Windows/Meta keys + if (key == SDL_SCANCODE_LGUI || key == SDL_SCANCODE_RGUI) + return; + #endif + + if(!mDetectingKeyboard) + return; + + clearAllKeyBindings(mInputBinder, control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::keyBindingDetected(ICS, control, key, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) + { + // we don't want mouse movement bindings + return; + } + + virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , unsigned int button, ICS::Control::ControlChangingDirection direction) + { + if(!mDetectingKeyboard) + return; + clearAllKeyBindings(mInputBinder, control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::mouseButtonBindingDetected(ICS, control, button, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) + { + if(!mDetectingKeyboard) + return; + clearAllKeyBindings(mInputBinder, control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::mouseWheelBindingDetected(ICS, control, click, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control + , int axis, ICS::Control::ControlChangingDirection direction) + { + //only allow binding to the trigers + if(axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + return; + if(mDetectingKeyboard) + return; + + clearAllControllerBindings(mInputBinder, control); + control->setValue(0.5f); //axis bindings must start at 0.5 + control->setInitialValue(0.5f); + ICS::DetectingBindingListener::joystickAxisBindingDetected(ICS, deviceID, control, axis, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control + , unsigned int button, ICS::Control::ControlChangingDirection direction) + { + if(mDetectingKeyboard) + return; + clearAllControllerBindings(mInputBinder,control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, deviceID, control, button, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + void setDetectingKeyboard(bool detecting) + { + mDetectingKeyboard = detecting; + } + + private: + ICS::InputControlSystem* mInputBinder; + BindingsManager* mBindingsManager; + bool mDetectingKeyboard; + }; + + BindingsManager::BindingsManager(const std::string& userFile, bool userFileExists) + : mUserFile(userFile) + , mDragDrop(false) + { + std::string file = userFileExists ? userFile : ""; + mInputBinder = new InputControlSystem(file); + mListener = new BindingsListener(mInputBinder, this); + mInputBinder->setDetectingBindingListener(mListener); + + loadKeyDefaults(); + loadControllerDefaults(); + + for (int i = 0; i < A_Last; ++i) + { + mInputBinder->getChannel(i)->addListener(mListener); + } + } + + void BindingsManager::setDragDrop(bool dragDrop) + { + mDragDrop = dragDrop; + } + + BindingsManager::~BindingsManager() + { + mInputBinder->save(mUserFile); + delete mInputBinder; + } + + void BindingsManager::update(float dt) + { + // update values of channels (as a result of pressed keys) + mInputBinder->update(dt); + } + + bool BindingsManager::isLeftOrRightButton(int action, bool joystick) const + { + int mouseBinding = mInputBinder->getMouseButtonBinding(mInputBinder->getControl(action), ICS::Control::INCREASE); + if (mouseBinding != ICS_MAX_DEVICE_BUTTONS) + return true; + int buttonBinding = mInputBinder->getJoystickButtonBinding(mInputBinder->getControl(action), sFakeDeviceId, ICS::Control::INCREASE); + if (joystick && (buttonBinding == 0 || buttonBinding == 1)) + return true; + return false; + } + + void BindingsManager::setPlayerControlsEnabled(bool enabled) + { + int playerChannels[] = {A_AutoMove, A_AlwaysRun, A_ToggleWeapon, + A_ToggleSpell, A_Rest, A_QuickKey1, A_QuickKey2, + A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6, + A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, + A_Use, A_Journal}; + + for(size_t i = 0; i < sizeof(playerChannels)/sizeof(playerChannels[0]); i++) { + int pc = playerChannels[i]; + mInputBinder->getChannel(pc)->setEnabled(enabled); + } + } + + float BindingsManager::getActionValue (int id) const + { + return mInputBinder->getChannel(id)->getValue(); + } + + bool BindingsManager::actionIsActive (int id) const + { + return getActionValue(id) == 1.0; + } + + void BindingsManager::loadKeyDefaults (bool force) + { + // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid + // across different versions of OpenMW (in the case where another input action is added) + std::map defaultKeyBindings; + + //Gets the Keyvalue from the Scancode; gives the button in the same place reguardless of keyboard format + defaultKeyBindings[A_Activate] = SDL_SCANCODE_SPACE; + defaultKeyBindings[A_MoveBackward] = SDL_SCANCODE_S; + defaultKeyBindings[A_MoveForward] = SDL_SCANCODE_W; + defaultKeyBindings[A_MoveLeft] = SDL_SCANCODE_A; + defaultKeyBindings[A_MoveRight] = SDL_SCANCODE_D; + defaultKeyBindings[A_ToggleWeapon] = SDL_SCANCODE_F; + defaultKeyBindings[A_ToggleSpell] = SDL_SCANCODE_R; + defaultKeyBindings[A_CycleSpellLeft] = SDL_SCANCODE_MINUS; + defaultKeyBindings[A_CycleSpellRight] = SDL_SCANCODE_EQUALS; + defaultKeyBindings[A_CycleWeaponLeft] = SDL_SCANCODE_LEFTBRACKET; + defaultKeyBindings[A_CycleWeaponRight] = SDL_SCANCODE_RIGHTBRACKET; + + defaultKeyBindings[A_QuickKeysMenu] = SDL_SCANCODE_F1; + defaultKeyBindings[A_Console] = SDL_SCANCODE_GRAVE; + defaultKeyBindings[A_Run] = SDL_SCANCODE_LSHIFT; + defaultKeyBindings[A_Sneak] = SDL_SCANCODE_LCTRL; + defaultKeyBindings[A_AutoMove] = SDL_SCANCODE_Q; + defaultKeyBindings[A_Jump] = SDL_SCANCODE_E; + defaultKeyBindings[A_Journal] = SDL_SCANCODE_J; + defaultKeyBindings[A_Rest] = SDL_SCANCODE_T; + defaultKeyBindings[A_GameMenu] = SDL_SCANCODE_ESCAPE; + defaultKeyBindings[A_TogglePOV] = SDL_SCANCODE_TAB; + defaultKeyBindings[A_QuickKey1] = SDL_SCANCODE_1; + defaultKeyBindings[A_QuickKey2] = SDL_SCANCODE_2; + defaultKeyBindings[A_QuickKey3] = SDL_SCANCODE_3; + defaultKeyBindings[A_QuickKey4] = SDL_SCANCODE_4; + defaultKeyBindings[A_QuickKey5] = SDL_SCANCODE_5; + defaultKeyBindings[A_QuickKey6] = SDL_SCANCODE_6; + defaultKeyBindings[A_QuickKey7] = SDL_SCANCODE_7; + defaultKeyBindings[A_QuickKey8] = SDL_SCANCODE_8; + defaultKeyBindings[A_QuickKey9] = SDL_SCANCODE_9; + defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0; + defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12; + defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11; + defaultKeyBindings[A_ToggleDebug] = SDL_SCANCODE_F10; + defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK; + defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5; + defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9; + + std::map defaultMouseButtonBindings; + defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT; + defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT; + + std::map defaultMouseWheelBindings; + defaultMouseWheelBindings[A_ZoomIn] = ICS::InputControlSystem::MouseWheelClick::UP; + defaultMouseWheelBindings[A_ZoomOut] = ICS::InputControlSystem::MouseWheelClick::DOWN; + + for (int i = 0; i < A_Last; ++i) + { + ICS::Control* control; + bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; + if (!controlExists) + { + control = new ICS::Control(std::to_string(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX); + mInputBinder->addControl(control); + control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); + } + else + { + control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; + } + + if (!controlExists || force || + ( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN + && mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS + && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED + )) + { + clearAllKeyBindings(mInputBinder, control); + + if (defaultKeyBindings.find(i) != defaultKeyBindings.end() + && (force || !mInputBinder->isKeyBound(defaultKeyBindings[i]))) + { + control->setInitialValue(0.0f); + mInputBinder->addKeyBinding(control, defaultKeyBindings[i], ICS::Control::INCREASE); + } + else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end() + && (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))) + { + control->setInitialValue(0.0f); + mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); + } + else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end() + && (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i]))) + { + control->setInitialValue(0.f); + mInputBinder->addMouseWheelBinding(control, defaultMouseWheelBindings[i], ICS::Control::INCREASE); + } + + if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6)) + { + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_6, ICS::Control::INCREASE); + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_4, ICS::Control::DECREASE); + } + if (i == A_LookUpDown && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_8) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_2)) + { + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_2, ICS::Control::INCREASE); + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_8, ICS::Control::DECREASE); + } + } + } + } + + void BindingsManager::loadControllerDefaults(bool force) + { + // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid + // across different versions of OpenMW (in the case where another input action is added) + std::map defaultButtonBindings; + + defaultButtonBindings[A_Activate] = SDL_CONTROLLER_BUTTON_A; + defaultButtonBindings[A_ToggleWeapon] = SDL_CONTROLLER_BUTTON_X; + defaultButtonBindings[A_ToggleSpell] = SDL_CONTROLLER_BUTTON_Y; + //defaultButtonBindings[A_QuickButtonsMenu] = SDL_GetButtonFromScancode(SDL_SCANCODE_F1); // Need to implement, should be ToggleSpell(5) AND Wait(9) + defaultButtonBindings[A_Sneak] = SDL_CONTROLLER_BUTTON_LEFTSTICK; + defaultButtonBindings[A_Journal] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; + defaultButtonBindings[A_Rest] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; + defaultButtonBindings[A_TogglePOV] = SDL_CONTROLLER_BUTTON_RIGHTSTICK; + defaultButtonBindings[A_Inventory] = SDL_CONTROLLER_BUTTON_B; + defaultButtonBindings[A_GameMenu] = SDL_CONTROLLER_BUTTON_START; + defaultButtonBindings[A_QuickSave] = SDL_CONTROLLER_BUTTON_GUIDE; + defaultButtonBindings[A_MoveForward] = SDL_CONTROLLER_BUTTON_DPAD_UP; + defaultButtonBindings[A_MoveLeft] = SDL_CONTROLLER_BUTTON_DPAD_LEFT; + defaultButtonBindings[A_MoveBackward] = SDL_CONTROLLER_BUTTON_DPAD_DOWN; + defaultButtonBindings[A_MoveRight] = SDL_CONTROLLER_BUTTON_DPAD_RIGHT; + + std::map defaultAxisBindings; + defaultAxisBindings[A_MoveForwardBackward] = SDL_CONTROLLER_AXIS_LEFTY; + defaultAxisBindings[A_MoveLeftRight] = SDL_CONTROLLER_AXIS_LEFTX; + defaultAxisBindings[A_LookUpDown] = SDL_CONTROLLER_AXIS_RIGHTY; + defaultAxisBindings[A_LookLeftRight] = SDL_CONTROLLER_AXIS_RIGHTX; + defaultAxisBindings[A_Use] = SDL_CONTROLLER_AXIS_TRIGGERRIGHT; + defaultAxisBindings[A_Jump] = SDL_CONTROLLER_AXIS_TRIGGERLEFT; + + for (int i = 0; i < A_Last; i++) + { + ICS::Control* control; + bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; + if (!controlExists) + { + float initial; + if (defaultAxisBindings.find(i) == defaultAxisBindings.end()) + initial = 0.0f; + else initial = 0.5f; + control = new ICS::Control(std::to_string(i), false, true, initial, ICS::ICS_MAX, ICS::ICS_MAX); + mInputBinder->addControl(control); + control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); + } + else + { + control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; + } + + if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, sFakeDeviceId, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, sFakeDeviceId, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) + { + clearAllControllerBindings(mInputBinder, control); + + if (defaultButtonBindings.find(i) != defaultButtonBindings.end() + && (force || !mInputBinder->isJoystickButtonBound(sFakeDeviceId, defaultButtonBindings[i]))) + { + control->setInitialValue(0.0f); + mInputBinder->addJoystickButtonBinding(control, sFakeDeviceId, defaultButtonBindings[i], ICS::Control::INCREASE); + } + else if (defaultAxisBindings.find(i) != defaultAxisBindings.end() && (force || !mInputBinder->isJoystickAxisBound(sFakeDeviceId, defaultAxisBindings[i]))) + { + control->setValue(0.5f); + control->setInitialValue(0.5f); + mInputBinder->addJoystickAxisBinding(control, sFakeDeviceId, defaultAxisBindings[i], ICS::Control::INCREASE); + } + } + } + } + + std::string BindingsManager::getActionDescription (int action) + { + std::map descriptions; + + if (action == A_Screenshot) + return "Screenshot"; + else if (action == A_ZoomIn) + return "Zoom In"; + else if (action == A_ZoomOut) + return "Zoom Out"; + else if (action == A_ToggleHUD) + return "Toggle HUD"; + + descriptions[A_Use] = "sUse"; + descriptions[A_Activate] = "sActivate"; + descriptions[A_MoveBackward] = "sBack"; + descriptions[A_MoveForward] = "sForward"; + descriptions[A_MoveLeft] = "sLeft"; + descriptions[A_MoveRight] = "sRight"; + descriptions[A_ToggleWeapon] = "sReady_Weapon"; + descriptions[A_ToggleSpell] = "sReady_Magic"; + descriptions[A_CycleSpellLeft] = "sPrevSpell"; + descriptions[A_CycleSpellRight] = "sNextSpell"; + descriptions[A_CycleWeaponLeft] = "sPrevWeapon"; + descriptions[A_CycleWeaponRight] = "sNextWeapon"; + descriptions[A_Console] = "sConsoleTitle"; + descriptions[A_Run] = "sRun"; + descriptions[A_Sneak] = "sCrouch_Sneak"; + descriptions[A_AutoMove] = "sAuto_Run"; + descriptions[A_Jump] = "sJump"; + descriptions[A_Journal] = "sJournal"; + descriptions[A_Rest] = "sRestKey"; + descriptions[A_Inventory] = "sInventory"; + descriptions[A_TogglePOV] = "sTogglePOVCmd"; + descriptions[A_QuickKeysMenu] = "sQuickMenu"; + descriptions[A_QuickKey1] = "sQuick1Cmd"; + descriptions[A_QuickKey2] = "sQuick2Cmd"; + descriptions[A_QuickKey3] = "sQuick3Cmd"; + descriptions[A_QuickKey4] = "sQuick4Cmd"; + descriptions[A_QuickKey5] = "sQuick5Cmd"; + descriptions[A_QuickKey6] = "sQuick6Cmd"; + descriptions[A_QuickKey7] = "sQuick7Cmd"; + descriptions[A_QuickKey8] = "sQuick8Cmd"; + descriptions[A_QuickKey9] = "sQuick9Cmd"; + descriptions[A_QuickKey10] = "sQuick10Cmd"; + descriptions[A_AlwaysRun] = "sAlways_Run"; + descriptions[A_QuickSave] = "sQuickSaveCmd"; + descriptions[A_QuickLoad] = "sQuickLoadCmd"; + + if (descriptions[action] == "") + return ""; // not configurable + + return "#{" + descriptions[action] + "}"; + } + + std::string BindingsManager::getActionKeyBindingName (int action) + { + if (mInputBinder->getChannel (action)->getControlsCount () == 0) + return "#{sNone}"; + + ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; + + SDL_Scancode key = mInputBinder->getKeyBinding (c, ICS::Control::INCREASE); + unsigned int mouse = mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE); + ICS::InputControlSystem::MouseWheelClick wheel = mInputBinder->getMouseWheelBinding(c, ICS::Control::INCREASE); + if (key != SDL_SCANCODE_UNKNOWN) + return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString (key)); + else if (mouse != ICS_MAX_DEVICE_BUTTONS) + return "#{sMouse} " + std::to_string(mouse); + else if (wheel != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) + switch (wheel) + { + case ICS::InputControlSystem::MouseWheelClick::UP: + return "Mouse Wheel Up"; + case ICS::InputControlSystem::MouseWheelClick::DOWN: + return "Mouse Wheel Down"; + case ICS::InputControlSystem::MouseWheelClick::RIGHT: + return "Mouse Wheel Right"; + case ICS::InputControlSystem::MouseWheelClick::LEFT: + return "Mouse Wheel Left"; + default: + return "#{sNone}"; + } + else + return "#{sNone}"; + } + + std::string BindingsManager::getActionControllerBindingName (int action) + { + if (mInputBinder->getChannel (action)->getControlsCount () == 0) + return "#{sNone}"; + + ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; + + if (mInputBinder->getJoystickAxisBinding (c, sFakeDeviceId, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) + return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, sFakeDeviceId, ICS::Control::INCREASE)); + else if (mInputBinder->getJoystickButtonBinding (c, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS ) + return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, sFakeDeviceId, ICS::Control::INCREASE)); + else + return "#{sNone}"; + } + + std::vector BindingsManager::getActionKeySorting() + { + std::vector ret; + ret.push_back(A_MoveForward); + ret.push_back(A_MoveBackward); + ret.push_back(A_MoveLeft); + ret.push_back(A_MoveRight); + ret.push_back(A_TogglePOV); + ret.push_back(A_ZoomIn); + ret.push_back(A_ZoomOut); + ret.push_back(A_Run); + ret.push_back(A_AlwaysRun); + ret.push_back(A_Sneak); + ret.push_back(A_Activate); + ret.push_back(A_Use); + ret.push_back(A_ToggleWeapon); + ret.push_back(A_ToggleSpell); + ret.push_back(A_CycleSpellLeft); + ret.push_back(A_CycleSpellRight); + ret.push_back(A_CycleWeaponLeft); + ret.push_back(A_CycleWeaponRight); + ret.push_back(A_AutoMove); + ret.push_back(A_Jump); + ret.push_back(A_Inventory); + ret.push_back(A_Journal); + ret.push_back(A_Rest); + ret.push_back(A_Console); + ret.push_back(A_QuickSave); + ret.push_back(A_QuickLoad); + ret.push_back(A_ToggleHUD); + ret.push_back(A_Screenshot); + ret.push_back(A_QuickKeysMenu); + ret.push_back(A_QuickKey1); + ret.push_back(A_QuickKey2); + ret.push_back(A_QuickKey3); + ret.push_back(A_QuickKey4); + ret.push_back(A_QuickKey5); + ret.push_back(A_QuickKey6); + ret.push_back(A_QuickKey7); + ret.push_back(A_QuickKey8); + ret.push_back(A_QuickKey9); + ret.push_back(A_QuickKey10); + + return ret; + } + std::vector BindingsManager::getActionControllerSorting() + { + std::vector ret; + ret.push_back(A_TogglePOV); + ret.push_back(A_ZoomIn); + ret.push_back(A_ZoomOut); + ret.push_back(A_Sneak); + ret.push_back(A_Activate); + ret.push_back(A_Use); + ret.push_back(A_ToggleWeapon); + ret.push_back(A_ToggleSpell); + ret.push_back(A_AutoMove); + ret.push_back(A_Jump); + ret.push_back(A_Inventory); + ret.push_back(A_Journal); + ret.push_back(A_Rest); + ret.push_back(A_QuickSave); + ret.push_back(A_QuickLoad); + ret.push_back(A_ToggleHUD); + ret.push_back(A_Screenshot); + ret.push_back(A_QuickKeysMenu); + ret.push_back(A_QuickKey1); + ret.push_back(A_QuickKey2); + ret.push_back(A_QuickKey3); + ret.push_back(A_QuickKey4); + ret.push_back(A_QuickKey5); + ret.push_back(A_QuickKey6); + ret.push_back(A_QuickKey7); + ret.push_back(A_QuickKey8); + ret.push_back(A_QuickKey9); + ret.push_back(A_QuickKey10); + ret.push_back(A_CycleSpellLeft); + ret.push_back(A_CycleSpellRight); + ret.push_back(A_CycleWeaponLeft); + ret.push_back(A_CycleWeaponRight); + + return ret; + } + + void BindingsManager::enableDetectingBindingMode(int action, bool keyboard) + { + mListener->setDetectingKeyboard(keyboard); + ICS::Control* c = mInputBinder->getChannel(action)->getAttachedControls().front().control; + mInputBinder->enableDetectingBindingState(c, ICS::Control::INCREASE); + } + + bool BindingsManager::isDetectingBindingState() const + { + return mInputBinder->detectingBindingState(); + } + + void BindingsManager::mousePressed(const SDL_MouseButtonEvent &arg, int deviceID) + { + mInputBinder->mousePressed(arg, deviceID); + } + + void BindingsManager::mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID) + { + mInputBinder->mouseReleased(arg, deviceID); + } + + void BindingsManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg) + { + mInputBinder->mouseMoved(arg); + } + + void BindingsManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) + { + mInputBinder->mouseWheelMoved(arg); + } + + void BindingsManager::keyPressed(const SDL_KeyboardEvent &arg) + { + mInputBinder->keyPressed(arg); + } + + void BindingsManager::keyReleased(const SDL_KeyboardEvent &arg) + { + mInputBinder->keyReleased(arg); + } + + void BindingsManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) + { + mInputBinder->controllerAdded(deviceID, arg); + } + + void BindingsManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) + { + mInputBinder->controllerRemoved(arg); + } + + void BindingsManager::controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) + { + mInputBinder->buttonPressed(deviceID, arg); + } + + void BindingsManager::controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) + { + mInputBinder->buttonReleased(deviceID, arg); + } + + void BindingsManager::controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) + { + mInputBinder->axisMoved(deviceID, arg); + } + + SDL_Scancode BindingsManager::getKeyBinding(int actionId) + { + return mInputBinder->getKeyBinding(mInputBinder->getControl(actionId), ICS::Control::INCREASE); + } + + void BindingsManager::actionValueChanged(int action, float currentValue, float previousValue) + { + MWBase::Environment::get().getInputManager()->resetIdleTime(); + + if (mDragDrop && action != A_GameMenu && action != A_Inventory) + return; + + if((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0)) + { + //Is a normal button press, so don't change it at all + } + //Otherwise only trigger button presses as they go through specific points + else if(previousValue >= .8 && currentValue < .8) + { + currentValue = 0.0; + previousValue = 1.0; + } + else if(previousValue <= .6 && currentValue > .6) + { + currentValue = 1.0; + previousValue = 0.0; + } + else + { + //If it's not switching between those values, ignore the channel change. + return; + } + + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); + if (action == A_Use) + { + if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + action = A_CycleWeaponRight; + + else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) + action = A_CycleSpellRight; + + else + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + MWMechanics::DrawState_ state = player.getDrawState(); + player.setAttackingOrSpell(currentValue != 0 && state != MWMechanics::DrawState_Nothing); + } + } + else if (action == A_Jump) + { + if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + action = A_CycleWeaponLeft; + + else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) + action = A_CycleSpellLeft; + + else + MWBase::Environment::get().getInputManager()->setAttemptJump(currentValue == 1.0 && previousValue == 0.0); + } + } + + if (currentValue == 1) + MWBase::Environment::get().getInputManager()->executeAction(action); + } +} diff --git a/apps/openmw/mwinput/bindingsmanager.hpp b/apps/openmw/mwinput/bindingsmanager.hpp new file mode 100644 index 0000000000..35b26c877c --- /dev/null +++ b/apps/openmw/mwinput/bindingsmanager.hpp @@ -0,0 +1,73 @@ +#ifndef MWINPUT_MWBINDINGSMANAGER_H +#define MWINPUT_MWBINDINGSMANAGER_H + +#include +#include + +#include + +namespace MWInput +{ + class BindingsListener; + class InputControlSystem; + + class BindingsManager + { + public: + BindingsManager(const std::string& userFile, bool userFileExists); + + virtual ~BindingsManager(); + + std::string getActionDescription (int action); + std::string getActionKeyBindingName (int action); + std::string getActionControllerBindingName (int action); + std::vector getActionKeySorting(); + std::vector getActionControllerSorting(); + + void enableDetectingBindingMode (int action, bool keyboard); + bool isDetectingBindingState() const; + + void loadKeyDefaults(bool force = false); + void loadControllerDefaults(bool force = false); + + void setDragDrop(bool dragDrop); + + void update(float dt); + + void setPlayerControlsEnabled(bool enabled); + + bool isLeftOrRightButton(int action, bool joystick) const; + + bool actionIsActive(int id) const; + float getActionValue(int id) const; + + void mousePressed(const SDL_MouseButtonEvent &evt, int deviceID); + void mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID); + void mouseMoved(const SDLUtil::MouseMotionEvent &arg); + void mouseWheelMoved(const SDL_MouseWheelEvent &arg); + + void keyPressed(const SDL_KeyboardEvent &arg); + void keyReleased(const SDL_KeyboardEvent &arg); + + void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg); + void controllerRemoved(const SDL_ControllerDeviceEvent &arg); + void controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); + void controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); + void controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); + + SDL_Scancode getKeyBinding(int actionId); + + void actionValueChanged(int action, float currentValue, float previousValue); + + private: + void setupSDLKeyMappings(); + + InputControlSystem* mInputBinder; + BindingsListener* mListener; + + std::string mUserFile; + + bool mDragDrop; + }; +} +#endif diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index 697d3ab91d..b8fc0ca749 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include #include "../mwbase/environment.hpp" @@ -18,20 +16,18 @@ #include "actions.hpp" #include "actionmanager.hpp" +#include "bindingsmanager.hpp" #include "mousemanager.hpp" +#include "sdlmappings.hpp" namespace MWInput { - static const int sFakeDeviceID = 1; - - ControllerManager::ControllerManager(ICS::InputControlSystem* inputBinder, - SDLUtil::InputWrapper* inputWrapper, + ControllerManager::ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, MouseManager* mouseManager, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile) - : mInputBinder(inputBinder) - , mInputWrapper(inputWrapper) + : mBindingsManager(bindingsManager) , mActionManager(actionManager) , mMouseManager(mouseManager) , mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input")) @@ -62,7 +58,8 @@ namespace MWInput { SDL_ControllerDeviceEvent evt; evt.which = i; - controllerAdded(sFakeDeviceID, evt); + static const int fakeDeviceID = 1; + controllerAdded(fakeDeviceID, evt); Log(Debug::Info) << "Detected game controller: " << SDL_GameControllerNameForIndex(i); } else @@ -82,18 +79,13 @@ namespace MWInput void ControllerManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "enable controller") + if (setting.first == "Input" && setting.second == "enable controller") mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input"); } } - bool ControllerManager::actionIsActive (int id) - { - return (mInputBinder->getChannel (id)->getValue ()==1.0); - } - bool ControllerManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; @@ -101,12 +93,12 @@ namespace MWInput if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) { - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue()*2.0f-1.0f; - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue()*2.0f-1.0f; - float zAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; + float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight)*2.0f-1.0f; + float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward)*2.0f-1.0f; + float zAxis = mBindingsManager->getActionValue(A_LookUpDown)*2.0f-1.0f; - xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); - yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); + xAxis *= (1.5f - mBindingsManager->getActionValue(A_Use)); + yAxis *= (1.5f - mBindingsManager->getActionValue(A_Use)); // 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 @@ -137,8 +129,8 @@ namespace MWInput // be done in the physics system. if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) { - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight); + float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward); if (xAxis != .5) { triedToMove = true; @@ -163,7 +155,7 @@ namespace MWInput { if(mJoystickLastUsed) { - if(actionIsActive(A_Sneak)) + if(mBindingsManager->actionIsActive(A_Sneak)) { if(mSneakToggleShortcutTimer) // New Sneak Button Press { @@ -189,13 +181,13 @@ namespace MWInput } } else - player.setSneak(actionIsActive(A_Sneak)); + player.setSneak(mBindingsManager->actionIsActive(A_Sneak)); } } if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch")) { - if (!actionIsActive(A_TogglePOV)) + if (!mBindingsManager->actionIsActive(A_TogglePOV)) mGamepadZoom = 0; if(mGamepadZoom) @@ -210,7 +202,7 @@ namespace MWInput void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) { - if (!mJoystickEnabled || mInputBinder->detectingBindingState()) + if (!mJoystickEnabled || mBindingsManager->isDetectingBindingState()) return; mJoystickLastUsed = true; @@ -231,26 +223,26 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); } - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess); + mBindingsManager->setPlayerControlsEnabled(!mousePressSuccess); } } } else - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(true); + mBindingsManager->setPlayerControlsEnabled(true); //esc, to leave initial movie screen - auto kc = mInputWrapper->sdl2OISKeyCode(SDLK_ESCAPE); - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0)); + auto kc = sdlKeyToMyGUI(SDLK_ESCAPE); + mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(kc, 0)); if (!mControlsDisabled) - mInputBinder->buttonPressed(deviceID, arg); + mBindingsManager->controllerButtonPressed(deviceID, arg); } - void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg ) + void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) { - if(mInputBinder->detectingBindingState()) + if (mBindingsManager->isDetectingBindingState()) { - mInputBinder->buttonReleased(deviceID, arg); + mBindingsManager->controllerButtonReleased(deviceID, arg); return; } if (!mJoystickEnabled || mControlsDisabled) @@ -265,21 +257,21 @@ namespace MWInput if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. { bool mousePressSuccess = mMouseManager->injectMouseButtonRelease(SDL_BUTTON_LEFT); - if (mInputBinder->detectingBindingState()) // If the player just triggered binding, don't let button release bind. + if (mBindingsManager->isDetectingBindingState()) // If the player just triggered binding, don't let button release bind. return; - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess); + mBindingsManager->setPlayerControlsEnabled(!mousePressSuccess); } } } else - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(true); + mBindingsManager->setPlayerControlsEnabled(true); //esc, to leave initial movie screen - auto kc = mInputWrapper->sdl2OISKeyCode(SDLK_ESCAPE); - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); + auto kc = sdlKeyToMyGUI(SDLK_ESCAPE); + mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc)); - mInputBinder->buttonReleased(deviceID, arg); + mBindingsManager->controllerButtonReleased(deviceID, arg); } void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) @@ -308,17 +300,17 @@ namespace MWInput } } } - mInputBinder->axisMoved(deviceID, arg); + mBindingsManager->controllerAxisMoved(deviceID, arg); } void ControllerManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) { - mInputBinder->controllerAdded(deviceID, arg); + mBindingsManager->controllerAdded(deviceID, arg); } void ControllerManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) { - mInputBinder->controllerRemoved(arg); + mBindingsManager->controllerRemoved(arg); } bool ControllerManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg) diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 1ab6ea76d8..f1be50ee68 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -5,23 +5,17 @@ #include #include -#include - -namespace ICS -{ - class InputControlSystem; -} namespace MWInput { class ActionManager; + class BindingsManager; class MouseManager; class ControllerManager : public SDLUtil::ControllerListener { public: - ControllerManager(ICS::InputControlSystem* inputBinder, - SDLUtil::InputWrapper* inputWrapper, + ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, MouseManager* mouseManager, const std::string& userControllerBindingsFile, @@ -54,10 +48,7 @@ namespace MWInput bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg); bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg); - bool actionIsActive(int id); - - ICS::InputControlSystem* mInputBinder; - SDLUtil::InputWrapper* mInputWrapper; + BindingsManager* mBindingsManager; ActionManager* mActionManager; MouseManager* mMouseManager; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index f7f32b9a93..0a43a62fc7 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -30,6 +30,7 @@ #include "../mwmechanics/actorutil.hpp" #include "actionmanager.hpp" +#include "bindingsmanager.hpp" #include "controllermanager.hpp" #include "controlswitch.hpp" #include "keyboardmanager.hpp" @@ -46,38 +47,25 @@ namespace MWInput osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile, bool grab) - : mUserFile(userFile) - , mDragDrop(false) - , mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) + : mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) , mGuiCursorEnabled(true) - , mDetectingKeyboard(false) - , mFakeDeviceID(1) { mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); mInputWrapper->setWindowEventCallback(MWBase::Environment::get().getWindowManager()); - std::string file = userFileExists ? userFile : ""; - mInputBinder = new ICS::InputControlSystem(file, true, this, nullptr, A_Last); - - loadKeyDefaults(); - loadControllerDefaults(); - - for (int i = 0; i < A_Last; ++i) - { - mInputBinder->getChannel (i)->addListener (this); - } + mBindingsManager = new BindingsManager(userFile, userFileExists); mControlSwitch = new ControlSwitch(); - mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); + mActionManager = new ActionManager(mBindingsManager, screenCaptureOperation, viewer, screenCaptureHandler); - mKeyboardManager = new KeyboardManager(mInputBinder, mInputWrapper, mActionManager); + mKeyboardManager = new KeyboardManager(mBindingsManager, mActionManager); mInputWrapper->setKeyboardEventCallback(mKeyboardManager); - mMouseManager = new MouseManager(mInputBinder, mInputWrapper, window); + mMouseManager = new MouseManager(mBindingsManager, mInputWrapper, window); mInputWrapper->setMouseEventCallback(mMouseManager); - mControllerManager = new ControllerManager(mInputBinder, mInputWrapper, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); + mControllerManager = new ControllerManager(mBindingsManager, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); mInputWrapper->setControllerEventCallback(mControllerManager); mSensorManager = new SensorManager(); @@ -105,89 +93,14 @@ namespace MWInput delete mControlSwitch; - mInputBinder->save(mUserFile); - delete mInputBinder; + delete mBindingsManager; delete mInputWrapper; } - void InputManager::setPlayerControlsEnabled(bool enabled) + void InputManager::setAttemptJump(bool jumping) { - int playerChannels[] = {A_AutoMove, A_AlwaysRun, A_ToggleWeapon, - A_ToggleSpell, A_Rest, A_QuickKey1, A_QuickKey2, - A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6, - A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, - A_Use, A_Journal}; - - for(size_t i = 0; i < sizeof(playerChannels)/sizeof(playerChannels[0]); i++) { - int pc = playerChannels[i]; - mInputBinder->getChannel(pc)->setEnabled(enabled); - } - } - - void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) - { - resetIdleTime (); - - int action = channel->getNumber(); - - if (mDragDrop && action != A_GameMenu && action != A_Inventory) - return; - - if((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0)) - { - //Is a normal button press, so don't change it at all - } - //Otherwise only trigger button presses as they go through specific points - else if(previousValue >= .8 && currentValue < .8) - { - currentValue = 0.0; - previousValue = 1.0; - } - else if(previousValue <= .6 && currentValue > .6) - { - currentValue = 1.0; - previousValue = 0.0; - } - else - { - //If it's not switching between those values, ignore the channel change. - return; - } - - if (mControlSwitch->get("playercontrols")) - { - bool joystickUsed = mControllerManager->joystickLastUsed(); - if (action == A_Use) - { - if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) - action = A_CycleWeaponRight; - - else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) - action = A_CycleSpellRight; - - else - { - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - MWMechanics::DrawState_ state = player.getDrawState(); - player.setAttackingOrSpell(currentValue != 0 && state != MWMechanics::DrawState_Nothing); - } - } - else if (action == A_Jump) - { - if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) - action = A_CycleWeaponLeft; - - else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) - action = A_CycleSpellLeft; - - else - mActionManager->setAttemptJump(currentValue == 1.0 && previousValue == 0.0); - } - } - - if (currentValue == 1) - mActionManager->executeAction(action); + mActionManager->setAttemptJump(jumping); } void InputManager::updateCursorMode() @@ -225,8 +138,7 @@ namespace MWInput return; } - // update values of channels (as a result of pressed keys) - mInputBinder->update(dt); + mBindingsManager->update(dt); updateCursorMode(); @@ -238,7 +150,7 @@ namespace MWInput void InputManager::setDragDrop(bool dragDrop) { - mDragDrop = dragDrop; + mBindingsManager->setDragDrop(dragDrop); } void InputManager::setGamepadGuiCursorEnabled(bool enabled) @@ -260,10 +172,9 @@ namespace MWInput void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); - it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "grab cursor") + if (setting.first == "Input" && setting.second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); } @@ -271,12 +182,12 @@ namespace MWInput mSensorManager->processChangedSettings(changed); } - bool InputManager::getControlSwitch (const std::string& sw) + bool InputManager::getControlSwitch(const std::string& sw) { return mControlSwitch->get(sw); } - void InputManager::toggleControlSwitch (const std::string& sw, bool value) + void InputManager::toggleControlSwitch(const std::string& sw, bool value) { mControlSwitch->set(sw, value); } @@ -286,488 +197,34 @@ namespace MWInput mActionManager->resetIdleTime(); } - bool InputManager::actionIsActive (int id) + std::string InputManager::getActionDescription(int action) { - return (mInputBinder->getChannel (id)->getValue ()==1.0); + return mBindingsManager->getActionDescription(action); } - void InputManager::loadKeyDefaults (bool force) + std::string InputManager::getActionKeyBindingName(int action) { - // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid - // across different versions of OpenMW (in the case where another input action is added) - std::map defaultKeyBindings; - - //Gets the Keyvalue from the Scancode; gives the button in the same place reguardless of keyboard format - defaultKeyBindings[A_Activate] = SDL_SCANCODE_SPACE; - defaultKeyBindings[A_MoveBackward] = SDL_SCANCODE_S; - defaultKeyBindings[A_MoveForward] = SDL_SCANCODE_W; - defaultKeyBindings[A_MoveLeft] = SDL_SCANCODE_A; - defaultKeyBindings[A_MoveRight] = SDL_SCANCODE_D; - defaultKeyBindings[A_ToggleWeapon] = SDL_SCANCODE_F; - defaultKeyBindings[A_ToggleSpell] = SDL_SCANCODE_R; - defaultKeyBindings[A_CycleSpellLeft] = SDL_SCANCODE_MINUS; - defaultKeyBindings[A_CycleSpellRight] = SDL_SCANCODE_EQUALS; - defaultKeyBindings[A_CycleWeaponLeft] = SDL_SCANCODE_LEFTBRACKET; - defaultKeyBindings[A_CycleWeaponRight] = SDL_SCANCODE_RIGHTBRACKET; - - defaultKeyBindings[A_QuickKeysMenu] = SDL_SCANCODE_F1; - defaultKeyBindings[A_Console] = SDL_SCANCODE_GRAVE; - defaultKeyBindings[A_Run] = SDL_SCANCODE_LSHIFT; - defaultKeyBindings[A_Sneak] = SDL_SCANCODE_LCTRL; - defaultKeyBindings[A_AutoMove] = SDL_SCANCODE_Q; - defaultKeyBindings[A_Jump] = SDL_SCANCODE_E; - defaultKeyBindings[A_Journal] = SDL_SCANCODE_J; - defaultKeyBindings[A_Rest] = SDL_SCANCODE_T; - defaultKeyBindings[A_GameMenu] = SDL_SCANCODE_ESCAPE; - defaultKeyBindings[A_TogglePOV] = SDL_SCANCODE_TAB; - defaultKeyBindings[A_QuickKey1] = SDL_SCANCODE_1; - defaultKeyBindings[A_QuickKey2] = SDL_SCANCODE_2; - defaultKeyBindings[A_QuickKey3] = SDL_SCANCODE_3; - defaultKeyBindings[A_QuickKey4] = SDL_SCANCODE_4; - defaultKeyBindings[A_QuickKey5] = SDL_SCANCODE_5; - defaultKeyBindings[A_QuickKey6] = SDL_SCANCODE_6; - defaultKeyBindings[A_QuickKey7] = SDL_SCANCODE_7; - defaultKeyBindings[A_QuickKey8] = SDL_SCANCODE_8; - defaultKeyBindings[A_QuickKey9] = SDL_SCANCODE_9; - defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0; - defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12; - defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11; - defaultKeyBindings[A_ToggleDebug] = SDL_SCANCODE_F10; - defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK; - defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5; - defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9; - - std::map defaultMouseButtonBindings; - defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT; - defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT; - - std::map defaultMouseWheelBindings; - defaultMouseWheelBindings[A_ZoomIn] = ICS::InputControlSystem::MouseWheelClick::UP; - defaultMouseWheelBindings[A_ZoomOut] = ICS::InputControlSystem::MouseWheelClick::DOWN; - - for (int i = 0; i < A_Last; ++i) - { - ICS::Control* control; - bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; - if (!controlExists) - { - control = new ICS::Control(std::to_string(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX); - mInputBinder->addControl(control); - control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); - } - else - { - control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; - } - - if (!controlExists || force || - ( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN - && mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS - && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED - )) - { - clearAllKeyBindings(control); - - if (defaultKeyBindings.find(i) != defaultKeyBindings.end() - && (force || !mInputBinder->isKeyBound(defaultKeyBindings[i]))) - { - control->setInitialValue(0.0f); - mInputBinder->addKeyBinding(control, defaultKeyBindings[i], ICS::Control::INCREASE); - } - else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end() - && (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))) - { - control->setInitialValue(0.0f); - mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); - } - else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end() - && (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i]))) - { - control->setInitialValue(0.f); - mInputBinder->addMouseWheelBinding(control, defaultMouseWheelBindings[i], ICS::Control::INCREASE); - } - - if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6)) - { - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_6, ICS::Control::INCREASE); - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_4, ICS::Control::DECREASE); - } - if (i == A_LookUpDown && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_8) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_2)) - { - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_2, ICS::Control::INCREASE); - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_8, ICS::Control::DECREASE); - } - } - } + return mBindingsManager->getActionKeyBindingName(action); } - void InputManager::loadControllerDefaults(bool force) + std::string InputManager::getActionControllerBindingName(int action) { - // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid - // across different versions of OpenMW (in the case where another input action is added) - std::map defaultButtonBindings; - - defaultButtonBindings[A_Activate] = SDL_CONTROLLER_BUTTON_A; - defaultButtonBindings[A_ToggleWeapon] = SDL_CONTROLLER_BUTTON_X; - defaultButtonBindings[A_ToggleSpell] = SDL_CONTROLLER_BUTTON_Y; - //defaultButtonBindings[A_QuickButtonsMenu] = SDL_GetButtonFromScancode(SDL_SCANCODE_F1); // Need to implement, should be ToggleSpell(5) AND Wait(9) - defaultButtonBindings[A_Sneak] = SDL_CONTROLLER_BUTTON_LEFTSTICK; - defaultButtonBindings[A_Journal] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - defaultButtonBindings[A_Rest] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; - defaultButtonBindings[A_TogglePOV] = SDL_CONTROLLER_BUTTON_RIGHTSTICK; - defaultButtonBindings[A_Inventory] = SDL_CONTROLLER_BUTTON_B; - defaultButtonBindings[A_GameMenu] = SDL_CONTROLLER_BUTTON_START; - defaultButtonBindings[A_QuickSave] = SDL_CONTROLLER_BUTTON_GUIDE; - defaultButtonBindings[A_MoveForward] = SDL_CONTROLLER_BUTTON_DPAD_UP; - defaultButtonBindings[A_MoveLeft] = SDL_CONTROLLER_BUTTON_DPAD_LEFT; - defaultButtonBindings[A_MoveBackward] = SDL_CONTROLLER_BUTTON_DPAD_DOWN; - defaultButtonBindings[A_MoveRight] = SDL_CONTROLLER_BUTTON_DPAD_RIGHT; - - std::map defaultAxisBindings; - defaultAxisBindings[A_MoveForwardBackward] = SDL_CONTROLLER_AXIS_LEFTY; - defaultAxisBindings[A_MoveLeftRight] = SDL_CONTROLLER_AXIS_LEFTX; - defaultAxisBindings[A_LookUpDown] = SDL_CONTROLLER_AXIS_RIGHTY; - defaultAxisBindings[A_LookLeftRight] = SDL_CONTROLLER_AXIS_RIGHTX; - defaultAxisBindings[A_Use] = SDL_CONTROLLER_AXIS_TRIGGERRIGHT; - defaultAxisBindings[A_Jump] = SDL_CONTROLLER_AXIS_TRIGGERLEFT; - - for (int i = 0; i < A_Last; i++) - { - ICS::Control* control; - bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; - if (!controlExists) - { - float initial; - if (defaultAxisBindings.find(i) == defaultAxisBindings.end()) - initial = 0.0f; - else initial = 0.5f; - control = new ICS::Control(std::to_string(i), false, true, initial, ICS::ICS_MAX, ICS::ICS_MAX); - mInputBinder->addControl(control); - control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); - } - else - { - control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; - } - - if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) - { - clearAllControllerBindings(control); - - if (defaultButtonBindings.find(i) != defaultButtonBindings.end() - && (force || !mInputBinder->isJoystickButtonBound(mFakeDeviceID, defaultButtonBindings[i]))) - { - control->setInitialValue(0.0f); - mInputBinder->addJoystickButtonBinding(control, mFakeDeviceID, defaultButtonBindings[i], ICS::Control::INCREASE); - } - else if (defaultAxisBindings.find(i) != defaultAxisBindings.end() && (force || !mInputBinder->isJoystickAxisBound(mFakeDeviceID, defaultAxisBindings[i]))) - { - control->setValue(0.5f); - control->setInitialValue(0.5f); - mInputBinder->addJoystickAxisBinding(control, mFakeDeviceID, defaultAxisBindings[i], ICS::Control::INCREASE); - } - } - } - } - - std::string InputManager::getActionDescription (int action) - { - std::map descriptions; - - if (action == A_Screenshot) - return "Screenshot"; - else if (action == A_ZoomIn) - return "Zoom In"; - else if (action == A_ZoomOut) - return "Zoom Out"; - else if (action == A_ToggleHUD) - return "Toggle HUD"; - - descriptions[A_Use] = "sUse"; - descriptions[A_Activate] = "sActivate"; - descriptions[A_MoveBackward] = "sBack"; - descriptions[A_MoveForward] = "sForward"; - descriptions[A_MoveLeft] = "sLeft"; - descriptions[A_MoveRight] = "sRight"; - descriptions[A_ToggleWeapon] = "sReady_Weapon"; - descriptions[A_ToggleSpell] = "sReady_Magic"; - descriptions[A_CycleSpellLeft] = "sPrevSpell"; - descriptions[A_CycleSpellRight] = "sNextSpell"; - descriptions[A_CycleWeaponLeft] = "sPrevWeapon"; - descriptions[A_CycleWeaponRight] = "sNextWeapon"; - descriptions[A_Console] = "sConsoleTitle"; - descriptions[A_Run] = "sRun"; - descriptions[A_Sneak] = "sCrouch_Sneak"; - descriptions[A_AutoMove] = "sAuto_Run"; - descriptions[A_Jump] = "sJump"; - descriptions[A_Journal] = "sJournal"; - descriptions[A_Rest] = "sRestKey"; - descriptions[A_Inventory] = "sInventory"; - descriptions[A_TogglePOV] = "sTogglePOVCmd"; - descriptions[A_QuickKeysMenu] = "sQuickMenu"; - descriptions[A_QuickKey1] = "sQuick1Cmd"; - descriptions[A_QuickKey2] = "sQuick2Cmd"; - descriptions[A_QuickKey3] = "sQuick3Cmd"; - descriptions[A_QuickKey4] = "sQuick4Cmd"; - descriptions[A_QuickKey5] = "sQuick5Cmd"; - descriptions[A_QuickKey6] = "sQuick6Cmd"; - descriptions[A_QuickKey7] = "sQuick7Cmd"; - descriptions[A_QuickKey8] = "sQuick8Cmd"; - descriptions[A_QuickKey9] = "sQuick9Cmd"; - descriptions[A_QuickKey10] = "sQuick10Cmd"; - descriptions[A_AlwaysRun] = "sAlways_Run"; - descriptions[A_QuickSave] = "sQuickSaveCmd"; - descriptions[A_QuickLoad] = "sQuickLoadCmd"; - - if (descriptions[action] == "") - return ""; // not configurable - - return "#{" + descriptions[action] + "}"; - } - - std::string InputManager::getActionKeyBindingName (int action) - { - if (mInputBinder->getChannel (action)->getControlsCount () == 0) - return "#{sNone}"; - - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - - SDL_Scancode key = mInputBinder->getKeyBinding (c, ICS::Control::INCREASE); - unsigned int mouse = mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE); - ICS::InputControlSystem::MouseWheelClick wheel = mInputBinder->getMouseWheelBinding(c, ICS::Control::INCREASE); - if (key != SDL_SCANCODE_UNKNOWN) - return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString (key)); - else if (mouse != ICS_MAX_DEVICE_BUTTONS) - return "#{sMouse} " + std::to_string(mouse); - else if (wheel != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) - switch (wheel) - { - case ICS::InputControlSystem::MouseWheelClick::UP: - return "Mouse Wheel Up"; - case ICS::InputControlSystem::MouseWheelClick::DOWN: - return "Mouse Wheel Down"; - case ICS::InputControlSystem::MouseWheelClick::RIGHT: - return "Mouse Wheel Right"; - case ICS::InputControlSystem::MouseWheelClick::LEFT: - return "Mouse Wheel Left"; - default: - return "#{sNone}"; - } - else - return "#{sNone}"; - } - - std::string InputManager::getActionControllerBindingName (int action) - { - if (mInputBinder->getChannel (action)->getControlsCount () == 0) - return "#{sNone}"; - - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - - if (mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) - return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE)); - else if (mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS ) - return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE)); - else - return "#{sNone}"; + return mBindingsManager->getActionControllerBindingName(action); } std::vector InputManager::getActionKeySorting() { - std::vector ret; - ret.push_back(A_MoveForward); - ret.push_back(A_MoveBackward); - ret.push_back(A_MoveLeft); - ret.push_back(A_MoveRight); - ret.push_back(A_TogglePOV); - ret.push_back(A_ZoomIn); - ret.push_back(A_ZoomOut); - ret.push_back(A_Run); - ret.push_back(A_AlwaysRun); - ret.push_back(A_Sneak); - ret.push_back(A_Activate); - ret.push_back(A_Use); - ret.push_back(A_ToggleWeapon); - ret.push_back(A_ToggleSpell); - ret.push_back(A_CycleSpellLeft); - ret.push_back(A_CycleSpellRight); - ret.push_back(A_CycleWeaponLeft); - ret.push_back(A_CycleWeaponRight); - ret.push_back(A_AutoMove); - ret.push_back(A_Jump); - ret.push_back(A_Inventory); - ret.push_back(A_Journal); - ret.push_back(A_Rest); - ret.push_back(A_Console); - ret.push_back(A_QuickSave); - ret.push_back(A_QuickLoad); - ret.push_back(A_ToggleHUD); - ret.push_back(A_Screenshot); - ret.push_back(A_QuickKeysMenu); - ret.push_back(A_QuickKey1); - ret.push_back(A_QuickKey2); - ret.push_back(A_QuickKey3); - ret.push_back(A_QuickKey4); - ret.push_back(A_QuickKey5); - ret.push_back(A_QuickKey6); - ret.push_back(A_QuickKey7); - ret.push_back(A_QuickKey8); - ret.push_back(A_QuickKey9); - ret.push_back(A_QuickKey10); - - return ret; + return mBindingsManager->getActionKeySorting(); } + std::vector InputManager::getActionControllerSorting() { - std::vector ret; - ret.push_back(A_TogglePOV); - ret.push_back(A_ZoomIn); - ret.push_back(A_ZoomOut); - ret.push_back(A_Sneak); - ret.push_back(A_Activate); - ret.push_back(A_Use); - ret.push_back(A_ToggleWeapon); - ret.push_back(A_ToggleSpell); - ret.push_back(A_AutoMove); - ret.push_back(A_Jump); - ret.push_back(A_Inventory); - ret.push_back(A_Journal); - ret.push_back(A_Rest); - ret.push_back(A_QuickSave); - ret.push_back(A_QuickLoad); - ret.push_back(A_ToggleHUD); - ret.push_back(A_Screenshot); - ret.push_back(A_QuickKeysMenu); - ret.push_back(A_QuickKey1); - ret.push_back(A_QuickKey2); - ret.push_back(A_QuickKey3); - ret.push_back(A_QuickKey4); - ret.push_back(A_QuickKey5); - ret.push_back(A_QuickKey6); - ret.push_back(A_QuickKey7); - ret.push_back(A_QuickKey8); - ret.push_back(A_QuickKey9); - ret.push_back(A_QuickKey10); - ret.push_back(A_CycleSpellLeft); - ret.push_back(A_CycleSpellRight); - ret.push_back(A_CycleWeaponLeft); - ret.push_back(A_CycleWeaponRight); - - return ret; + return mBindingsManager->getActionControllerSorting(); } - void InputManager::enableDetectingBindingMode (int action, bool keyboard) + void InputManager::enableDetectingBindingMode(int action, bool keyboard) { - mDetectingKeyboard = keyboard; - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - mInputBinder->enableDetectingBindingState (c, ICS::Control::INCREASE); - } - - void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) - { - //Disallow binding escape key - if(key==SDL_SCANCODE_ESCAPE) - { - //Stop binding if esc pressed - mInputBinder->cancelDetectingBindingState(); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - return; - } - - // Disallow binding reserved keys - if (key == SDL_SCANCODE_F3 || key == SDL_SCANCODE_F4 || key == SDL_SCANCODE_F10) - return; - - #ifndef __APPLE__ - // Disallow binding Windows/Meta keys - if (key == SDL_SCANCODE_LGUI || key == SDL_SCANCODE_RGUI) - return; - #endif - - if(!mDetectingKeyboard) - return; - - clearAllKeyBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - } - - void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) - { - // we don't want mouse movement bindings - return; - } - - void InputManager::mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) - { - if(!mDetectingKeyboard) - return; - clearAllKeyBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::mouseButtonBindingDetected (ICS, control, button, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - } - - void InputManager::mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) - { - if(!mDetectingKeyboard) - return; - clearAllKeyBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::mouseWheelBindingDetected(ICS, control, click, direction); - MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); - } - - void InputManager::joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , int axis, ICS::Control::ControlChangingDirection direction) - { - //only allow binding to the trigers - if(axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) - return; - if(mDetectingKeyboard) - return; - - clearAllControllerBindings(control); - control->setValue(0.5f); //axis bindings must start at 0.5 - control->setInitialValue(0.5f); - ICS::DetectingBindingListener::joystickAxisBindingDetected (ICS, deviceID, control, axis, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - } - - void InputManager::joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) - { - if(mDetectingKeyboard) - return; - clearAllControllerBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, deviceID, control, button, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - } - - void InputManager::clearAllKeyBindings (ICS::Control* control) - { - // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) - mInputBinder->removeKeyBinding (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE)); - if (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - mInputBinder->removeMouseButtonBinding (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE)); - if (mInputBinder->getMouseWheelBinding (control, ICS::Control::INCREASE) != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) - mInputBinder->removeMouseWheelBinding (mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE)); - } - - void InputManager::clearAllControllerBindings (ICS::Control* control) - { - // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) - mInputBinder->removeJoystickAxisBinding (mFakeDeviceID, mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); - if (mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - mInputBinder->removeJoystickButtonBinding (mFakeDeviceID, mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); + mBindingsManager->enableDetectingBindingMode(action, keyboard); } int InputManager::countSavedGameRecords() const @@ -810,12 +267,12 @@ namespace MWInput void InputManager::resetToDefaultKeyBindings() { - loadKeyDefaults(true); + mBindingsManager->loadKeyDefaults(true); } void InputManager::resetToDefaultControllerBindings() { - loadControllerDefaults(true); + mBindingsManager->loadControllerDefaults(true); } void InputManager::setJoystickLastUsed(bool enabled) @@ -827,4 +284,9 @@ namespace MWInput { return mControllerManager->joystickLastUsed(); } + + void InputManager::executeAction(int action) + { + mActionManager->executeAction(action); + } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index ac056809e4..8e8096d924 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -8,9 +8,6 @@ #include #include -#include -#include - #include #include #include @@ -23,6 +20,7 @@ namespace MWInput { class ControlSwitch; class ActionManager; + class BindingsManager; class ControllerManager; class KeyboardManager; class MouseManager; @@ -39,11 +37,6 @@ namespace MWBase class WindowManager; } -namespace ICS -{ - class InputControlSystem; -} - namespace Files { struct ConfigurationManager; @@ -62,9 +55,7 @@ namespace MWInput * @brief Class that handles all input and key bindings for OpenMW. */ class InputManager : - public MWBase::InputManager, - public ICS::ChannelListener, - public ICS::DetectingBindingListener + public MWBase::InputManager { public: InputManager( @@ -89,6 +80,7 @@ namespace MWInput virtual void setDragDrop(bool dragDrop); virtual void setGamepadGuiCursorEnabled(bool enabled); + virtual void setAttemptJump(bool jumping); virtual void toggleControlSwitch (const std::string& sw, bool value); virtual bool getControlSwitch (const std::string& sw); @@ -106,55 +98,25 @@ namespace MWInput virtual void setJoystickLastUsed(bool enabled); virtual bool joystickLastUsed(); - virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue); - - virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , SDL_Scancode key, ICS::Control::ControlChangingDirection direction); - - virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction); - - virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction); - - virtual void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction); - - virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , int axis, ICS::Control::ControlChangingDirection direction); - - virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction); - - void clearAllKeyBindings (ICS::Control* control); - void clearAllControllerBindings (ICS::Control* control); - virtual int countSavedGameRecords() const; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress); virtual void readRecord(ESM::ESMReader& reader, uint32_t type); - virtual void setPlayerControlsEnabled(bool enabled); - virtual void resetIdleTime(); + virtual void executeAction(int action); + private: - ICS::InputControlSystem* mInputBinder; - SDLUtil::InputWrapper* mInputWrapper; - std::string mUserFile; - - bool mDragDrop; - bool mGrabCursor; bool mGuiCursorEnabled; - bool mDetectingKeyboard; - ControlSwitch* mControlSwitch; ActionManager* mActionManager; + BindingsManager* mBindingsManager; ControllerManager* mControllerManager; KeyboardManager* mKeyboardManager; MouseManager* mMouseManager; @@ -166,15 +128,11 @@ namespace MWInput void updateCursorMode(); - void quickKey (int index); + void quickKey(int index); void showQuickKeysMenu(); - bool actionIsActive (int id); - void loadKeyDefaults(bool force = false); void loadControllerDefaults(bool force = false); - - int mFakeDeviceID; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers }; } #endif diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index 773ea4028f..efe9115937 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -2,10 +2,6 @@ #include -#include - -#include - #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" #include "../mwbase/statemanager.hpp" @@ -16,22 +12,18 @@ #include "actionmanager.hpp" #include "actions.hpp" +#include "bindingsmanager.hpp" +#include "sdlmappings.hpp" namespace MWInput { - KeyboardManager::KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager) - : mInputBinder(inputBinder) - , mInputWrapper(inputWrapper) + KeyboardManager::KeyboardManager(BindingsManager* bindingsManager, ActionManager* actionManager) + : mBindingsManager(bindingsManager) , mActionManager(actionManager) , mControlsDisabled(false) { } - bool KeyboardManager::actionIsActive (int id) - { - return (mInputBinder->getChannel(id)->getValue ()==1.0); - } - void KeyboardManager::textInput(const SDL_TextInputEvent &arg) { MyGUI::UString ustring(&arg.text[0]); @@ -42,39 +34,38 @@ namespace MWInput void KeyboardManager::keyPressed(const SDL_KeyboardEvent &arg) { - // HACK: to make Morrowind's default keybinding for the console work without printing an extra "^" upon closing + // HACK: to make default keybinding for the console work without printing an extra "^" upon closing // This assumes that SDL_TextInput events always come *after* the key event // (which is somewhat reasonable, and hopefully true for all SDL platforms) - OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); - if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE) - == arg.keysym.scancode + auto kc = sdlKeyToMyGUI(arg.keysym.sym); + if (mBindingsManager->getKeyBinding(A_Console) == arg.keysym.scancode && MWBase::Environment::get().getWindowManager()->isConsoleMode()) SDL_StopTextInput(); bool consumed = false; - if (kc != OIS::KC_UNASSIGNED && !mInputBinder->detectingBindingState()) + if (kc != MyGUI::KeyCode::None && !mBindingsManager->isDetectingBindingState()) { - consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Enum(kc), 0, arg.repeat); + consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(kc, 0, arg.repeat); if (SDL_IsTextInputActive() && // Little trick to check if key is printable - ( !(SDLK_SCANCODE_MASK & arg.keysym.sym) && std::isprint(arg.keysym.sym))) + (!(SDLK_SCANCODE_MASK & arg.keysym.sym) && std::isprint(arg.keysym.sym))) consumed = true; - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!consumed); + mBindingsManager->setPlayerControlsEnabled(!consumed); } if (arg.repeat) return; if (!mControlsDisabled && !consumed) - mInputBinder->keyPressed(arg); + mBindingsManager->keyPressed(arg); MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); } void KeyboardManager::keyReleased(const SDL_KeyboardEvent &arg) { MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); - OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); + auto kc = sdlKeyToMyGUI(arg.keysym.sym); - if (!mInputBinder->detectingBindingState()) - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); - mInputBinder->keyReleased(arg); + if (!mBindingsManager->isDetectingBindingState()) + mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc)); + mBindingsManager->keyReleased(arg); } } diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index 9d1c0b4fd6..bba2f5dc42 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -9,19 +9,15 @@ namespace SDLUtil class InputWrapper; } -namespace ICS -{ - class InputControlSystem; -} - namespace MWInput { class ActionManager; + class BindingsManager; class KeyboardManager : public SDLUtil::KeyListener { public: - KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager); + KeyboardManager(BindingsManager* bindingsManager, ActionManager* actionManager); virtual ~KeyboardManager() = default; @@ -32,10 +28,7 @@ namespace MWInput void setControlsDisabled(bool disabled) { mControlsDisabled = disabled; } private: - bool actionIsActive(int id); - - ICS::InputControlSystem* mInputBinder; - SDLUtil::InputWrapper* mInputWrapper; + BindingsManager* mBindingsManager; ActionManager* mActionManager; diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index 3fbfc78139..30e32bef8e 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -8,8 +8,6 @@ #include #include -#include - #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" #include "../mwbase/windowmanager.hpp" @@ -18,16 +16,17 @@ #include "../mwworld/player.hpp" #include "actions.hpp" +#include "bindingsmanager.hpp" #include "sdlmappings.hpp" namespace MWInput { - MouseManager::MouseManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window) + 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")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mCameraYMultiplier (Settings::Manager::getFloat("camera y multiplier", "Input")) - , mInputBinder(inputBinder) + , mBindingsManager(bindingsManager) , mInputWrapper(inputWrapper) , mInvUiScalingFactor(1.f) , mGuiCursorX(0) @@ -54,22 +53,22 @@ namespace MWInput void MouseManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "invert x axis") + if (setting.first == "Input" && setting.second == "invert x axis") mInvertX = Settings::Manager::getBool("invert x axis", "Input"); - if (it->first == "Input" && it->second == "invert y axis") + if (setting.first == "Input" && setting.second == "invert y axis") mInvertY = Settings::Manager::getBool("invert y axis", "Input"); - if (it->first == "Input" && it->second == "camera sensitivity") + if (setting.first == "Input" && setting.second == "camera sensitivity") mCameraSensitivity = Settings::Manager::getFloat("camera sensitivity", "Input"); } } void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg) { - mInputBinder->mouseMoved (arg); + mBindingsManager->mouseMoved(arg); MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); input->setJoystickLastUsed(false); @@ -122,26 +121,26 @@ namespace MWInput { MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); - if(mInputBinder->detectingBindingState()) + if(mBindingsManager->isDetectingBindingState()) { - mInputBinder->mouseReleased (arg, id); + mBindingsManager->mouseReleased(arg, id); } else { bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; - if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind + if(mBindingsManager->isDetectingBindingState()) return; // don't allow same mouseup to bind as initiated bind - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!guiMode); - mInputBinder->mouseReleased (arg, id); + mBindingsManager->setPlayerControlsEnabled(!guiMode); + mBindingsManager->mouseReleased(arg, id); } } void MouseManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) { - if (mInputBinder->detectingBindingState() || !mControlsDisabled) - mInputBinder->mouseWheelMoved(arg); + if (mBindingsManager->isDetectingBindingState() || !mControlsDisabled) + mBindingsManager->mouseWheelMoved(arg); MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); } @@ -166,11 +165,11 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->setCursorActive(true); } - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!guiMode); + mBindingsManager->setPlayerControlsEnabled(!guiMode); // Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings) - mInputBinder->mousePressed (arg, id); + mBindingsManager->mousePressed(arg, id); } void MouseManager::update(float dt, bool disableControls) @@ -180,8 +179,8 @@ namespace MWInput if (!mMouseLookEnabled) return; - float xAxis = mInputBinder->getChannel(A_LookLeftRight)->getValue()*2.0f-1.0f; - float yAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; + float xAxis = mBindingsManager->getActionValue(A_LookLeftRight)*2.0f-1.0f; + float yAxis = mBindingsManager->getActionValue(A_LookUpDown)*2.0f-1.0f; if (xAxis == 0 && yAxis == 0) return; diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index 6e59a639b7..2686c59b79 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -9,22 +9,14 @@ namespace SDLUtil class InputWrapper; } -namespace MWWorld -{ - class Player; -} - -namespace ICS -{ - class InputControlSystem; -} - namespace MWInput { + class BindingsManager; + class MouseManager : public SDLUtil::MouseListener { public: - MouseManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window); + MouseManager(BindingsManager* bindingsManager, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window); virtual ~MouseManager() = default; @@ -53,7 +45,7 @@ namespace MWInput float mCameraSensitivity; float mCameraYMultiplier; - ICS::InputControlSystem* mInputBinder; + BindingsManager* mBindingsManager; SDLUtil::InputWrapper* mInputWrapper; float mInvUiScalingFactor; diff --git a/apps/openmw/mwinput/sdlmappings.cpp b/apps/openmw/mwinput/sdlmappings.cpp index 53c9e77fe4..8a9ccf4e79 100644 --- a/apps/openmw/mwinput/sdlmappings.cpp +++ b/apps/openmw/mwinput/sdlmappings.cpp @@ -1,5 +1,7 @@ #include "sdlmappings.hpp" +#include + #include #include @@ -78,4 +80,142 @@ namespace MWInput //MyGUI's buttons are 0 indexed return MyGUI::MouseButton::Enum(button - 1); } + + void initKeyMap(std::map& keyMap) + { + keyMap[SDLK_UNKNOWN] = MyGUI::KeyCode::None; + keyMap[SDLK_ESCAPE] = MyGUI::KeyCode::Escape; + keyMap[SDLK_1] = MyGUI::KeyCode::One; + keyMap[SDLK_2] = MyGUI::KeyCode::Two; + keyMap[SDLK_3] = MyGUI::KeyCode::Three; + keyMap[SDLK_4] = MyGUI::KeyCode::Four; + keyMap[SDLK_5] = MyGUI::KeyCode::Five; + keyMap[SDLK_6] = MyGUI::KeyCode::Six; + keyMap[SDLK_7] = MyGUI::KeyCode::Seven; + keyMap[SDLK_8] = MyGUI::KeyCode::Eight; + keyMap[SDLK_9] = MyGUI::KeyCode::Nine; + keyMap[SDLK_0] = MyGUI::KeyCode::Zero; + keyMap[SDLK_MINUS] = MyGUI::KeyCode::Minus; + keyMap[SDLK_EQUALS] = MyGUI::KeyCode::Equals; + keyMap[SDLK_BACKSPACE] = MyGUI::KeyCode::Backspace; + keyMap[SDLK_TAB] = MyGUI::KeyCode::Tab; + keyMap[SDLK_q] = MyGUI::KeyCode::Q; + keyMap[SDLK_w] = MyGUI::KeyCode::W; + keyMap[SDLK_e] = MyGUI::KeyCode::E; + keyMap[SDLK_r] = MyGUI::KeyCode::R; + keyMap[SDLK_t] = MyGUI::KeyCode::T; + keyMap[SDLK_y] = MyGUI::KeyCode::Y; + keyMap[SDLK_u] = MyGUI::KeyCode::U; + keyMap[SDLK_i] = MyGUI::KeyCode::I; + keyMap[SDLK_o] = MyGUI::KeyCode::O; + keyMap[SDLK_p] = MyGUI::KeyCode::P; + keyMap[SDLK_RETURN] = MyGUI::KeyCode::Return; + keyMap[SDLK_a] = MyGUI::KeyCode::A; + keyMap[SDLK_s] = MyGUI::KeyCode::S; + keyMap[SDLK_d] = MyGUI::KeyCode::D; + keyMap[SDLK_f] = MyGUI::KeyCode::F; + keyMap[SDLK_g] = MyGUI::KeyCode::G; + keyMap[SDLK_h] = MyGUI::KeyCode::H; + keyMap[SDLK_j] = MyGUI::KeyCode::J; + keyMap[SDLK_k] = MyGUI::KeyCode::K; + keyMap[SDLK_l] = MyGUI::KeyCode::L; + keyMap[SDLK_SEMICOLON] = MyGUI::KeyCode::Semicolon; + keyMap[SDLK_QUOTE] = MyGUI::KeyCode::Apostrophe; + keyMap[SDLK_BACKQUOTE] = MyGUI::KeyCode::Grave; + keyMap[SDLK_LSHIFT] = MyGUI::KeyCode::LeftShift; + keyMap[SDLK_BACKSLASH] = MyGUI::KeyCode::Backslash; + keyMap[SDLK_z] = MyGUI::KeyCode::Z; + keyMap[SDLK_x] = MyGUI::KeyCode::X; + keyMap[SDLK_c] = MyGUI::KeyCode::C; + keyMap[SDLK_v] = MyGUI::KeyCode::V; + keyMap[SDLK_b] = MyGUI::KeyCode::B; + keyMap[SDLK_n] = MyGUI::KeyCode::N; + keyMap[SDLK_m] = MyGUI::KeyCode::M; + keyMap[SDLK_COMMA] = MyGUI::KeyCode::Comma; + keyMap[SDLK_PERIOD] = MyGUI::KeyCode::Period; + keyMap[SDLK_SLASH] = MyGUI::KeyCode::Slash; + keyMap[SDLK_RSHIFT] = MyGUI::KeyCode::RightShift; + keyMap[SDLK_KP_MULTIPLY] = MyGUI::KeyCode::Multiply; + keyMap[SDLK_LALT] = MyGUI::KeyCode::LeftAlt; + keyMap[SDLK_SPACE] = MyGUI::KeyCode::Space; + keyMap[SDLK_CAPSLOCK] = MyGUI::KeyCode::Capital; + keyMap[SDLK_F1] = MyGUI::KeyCode::F1; + keyMap[SDLK_F2] = MyGUI::KeyCode::F2; + keyMap[SDLK_F3] = MyGUI::KeyCode::F3; + keyMap[SDLK_F4] = MyGUI::KeyCode::F4; + keyMap[SDLK_F5] = MyGUI::KeyCode::F5; + keyMap[SDLK_F6] = MyGUI::KeyCode::F6; + keyMap[SDLK_F7] = MyGUI::KeyCode::F7; + keyMap[SDLK_F8] = MyGUI::KeyCode::F8; + keyMap[SDLK_F9] = MyGUI::KeyCode::F9; + keyMap[SDLK_F10] = MyGUI::KeyCode::F10; + keyMap[SDLK_NUMLOCKCLEAR] = MyGUI::KeyCode::NumLock; + keyMap[SDLK_SCROLLLOCK] = MyGUI::KeyCode::ScrollLock; + keyMap[SDLK_KP_7] = MyGUI::KeyCode::Numpad7; + keyMap[SDLK_KP_8] = MyGUI::KeyCode::Numpad8; + keyMap[SDLK_KP_9] = MyGUI::KeyCode::Numpad9; + keyMap[SDLK_KP_MINUS] = MyGUI::KeyCode::Subtract; + keyMap[SDLK_KP_4] = MyGUI::KeyCode::Numpad4; + keyMap[SDLK_KP_5] = MyGUI::KeyCode::Numpad5; + keyMap[SDLK_KP_6] = MyGUI::KeyCode::Numpad6; + keyMap[SDLK_KP_PLUS] = MyGUI::KeyCode::Add; + keyMap[SDLK_KP_1] = MyGUI::KeyCode::Numpad1; + keyMap[SDLK_KP_2] = MyGUI::KeyCode::Numpad2; + keyMap[SDLK_KP_3] = MyGUI::KeyCode::Numpad3; + keyMap[SDLK_KP_0] = MyGUI::KeyCode::Numpad0; + keyMap[SDLK_KP_PERIOD] = MyGUI::KeyCode::Decimal; + keyMap[SDLK_F11] = MyGUI::KeyCode::F11; + keyMap[SDLK_F12] = MyGUI::KeyCode::F12; + keyMap[SDLK_F13] = MyGUI::KeyCode::F13; + keyMap[SDLK_F14] = MyGUI::KeyCode::F14; + keyMap[SDLK_F15] = MyGUI::KeyCode::F15; + keyMap[SDLK_KP_EQUALS] = MyGUI::KeyCode::NumpadEquals; + keyMap[SDLK_COLON] = MyGUI::KeyCode::Colon; + keyMap[SDLK_KP_ENTER] = MyGUI::KeyCode::NumpadEnter; + keyMap[SDLK_KP_DIVIDE] = MyGUI::KeyCode::Divide; + keyMap[SDLK_SYSREQ] = MyGUI::KeyCode::SysRq; + keyMap[SDLK_RALT] = MyGUI::KeyCode::RightAlt; + keyMap[SDLK_HOME] = MyGUI::KeyCode::Home; + keyMap[SDLK_UP] = MyGUI::KeyCode::ArrowUp; + keyMap[SDLK_PAGEUP] = MyGUI::KeyCode::PageUp; + keyMap[SDLK_LEFT] = MyGUI::KeyCode::ArrowLeft; + keyMap[SDLK_RIGHT] = MyGUI::KeyCode::ArrowRight; + keyMap[SDLK_END] = MyGUI::KeyCode::End; + keyMap[SDLK_DOWN] = MyGUI::KeyCode::ArrowDown; + keyMap[SDLK_PAGEDOWN] = MyGUI::KeyCode::PageDown; + keyMap[SDLK_INSERT] = MyGUI::KeyCode::Insert; + keyMap[SDLK_DELETE] = MyGUI::KeyCode::Delete; + keyMap[SDLK_APPLICATION] = MyGUI::KeyCode::AppMenu; + +//The function of the Ctrl and Meta keys are switched on macOS compared to other platforms. +//For instance] = Cmd+C versus Ctrl+C to copy from the system clipboard +#if defined(__APPLE__) + keyMap[SDLK_LGUI] = MyGUI::KeyCode::LeftControl; + keyMap[SDLK_RGUI] = MyGUI::KeyCode::RightControl; + keyMap[SDLK_LCTRL] = MyGUI::KeyCode::LeftWindows; + keyMap[SDLK_RCTRL] = MyGUI::KeyCode::RightWindows; +#else + keyMap[SDLK_LGUI] = MyGUI::KeyCode::LeftWindows; + keyMap[SDLK_RGUI] = MyGUI::KeyCode::RightWindows; + keyMap[SDLK_LCTRL] = MyGUI::KeyCode::LeftControl; + keyMap[SDLK_RCTRL] = MyGUI::KeyCode::RightControl; +#endif + } + + MyGUI::KeyCode sdlKeyToMyGUI(SDL_Keycode code) + { + static std::map keyMap; + if (keyMap.empty()) + { + initKeyMap(keyMap); + } + + MyGUI::KeyCode kc = MyGUI::KeyCode::None; + + auto foundKey = keyMap.find(code); + if(foundKey != keyMap.end()) + kc = foundKey->second; + + return kc; + } } diff --git a/apps/openmw/mwinput/sdlmappings.hpp b/apps/openmw/mwinput/sdlmappings.hpp index dd6d750cb2..0cdd4694f5 100644 --- a/apps/openmw/mwinput/sdlmappings.hpp +++ b/apps/openmw/mwinput/sdlmappings.hpp @@ -3,7 +3,9 @@ #include -#include +#include + +#include namespace MyGUI { @@ -17,5 +19,7 @@ namespace MWInput std::string sdlControllerAxisToString(int axis); MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button); + + MyGUI::KeyCode sdlKeyToMyGUI(SDL_Keycode code); } #endif diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index 27879d2141..f78607fa21 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -156,30 +156,30 @@ namespace MWInput void SensorManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "invert x axis") + if (setting.first == "Input" && setting.second == "invert x axis") mInvertX = Settings::Manager::getBool("invert x axis", "Input"); - if (it->first == "Input" && it->second == "invert y axis") + if (setting.first == "Input" && setting.second == "invert y axis") mInvertY = Settings::Manager::getBool("invert y axis", "Input"); - if (it->first == "Input" && it->second == "gyro horizontal sensitivity") + if (setting.first == "Input" && setting.second == "gyro horizontal sensitivity") mGyroHSensitivity = Settings::Manager::getFloat("gyro horizontal sensitivity", "Input"); - if (it->first == "Input" && it->second == "gyro vertical sensitivity") + if (setting.first == "Input" && setting.second == "gyro vertical sensitivity") mGyroVSensitivity = Settings::Manager::getFloat("gyro vertical sensitivity", "Input"); - if (it->first == "Input" && it->second == "enable gyroscope") + if (setting.first == "Input" && setting.second == "enable gyroscope") init(); - if (it->first == "Input" && it->second == "gyro horizontal axis") + if (setting.first == "Input" && setting.second == "gyro horizontal axis") correctGyroscopeAxes(); - if (it->first == "Input" && it->second == "gyro vertical axis") + if (setting.first == "Input" && setting.second == "gyro vertical axis") correctGyroscopeAxes(); - if (it->first == "Input" && it->second == "gyro input threshold") + if (setting.first == "Input" && setting.second == "gyro input threshold") mGyroInputThreshold = Settings::Manager::getFloat("gyro input threshold", "Input"); } } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 06c777c02b..a7d70b4e0e 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -139,7 +139,7 @@ add_component_dir (fontloader ) add_component_dir (sdlutil - sdlgraphicswindow imagetosurface sdlinputwrapper sdlvideowrapper OISCompat events sdlcursormanager + sdlgraphicswindow imagetosurface sdlinputwrapper sdlvideowrapper events sdlcursormanager ) add_component_dir (version diff --git a/components/sdlutil/OISCompat.hpp b/components/sdlutil/OISCompat.hpp deleted file mode 100644 index a0acc5837a..0000000000 --- a/components/sdlutil/OISCompat.hpp +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef OIS_SDL_COMPAT_H -#define OIS_SDL_COMPAT_H - -#include -#include - -namespace OIS -{ -//! Keyboard scan codes -enum KeyCode -{ - KC_UNASSIGNED = 0x00, - KC_ESCAPE = 0x01, - KC_1 = 0x02, - KC_2 = 0x03, - KC_3 = 0x04, - KC_4 = 0x05, - KC_5 = 0x06, - KC_6 = 0x07, - KC_7 = 0x08, - KC_8 = 0x09, - KC_9 = 0x0A, - KC_0 = 0x0B, - KC_MINUS = 0x0C, // - on main keyboard - KC_EQUALS = 0x0D, - KC_BACK = 0x0E, // backspace - KC_TAB = 0x0F, - KC_Q = 0x10, - KC_W = 0x11, - KC_E = 0x12, - KC_R = 0x13, - KC_T = 0x14, - KC_Y = 0x15, - KC_U = 0x16, - KC_I = 0x17, - KC_O = 0x18, - KC_P = 0x19, - KC_LBRACKET = 0x1A, - KC_RBRACKET = 0x1B, - KC_RETURN = 0x1C, // Enter on main keyboard - KC_LCONTROL = 0x1D, - KC_A = 0x1E, - KC_S = 0x1F, - KC_D = 0x20, - KC_F = 0x21, - KC_G = 0x22, - KC_H = 0x23, - KC_J = 0x24, - KC_K = 0x25, - KC_L = 0x26, - KC_SEMICOLON = 0x27, - KC_APOSTROPHE = 0x28, - KC_GRAVE = 0x29, // accent - KC_LSHIFT = 0x2A, - KC_BACKSLASH = 0x2B, - KC_Z = 0x2C, - KC_X = 0x2D, - KC_C = 0x2E, - KC_V = 0x2F, - KC_B = 0x30, - KC_N = 0x31, - KC_M = 0x32, - KC_COMMA = 0x33, - KC_PERIOD = 0x34, // . on main keyboard - KC_SLASH = 0x35, // / on main keyboard - KC_RSHIFT = 0x36, - KC_MULTIPLY = 0x37, // * on numeric keypad - KC_LMENU = 0x38, // left Alt - KC_SPACE = 0x39, - KC_CAPITAL = 0x3A, - KC_F1 = 0x3B, - KC_F2 = 0x3C, - KC_F3 = 0x3D, - KC_F4 = 0x3E, - KC_F5 = 0x3F, - KC_F6 = 0x40, - KC_F7 = 0x41, - KC_F8 = 0x42, - KC_F9 = 0x43, - KC_F10 = 0x44, - KC_NUMLOCK = 0x45, - KC_SCROLL = 0x46, // Scroll Lock - KC_NUMPAD7 = 0x47, - KC_NUMPAD8 = 0x48, - KC_NUMPAD9 = 0x49, - KC_SUBTRACT = 0x4A, // - on numeric keypad - KC_NUMPAD4 = 0x4B, - KC_NUMPAD5 = 0x4C, - KC_NUMPAD6 = 0x4D, - KC_ADD = 0x4E, // + on numeric keypad - KC_NUMPAD1 = 0x4F, - KC_NUMPAD2 = 0x50, - KC_NUMPAD3 = 0x51, - KC_NUMPAD0 = 0x52, - KC_DECIMAL = 0x53, // . on numeric keypad - KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards - KC_F11 = 0x57, - KC_F12 = 0x58, - KC_F13 = 0x64, // (NEC PC98) - KC_F14 = 0x65, // (NEC PC98) - KC_F15 = 0x66, // (NEC PC98) - KC_KANA = 0x70, // (Japanese keyboard) - KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards - KC_CONVERT = 0x79, // (Japanese keyboard) - KC_NOCONVERT = 0x7B, // (Japanese keyboard) - KC_YEN = 0x7D, // (Japanese keyboard) - KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards - KC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98) - KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard) - KC_AT = 0x91, // (NEC PC98) - KC_COLON = 0x92, // (NEC PC98) - KC_UNDERLINE = 0x93, // (NEC PC98) - KC_KANJI = 0x94, // (Japanese keyboard) - KC_STOP = 0x95, // (NEC PC98) - KC_AX = 0x96, // (Japan AX) - KC_UNLABELED = 0x97, // (J3100) - KC_NEXTTRACK = 0x99, // Next Track - KC_NUMPADENTER = 0x9C, // Enter on numeric keypad - KC_RCONTROL = 0x9D, - KC_MUTE = 0xA0, // Mute - KC_CALCULATOR = 0xA1, // Calculator - KC_PLAYPAUSE = 0xA2, // Play / Pause - KC_MEDIASTOP = 0xA4, // Media Stop - KC_VOLUMEDOWN = 0xAE, // Volume - - KC_VOLUMEUP = 0xB0, // Volume + - KC_WEBHOME = 0xB2, // Web home - KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98) - KC_DIVIDE = 0xB5, // / on numeric keypad - KC_SYSRQ = 0xB7, - KC_RMENU = 0xB8, // right Alt - KC_PAUSE = 0xC5, // Pause - KC_HOME = 0xC7, // Home on arrow keypad - KC_UP = 0xC8, // UpArrow on arrow keypad - KC_PGUP = 0xC9, // PgUp on arrow keypad - KC_LEFT = 0xCB, // LeftArrow on arrow keypad - KC_RIGHT = 0xCD, // RightArrow on arrow keypad - KC_END = 0xCF, // End on arrow keypad - KC_DOWN = 0xD0, // DownArrow on arrow keypad - KC_PGDOWN = 0xD1, // PgDn on arrow keypad - KC_INSERT = 0xD2, // Insert on arrow keypad - KC_DELETE = 0xD3, // Delete on arrow keypad - KC_LWIN = 0xDB, // Left Windows key - KC_RWIN = 0xDC, // Right Windows key - KC_APPS = 0xDD, // AppMenu key - KC_POWER = 0xDE, // System Power - KC_SLEEP = 0xDF, // System Sleep - KC_WAKE = 0xE3, // System Wake - KC_WEBSEARCH = 0xE5, // Web Search - KC_WEBFAVORITES= 0xE6, // Web Favorites - KC_WEBREFRESH = 0xE7, // Web Refresh - KC_WEBSTOP = 0xE8, // Web Stop - KC_WEBFORWARD = 0xE9, // Web Forward - KC_WEBBACK = 0xEA, // Web Back - KC_MYCOMPUTER = 0xEB, // My Computer - KC_MAIL = 0xEC, // Mail - KC_MEDIASELECT = 0xED // Media Select -}; -} -#endif diff --git a/components/sdlutil/sdlinputwrapper.cpp b/components/sdlutil/sdlinputwrapper.cpp index 3ea11c6d03..8d6a124e2c 100644 --- a/components/sdlutil/sdlinputwrapper.cpp +++ b/components/sdlutil/sdlinputwrapper.cpp @@ -33,8 +33,6 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr v mWindowHasFocus(true), mMouseInWindow(true) { - _setupOISKeys(); - Uint32 flags = SDL_GetWindowFlags(mSDLWindow); mWindowHasFocus = (flags & SDL_WINDOW_INPUT_FOCUS); mMouseInWindow = (flags & SDL_WINDOW_MOUSE_FOCUS); @@ -397,139 +395,4 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr v return pack_evt; } - - OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code) - { - OIS::KeyCode kc = OIS::KC_UNASSIGNED; - - KeyMap::const_iterator ois_equiv = mKeyMap.find(code); - - if(ois_equiv != mKeyMap.end()) - kc = ois_equiv->second; - - return kc; - } - - void InputWrapper::_setupOISKeys() - { - //lifted from OIS's SDLKeyboard.cpp - - mKeyMap.insert( KeyMap::value_type(SDLK_UNKNOWN, OIS::KC_UNASSIGNED)); - mKeyMap.insert( KeyMap::value_type(SDLK_ESCAPE, OIS::KC_ESCAPE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_1, OIS::KC_1) ); - mKeyMap.insert( KeyMap::value_type(SDLK_2, OIS::KC_2) ); - mKeyMap.insert( KeyMap::value_type(SDLK_3, OIS::KC_3) ); - mKeyMap.insert( KeyMap::value_type(SDLK_4, OIS::KC_4) ); - mKeyMap.insert( KeyMap::value_type(SDLK_5, OIS::KC_5) ); - mKeyMap.insert( KeyMap::value_type(SDLK_6, OIS::KC_6) ); - mKeyMap.insert( KeyMap::value_type(SDLK_7, OIS::KC_7) ); - mKeyMap.insert( KeyMap::value_type(SDLK_8, OIS::KC_8) ); - mKeyMap.insert( KeyMap::value_type(SDLK_9, OIS::KC_9) ); - mKeyMap.insert( KeyMap::value_type(SDLK_0, OIS::KC_0) ); - mKeyMap.insert( KeyMap::value_type(SDLK_MINUS, OIS::KC_MINUS) ); - mKeyMap.insert( KeyMap::value_type(SDLK_EQUALS, OIS::KC_EQUALS) ); - mKeyMap.insert( KeyMap::value_type(SDLK_BACKSPACE, OIS::KC_BACK) ); - mKeyMap.insert( KeyMap::value_type(SDLK_TAB, OIS::KC_TAB) ); - mKeyMap.insert( KeyMap::value_type(SDLK_q, OIS::KC_Q) ); - mKeyMap.insert( KeyMap::value_type(SDLK_w, OIS::KC_W) ); - mKeyMap.insert( KeyMap::value_type(SDLK_e, OIS::KC_E) ); - mKeyMap.insert( KeyMap::value_type(SDLK_r, OIS::KC_R) ); - mKeyMap.insert( KeyMap::value_type(SDLK_t, OIS::KC_T) ); - mKeyMap.insert( KeyMap::value_type(SDLK_y, OIS::KC_Y) ); - mKeyMap.insert( KeyMap::value_type(SDLK_u, OIS::KC_U) ); - mKeyMap.insert( KeyMap::value_type(SDLK_i, OIS::KC_I) ); - mKeyMap.insert( KeyMap::value_type(SDLK_o, OIS::KC_O) ); - mKeyMap.insert( KeyMap::value_type(SDLK_p, OIS::KC_P) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RETURN, OIS::KC_RETURN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_a, OIS::KC_A) ); - mKeyMap.insert( KeyMap::value_type(SDLK_s, OIS::KC_S) ); - mKeyMap.insert( KeyMap::value_type(SDLK_d, OIS::KC_D) ); - mKeyMap.insert( KeyMap::value_type(SDLK_f, OIS::KC_F) ); - mKeyMap.insert( KeyMap::value_type(SDLK_g, OIS::KC_G) ); - mKeyMap.insert( KeyMap::value_type(SDLK_h, OIS::KC_H) ); - mKeyMap.insert( KeyMap::value_type(SDLK_j, OIS::KC_J) ); - mKeyMap.insert( KeyMap::value_type(SDLK_k, OIS::KC_K) ); - mKeyMap.insert( KeyMap::value_type(SDLK_l, OIS::KC_L) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SEMICOLON, OIS::KC_SEMICOLON) ); - mKeyMap.insert( KeyMap::value_type(SDLK_COLON, OIS::KC_COLON) ); - mKeyMap.insert( KeyMap::value_type(SDLK_QUOTE, OIS::KC_APOSTROPHE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_BACKQUOTE, OIS::KC_GRAVE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LSHIFT, OIS::KC_LSHIFT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_BACKSLASH, OIS::KC_BACKSLASH) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SLASH, OIS::KC_SLASH) ); - mKeyMap.insert( KeyMap::value_type(SDLK_z, OIS::KC_Z) ); - mKeyMap.insert( KeyMap::value_type(SDLK_x, OIS::KC_X) ); - mKeyMap.insert( KeyMap::value_type(SDLK_c, OIS::KC_C) ); - mKeyMap.insert( KeyMap::value_type(SDLK_v, OIS::KC_V) ); - mKeyMap.insert( KeyMap::value_type(SDLK_b, OIS::KC_B) ); - mKeyMap.insert( KeyMap::value_type(SDLK_n, OIS::KC_N) ); - mKeyMap.insert( KeyMap::value_type(SDLK_m, OIS::KC_M) ); - mKeyMap.insert( KeyMap::value_type(SDLK_COMMA, OIS::KC_COMMA) ); - mKeyMap.insert( KeyMap::value_type(SDLK_PERIOD, OIS::KC_PERIOD)); - mKeyMap.insert( KeyMap::value_type(SDLK_RSHIFT, OIS::KC_RSHIFT)); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_MULTIPLY, OIS::KC_MULTIPLY) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LALT, OIS::KC_LMENU) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SPACE, OIS::KC_SPACE)); - mKeyMap.insert( KeyMap::value_type(SDLK_CAPSLOCK, OIS::KC_CAPITAL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F1, OIS::KC_F1) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F2, OIS::KC_F2) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F3, OIS::KC_F3) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F4, OIS::KC_F4) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F5, OIS::KC_F5) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F6, OIS::KC_F6) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F7, OIS::KC_F7) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F8, OIS::KC_F8) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F9, OIS::KC_F9) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F10, OIS::KC_F10) ); - mKeyMap.insert( KeyMap::value_type(SDLK_NUMLOCKCLEAR, OIS::KC_NUMLOCK) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SCROLLLOCK, OIS::KC_SCROLL)); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_7, OIS::KC_NUMPAD7) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_8, OIS::KC_NUMPAD8) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_9, OIS::KC_NUMPAD9) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_MINUS, OIS::KC_SUBTRACT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_4, OIS::KC_NUMPAD4) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_5, OIS::KC_NUMPAD5) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_6, OIS::KC_NUMPAD6) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_PLUS, OIS::KC_ADD) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_1, OIS::KC_NUMPAD1) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_2, OIS::KC_NUMPAD2) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_3, OIS::KC_NUMPAD3) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_0, OIS::KC_NUMPAD0) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_PERIOD, OIS::KC_DECIMAL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F11, OIS::KC_F11) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F12, OIS::KC_F12) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F13, OIS::KC_F13) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F14, OIS::KC_F14) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F15, OIS::KC_F15) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_EQUALS, OIS::KC_NUMPADEQUALS) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_DIVIDE, OIS::KC_DIVIDE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SYSREQ, OIS::KC_SYSRQ) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RALT, OIS::KC_RMENU) ); - mKeyMap.insert( KeyMap::value_type(SDLK_HOME, OIS::KC_HOME) ); - mKeyMap.insert( KeyMap::value_type(SDLK_UP, OIS::KC_UP) ); - mKeyMap.insert( KeyMap::value_type(SDLK_PAGEUP, OIS::KC_PGUP) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LEFT, OIS::KC_LEFT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RIGHT, OIS::KC_RIGHT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_END, OIS::KC_END) ); - mKeyMap.insert( KeyMap::value_type(SDLK_DOWN, OIS::KC_DOWN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_PAGEDOWN, OIS::KC_PGDOWN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_INSERT, OIS::KC_INSERT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_DELETE, OIS::KC_DELETE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_ENTER, OIS::KC_NUMPADENTER) ); - mKeyMap.insert( KeyMap::value_type(SDLK_APPLICATION, OIS::KC_APPS) ); - -//The function of the Ctrl and Meta keys are switched on macOS compared to other platforms. -//For instance, Cmd+C versus Ctrl+C to copy from the system clipboard -#if defined(__APPLE__) - mKeyMap.insert( KeyMap::value_type(SDLK_LGUI, OIS::KC_LCONTROL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RGUI, OIS::KC_RCONTROL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, OIS::KC_LWIN)); - mKeyMap.insert( KeyMap::value_type(SDLK_RCTRL, OIS::KC_RWIN) ); -#else - mKeyMap.insert( KeyMap::value_type(SDLK_LGUI, OIS::KC_LWIN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RGUI, OIS::KC_RWIN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, OIS::KC_LCONTROL)); - mKeyMap.insert( KeyMap::value_type(SDLK_RCTRL, OIS::KC_RCONTROL) ); -#endif - } } diff --git a/components/sdlutil/sdlinputwrapper.hpp b/components/sdlutil/sdlinputwrapper.hpp index fde37f35fb..39b6530feb 100644 --- a/components/sdlutil/sdlinputwrapper.hpp +++ b/components/sdlutil/sdlinputwrapper.hpp @@ -8,7 +8,6 @@ #include #include -#include "OISCompat.hpp" #include "events.hpp" namespace osgViewer @@ -40,8 +39,6 @@ namespace SDLUtil bool getMouseRelative() { return mMouseRelative; } void setGrabPointer(bool grab); - OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code); - void warpMouse(int x, int y); void updateMouseSettings(); @@ -53,8 +50,6 @@ namespace SDLUtil void _wrapMousePointer(const SDL_MouseMotionEvent &evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); - void _setupOISKeys(); - SDL_Window* mSDLWindow; osg::ref_ptr mViewer; @@ -64,9 +59,6 @@ namespace SDLUtil WindowListener* mWindowListener; ControllerListener* mConListener; - typedef std::map KeyMap; - KeyMap mKeyMap; - Uint16 mWarpX; Uint16 mWarpY; bool mWarpCompensate; From 3328775eff45c69a841a2c7adf5e518aded2e8c6 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 17 Apr 2020 15:41:52 +0400 Subject: [PATCH 16/23] Unify cursor enabling --- apps/openmw/mwinput/inputmanagerimp.cpp | 11 +++++------ apps/openmw/mwinput/inputmanagerimp.hpp | 2 -- apps/openmw/mwinput/sensormanager.cpp | 5 +++-- apps/openmw/mwinput/sensormanager.hpp | 6 +++++- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 0a43a62fc7..be58ec2654 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -48,7 +48,6 @@ namespace MWInput const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile, bool grab) : mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) - , mGuiCursorEnabled(true) { mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); mInputWrapper->setWindowEventCallback(MWBase::Environment::get().getWindowManager()); @@ -144,7 +143,7 @@ namespace MWInput bool controllerMove = mControllerManager->update(dt, disableControls); mMouseManager->update(dt, disableControls); - mSensorManager->update(dt, mGuiCursorEnabled); + mSensorManager->update(dt); mActionManager->update(dt, controllerMove); } @@ -160,10 +159,10 @@ namespace MWInput void InputManager::changeInputMode(bool guiMode) { - mGuiCursorEnabled = guiMode; - mControllerManager->setGuiCursorEnabled(mGuiCursorEnabled); - mMouseManager->setGuiCursorEnabled(mGuiCursorEnabled); - mMouseManager->setMouseLookEnabled(!mGuiCursorEnabled); + mControllerManager->setGuiCursorEnabled(guiMode); + mMouseManager->setGuiCursorEnabled(guiMode); + mSensorManager->setGuiCursorEnabled(guiMode); + mMouseManager->setMouseLookEnabled(!guiMode); if (guiMode) MWBase::Environment::get().getWindowManager()->showCrosshair(false); MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mControllerManager->joystickLastUsed() || mControllerManager->gamepadGuiCursorEnabled())); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 8e8096d924..f7e732d998 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -111,8 +111,6 @@ namespace MWInput bool mGrabCursor; - bool mGuiCursorEnabled; - ControlSwitch* mControlSwitch; ActionManager* mActionManager; diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index f78607fa21..02669798ca 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -22,6 +22,7 @@ namespace MWInput , mGyroVAxis(GyroscopeAxis::Y) , mGyroInputThreshold(Settings::Manager::getFloat("gyro input threshold", "Input")) , mGyroscope(nullptr) + , mGuiCursorEnabled(true) { init(); } @@ -235,7 +236,7 @@ namespace MWInput } } - void SensorManager::update(float dt, bool isCursorEnabled) + void SensorManager::update(float dt) { if (mGyroXSpeed == 0.f && mGyroYSpeed == 0.f) return; @@ -252,7 +253,7 @@ namespace MWInput mGyroUpdateTimer += dt; - if (!isCursorEnabled) + if (!mGuiCursorEnabled) { float rot[3]; rot[0] = mGyroYSpeed * dt * mGyroVSensitivity * 4 * (mInvertY ? -1 : 1); diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp index 283a53c1f5..9b24328f73 100644 --- a/apps/openmw/mwinput/sensormanager.hpp +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -29,12 +29,14 @@ namespace MWInput void clear(); - void update(float dt, bool isCursorEnabled); + void update(float dt); virtual void sensorUpdated(const SDL_SensorEvent &arg); virtual void displayOrientationChanged(); void processChangedSettings(const Settings::CategorySettingVector& changed); + void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } + private: enum GyroscopeAxis { @@ -66,6 +68,8 @@ namespace MWInput float mGyroInputThreshold; SDL_Sensor* mGyroscope; + + bool mGuiCursorEnabled; }; } #endif From 85f91a7de8e088c26744c3d2d81522f15362c264 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 17 Apr 2020 15:59:37 +0400 Subject: [PATCH 17/23] Remove some redundant code --- apps/openmw/mwinput/inputmanagerimp.cpp | 19 +------------------ apps/openmw/mwinput/inputmanagerimp.hpp | 12 ++---------- apps/openmw/mwinput/keyboardmanager.cpp | 6 +----- apps/openmw/mwinput/keyboardmanager.hpp | 10 +--------- 4 files changed, 5 insertions(+), 42 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index be58ec2654..fb49ff464b 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -2,33 +2,16 @@ #include -#include -#include -#include -#include - -#include - -#include #include #include #include #include -#include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwbase/statemanager.hpp" #include "../mwbase/environment.hpp" -#include "../mwbase/mechanicsmanager.hpp" -#include "../mwworld/player.hpp" -#include "../mwworld/class.hpp" -#include "../mwworld/inventorystore.hpp" #include "../mwworld/esmstore.hpp" -#include "../mwmechanics/npcstats.hpp" -#include "../mwmechanics/actorutil.hpp" - #include "actionmanager.hpp" #include "bindingsmanager.hpp" #include "controllermanager.hpp" @@ -58,7 +41,7 @@ namespace MWInput mActionManager = new ActionManager(mBindingsManager, screenCaptureOperation, viewer, screenCaptureHandler); - mKeyboardManager = new KeyboardManager(mBindingsManager, mActionManager); + mKeyboardManager = new KeyboardManager(mBindingsManager); mInputWrapper->setKeyboardEventCallback(mKeyboardManager); mMouseManager = new MouseManager(mBindingsManager, mInputWrapper, window); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index f7e732d998..211a095831 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -1,19 +1,16 @@ #ifndef MWINPUT_MWINPUTMANAGERIMP_H #define MWINPUT_MWINPUTMANAGERIMP_H -#include "../mwgui/mode.hpp" - -#include - #include #include #include -#include #include #include "../mwbase/inputmanager.hpp" +#include "../mwgui/mode.hpp" + #include "actions.hpp" namespace MWInput @@ -37,11 +34,6 @@ namespace MWBase class WindowManager; } -namespace Files -{ - struct ConfigurationManager; -} - namespace SDLUtil { class InputWrapper; diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index efe9115937..159ea388fa 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -4,22 +4,18 @@ #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" -#include "../mwbase/statemanager.hpp" #include "../mwbase/windowmanager.hpp" -#include "../mwbase/world.hpp" #include "../mwworld/player.hpp" -#include "actionmanager.hpp" #include "actions.hpp" #include "bindingsmanager.hpp" #include "sdlmappings.hpp" namespace MWInput { - KeyboardManager::KeyboardManager(BindingsManager* bindingsManager, ActionManager* actionManager) + KeyboardManager::KeyboardManager(BindingsManager* bindingsManager) : mBindingsManager(bindingsManager) - , mActionManager(actionManager) , mControlsDisabled(false) { } diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index bba2f5dc42..ae473be51b 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -4,20 +4,14 @@ #include #include -namespace SDLUtil -{ - class InputWrapper; -} - namespace MWInput { - class ActionManager; class BindingsManager; class KeyboardManager : public SDLUtil::KeyListener { public: - KeyboardManager(BindingsManager* bindingsManager, ActionManager* actionManager); + KeyboardManager(BindingsManager* bindingsManager); virtual ~KeyboardManager() = default; @@ -30,8 +24,6 @@ namespace MWInput private: BindingsManager* mBindingsManager; - ActionManager* mActionManager; - bool mControlsDisabled; }; } From b575712cb1ce9ddd8d5e15ed2b0601499b97eb22 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 17 Apr 2020 16:51:47 +0400 Subject: [PATCH 18/23] Formatting changes --- apps/openmw/mwinput/actionmanager.cpp | 30 ++++----- apps/openmw/mwinput/actionmanager.hpp | 2 - apps/openmw/mwinput/bindingsmanager.cpp | 80 +++++++++++------------ apps/openmw/mwinput/controllermanager.cpp | 43 ++++++------ apps/openmw/mwinput/controllermanager.hpp | 2 - apps/openmw/mwinput/inputmanagerimp.cpp | 19 +++--- apps/openmw/mwinput/inputmanagerimp.hpp | 48 +++++++------- apps/openmw/mwinput/keyboardmanager.cpp | 2 + apps/openmw/mwinput/mousemanager.cpp | 13 ++-- apps/openmw/mwinput/mousemanager.hpp | 2 - apps/openmw/mwinput/sdlmappings.cpp | 5 +- apps/openmw/mwinput/sensormanager.cpp | 10 +-- apps/openmw/mwinput/sensormanager.hpp | 2 - 13 files changed, 114 insertions(+), 144 deletions(-) diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index e90a4ddaf5..f2af3089df 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -218,22 +218,22 @@ namespace MWInput handleGuiArrowKey(action); break; case A_Journal: - toggleJournal (); + toggleJournal(); break; case A_AutoMove: - toggleAutoMove (); + toggleAutoMove(); break; case A_AlwaysRun: - toggleWalking (); + toggleWalking(); break; case A_ToggleWeapon: - toggleWeapon (); + toggleWeapon(); break; case A_Rest: rest(); break; case A_ToggleSpell: - toggleSpell (); + toggleSpell(); break; case A_QuickKey1: quickKey(1); @@ -344,9 +344,9 @@ namespace MWInput { osg::ref_ptr screenshot (new osg::Image); - if (MWBase::Environment::get().getWorld()->screenshot360(screenshot.get(),settingStr)) + if (MWBase::Environment::get().getWorld()->screenshot360(screenshot.get(), settingStr)) { - (*mScreenCaptureOperation) (*(screenshot.get()),0); + (*mScreenCaptureOperation) (*(screenshot.get()), 0); // FIXME: mScreenCaptureHandler->getCaptureOperation() causes crash for some reason } } @@ -444,10 +444,10 @@ namespace MWInput if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) return; - if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ()) + if (!MWBase::Environment::get().getWindowManager()->getRestEnabled() || MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_Rest); //Open rest GUI + MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Rest); //Open rest GUI } void ActionManager::toggleInventory() @@ -476,7 +476,7 @@ namespace MWInput void ActionManager::toggleConsole() { - if (MyGUI::InputManager::getInstance ().isModalAny()) + if (MyGUI::InputManager::getInstance().isModalAny()) return; MWBase::Environment::get().getWindowManager()->toggleConsole(); @@ -489,14 +489,14 @@ namespace MWInput if (MyGUI::InputManager::getInstance ().isModalAny()) return; - if(MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Journal + if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Journal && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_MainMenu && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings && MWBase::Environment::get().getWindowManager ()->getJournalAllowed()) { MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Journal); } - else if(MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Journal)) + else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Journal)) { MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Journal); } @@ -528,7 +528,7 @@ namespace MWInput } else if (MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_QuickKeysMenu) { - while(MyGUI::InputManager::getInstance().isModalAny()) + while (MyGUI::InputManager::getInstance().isModalAny()) { //Handle any open Modal windows MWBase::Environment::get().getWindowManager()->exitCurrentModal(); } @@ -579,10 +579,6 @@ namespace MWInput player.setSneak(mSneaking); } - void ActionManager::clear() - { - } - void ActionManager::handleGuiArrowKey(int action) { bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp index 31fd993c95..7aa73f5209 100644 --- a/apps/openmw/mwinput/actionmanager.hpp +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -23,8 +23,6 @@ namespace MWInput osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler); - void clear(); - void update(float dt, bool triedToMove); void executeAction(int action); diff --git a/apps/openmw/mwinput/bindingsmanager.cpp b/apps/openmw/mwinput/bindingsmanager.cpp index f871f0c511..f21e184b7a 100644 --- a/apps/openmw/mwinput/bindingsmanager.cpp +++ b/apps/openmw/mwinput/bindingsmanager.cpp @@ -72,7 +72,7 @@ namespace MWInput , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) { //Disallow binding escape key - if(key==SDL_SCANCODE_ESCAPE) + if (key==SDL_SCANCODE_ESCAPE) { //Stop binding if esc pressed mInputBinder->cancelDetectingBindingState(); @@ -90,7 +90,7 @@ namespace MWInput return; #endif - if(!mDetectingKeyboard) + if (!mDetectingKeyboard) return; clearAllKeyBindings(mInputBinder, control); @@ -109,7 +109,7 @@ namespace MWInput virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , unsigned int button, ICS::Control::ControlChangingDirection direction) { - if(!mDetectingKeyboard) + if (!mDetectingKeyboard) return; clearAllKeyBindings(mInputBinder, control); control->setInitialValue(0.0f); @@ -120,7 +120,7 @@ namespace MWInput virtual void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) { - if(!mDetectingKeyboard) + if (!mDetectingKeyboard) return; clearAllKeyBindings(mInputBinder, control); control->setInitialValue(0.0f); @@ -132,9 +132,9 @@ namespace MWInput , int axis, ICS::Control::ControlChangingDirection direction) { //only allow binding to the trigers - if(axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + if (axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) return; - if(mDetectingKeyboard) + if (mDetectingKeyboard) return; clearAllControllerBindings(mInputBinder, control); @@ -147,7 +147,7 @@ namespace MWInput virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control , unsigned int button, ICS::Control::ControlChangingDirection direction) { - if(mDetectingKeyboard) + if (mDetectingKeyboard) return; clearAllControllerBindings(mInputBinder,control); control->setInitialValue(0.0f); @@ -220,8 +220,8 @@ namespace MWInput A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, A_Use, A_Journal}; - for(size_t i = 0; i < sizeof(playerChannels)/sizeof(playerChannels[0]); i++) { - int pc = playerChannels[i]; + for(int pc : playerChannels) + { mInputBinder->getChannel(pc)->setEnabled(enabled); } } @@ -293,7 +293,7 @@ namespace MWInput for (int i = 0; i < A_Last; ++i) { ICS::Control* control; - bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; + bool controlExists = mInputBinder->getChannel(i)->getControlsCount() != 0; if (!controlExists) { control = new ICS::Control(std::to_string(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX); @@ -302,14 +302,13 @@ namespace MWInput } else { - control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; + control = mInputBinder->getChannel(i)->getAttachedControls().front().control; } if (!controlExists || force || - ( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN - && mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS - && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED - )) + (mInputBinder->getKeyBinding(control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN + && mInputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS + && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED)) { clearAllKeyBindings(mInputBinder, control); @@ -323,7 +322,7 @@ namespace MWInput && (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))) { control->setInitialValue(0.0f); - mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); + mInputBinder->addMouseButtonBinding(control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); } else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end() && (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i]))) @@ -379,7 +378,7 @@ namespace MWInput for (int i = 0; i < A_Last; i++) { ICS::Control* control; - bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; + bool controlExists = mInputBinder->getChannel(i)->getControlsCount() != 0; if (!controlExists) { float initial; @@ -392,10 +391,11 @@ namespace MWInput } else { - control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; + control = mInputBinder->getChannel(i)->getAttachedControls().front().control; } - if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, sFakeDeviceId, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, sFakeDeviceId, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) + if (!controlExists || force || (mInputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && + mInputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS)) { clearAllControllerBindings(mInputBinder, control); @@ -415,7 +415,7 @@ namespace MWInput } } - std::string BindingsManager::getActionDescription (int action) + std::string BindingsManager::getActionDescription(int action) { std::map descriptions; @@ -464,24 +464,24 @@ namespace MWInput descriptions[A_QuickSave] = "sQuickSaveCmd"; descriptions[A_QuickLoad] = "sQuickLoadCmd"; - if (descriptions[action] == "") - return ""; // not configurable + if (descriptions[action].empty()) + return std::string(); // not configurable return "#{" + descriptions[action] + "}"; } - std::string BindingsManager::getActionKeyBindingName (int action) + std::string BindingsManager::getActionKeyBindingName(int action) { - if (mInputBinder->getChannel (action)->getControlsCount () == 0) + if (mInputBinder->getChannel(action)->getControlsCount() == 0) return "#{sNone}"; - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; + ICS::Control* c = mInputBinder->getChannel(action)->getAttachedControls().front().control; - SDL_Scancode key = mInputBinder->getKeyBinding (c, ICS::Control::INCREASE); - unsigned int mouse = mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE); + SDL_Scancode key = mInputBinder->getKeyBinding(c, ICS::Control::INCREASE); + unsigned int mouse = mInputBinder->getMouseButtonBinding(c, ICS::Control::INCREASE); ICS::InputControlSystem::MouseWheelClick wheel = mInputBinder->getMouseWheelBinding(c, ICS::Control::INCREASE); if (key != SDL_SCANCODE_UNKNOWN) - return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString (key)); + return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString(key)); else if (mouse != ICS_MAX_DEVICE_BUTTONS) return "#{sMouse} " + std::to_string(mouse); else if (wheel != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) @@ -502,17 +502,17 @@ namespace MWInput return "#{sNone}"; } - std::string BindingsManager::getActionControllerBindingName (int action) + std::string BindingsManager::getActionControllerBindingName(int action) { - if (mInputBinder->getChannel (action)->getControlsCount () == 0) + if (mInputBinder->getChannel(action)->getControlsCount() == 0) return "#{sNone}"; - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; + ICS::Control* c = mInputBinder->getChannel(action)->getAttachedControls().front().control; - if (mInputBinder->getJoystickAxisBinding (c, sFakeDeviceId, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) - return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, sFakeDeviceId, ICS::Control::INCREASE)); - else if (mInputBinder->getJoystickButtonBinding (c, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS ) - return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, sFakeDeviceId, ICS::Control::INCREASE)); + if (mInputBinder->getJoystickAxisBinding(c, sFakeDeviceId, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) + return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding(c, sFakeDeviceId, ICS::Control::INCREASE)); + else if (mInputBinder->getJoystickButtonBinding(c, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding(c, sFakeDeviceId, ICS::Control::INCREASE)); else return "#{sNone}"; } @@ -680,17 +680,17 @@ namespace MWInput if (mDragDrop && action != A_GameMenu && action != A_Inventory) return; - if((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0)) + if ((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0)) { //Is a normal button press, so don't change it at all } //Otherwise only trigger button presses as they go through specific points - else if(previousValue >= .8 && currentValue < .8) + else if (previousValue >= 0.8 && currentValue < 0.8) { currentValue = 0.0; previousValue = 1.0; } - else if(previousValue <= .6 && currentValue > .6) + else if (previousValue <= 0.6 && currentValue > 0.6) { currentValue = 1.0; previousValue = 0.0; @@ -706,7 +706,7 @@ namespace MWInput bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); if (action == A_Use) { - if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) action = A_CycleWeaponRight; else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) @@ -721,7 +721,7 @@ namespace MWInput } else if (action == A_Jump) { - if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) action = A_CycleWeaponLeft; else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index b8fc0ca749..5c5246cafd 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -41,20 +41,21 @@ namespace MWInput , mSneakGamepadShortcut(false) , mGamepadPreviewMode(false) { - if(!controllerBindingsFile.empty()) + if (!controllerBindingsFile.empty()) { SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str()); } - if(!userControllerBindingsFile.empty()) + + if (!userControllerBindingsFile.empty()) { SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str()); } // Open all presently connected sticks int numSticks = SDL_NumJoysticks(); - for(int i = 0; i < numSticks; i++) + for (int i = 0; i < numSticks; i++) { - if(SDL_IsGameController(i)) + if (SDL_IsGameController(i)) { SDL_ControllerDeviceEvent evt; evt.which = i; @@ -73,10 +74,6 @@ namespace MWInput mInvUiScalingFactor = 1.f / uiScale; } - void ControllerManager::clear() - { - } - void ControllerManager::processChangedSettings(const Settings::CategorySettingVector& changed) { for (const auto& setting : changed) @@ -131,13 +128,13 @@ namespace MWInput { float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight); float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward); - if (xAxis != .5) + if (xAxis != 0.5) { triedToMove = true; player.setLeftRight((xAxis - 0.5f) * 2); } - if (yAxis != .5) + if (yAxis != 0.5) { triedToMove = true; player.setAutoMove (false); @@ -153,13 +150,13 @@ namespace MWInput static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input"); if (!isToggleSneak) { - if(mJoystickLastUsed) + if (mJoystickLastUsed) { - if(mBindingsManager->actionIsActive(A_Sneak)) + if (mBindingsManager->actionIsActive(A_Sneak)) { - if(mSneakToggleShortcutTimer) // New Sneak Button Press + if (mSneakToggleShortcutTimer) // New Sneak Button Press { - if(mSneakToggleShortcutTimer <= 0.3f) + if (mSneakToggleShortcutTimer <= 0.3f) { mSneakGamepadShortcut = true; mActionManager->toggleSneaking(); @@ -168,15 +165,15 @@ namespace MWInput mSneakGamepadShortcut = false; } - if(!mActionManager->isSneaking()) + if (!mActionManager->isSneaking()) mActionManager->toggleSneaking(); mSneakToggleShortcutTimer = 0.f; } else { - if(!mSneakGamepadShortcut && mActionManager->isSneaking()) + if (!mSneakGamepadShortcut && mActionManager->isSneaking()) mActionManager->toggleSneaking(); - if(mSneakToggleShortcutTimer <= 0.3f) + if (mSneakToggleShortcutTimer <= 0.3f) mSneakToggleShortcutTimer += dt; } } @@ -190,7 +187,7 @@ namespace MWInput if (!mBindingsManager->actionIsActive(A_TogglePOV)) mGamepadZoom = 0; - if(mGamepadZoom) + if (mGamepadZoom) { MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom); MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true); @@ -210,6 +207,7 @@ namespace MWInput { if (gamepadToGuiControl(arg)) return; + if (mGamepadGuiCursorEnabled) { // Temporary mouse binding until keyboard controls are available: @@ -245,6 +243,7 @@ namespace MWInput mBindingsManager->controllerButtonReleased(deviceID, arg); return; } + if (!mJoystickEnabled || mControlsDisabled) return; @@ -276,7 +275,7 @@ namespace MWInput void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) { - if(!mJoystickEnabled || mControlsDisabled) + if (!mJoystickEnabled || mControlsDisabled) return; mJoystickLastUsed = true; @@ -286,14 +285,14 @@ namespace MWInput } else { - if(mGamepadPreviewMode && arg.value) // Preview Mode Gamepad Zooming + if (mGamepadPreviewMode && arg.value) // Preview Mode Gamepad Zooming { - if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { mGamepadZoom = arg.value * 0.85f / 1000.f; return; // Do not propagate event. } - else if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) + else if (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT) { mGamepadZoom = -arg.value * 0.85f / 1000.f; return; // Do not propagate event. diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index f1be50ee68..6b9546b0c1 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -23,8 +23,6 @@ namespace MWInput virtual ~ControllerManager() = default; - void clear(); - bool update(float dt, bool disableControls); virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index fb49ff464b..4f1ee78550 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -58,11 +58,6 @@ namespace MWInput { // Enable all controls mControlSwitch->clear(); - - mActionManager->clear(); - mControllerManager->clear(); - mSensorManager->clear(); - mMouseManager->clear(); } InputManager::~InputManager() @@ -90,19 +85,19 @@ namespace MWInput bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) && !MWBase::Environment::get().getWindowManager()->isConsoleMode(); - bool was_relative = mInputWrapper->getMouseRelative(); - bool is_relative = !MWBase::Environment::get().getWindowManager()->isGuiMode(); + bool wasRelative = mInputWrapper->getMouseRelative(); + bool isRelative = !MWBase::Environment::get().getWindowManager()->isGuiMode(); // don't keep the pointer away from the window edge in gui mode // stop using raw mouse motions and switch to system cursor movements - mInputWrapper->setMouseRelative(is_relative); + mInputWrapper->setMouseRelative(isRelative); //we let the mouse escape in the main menu - mInputWrapper->setGrabPointer(grab && (mGrabCursor || is_relative)); + mInputWrapper->setGrabPointer(grab && (mGrabCursor || isRelative)); //we switched to non-relative mode, move our cursor to where the in-game //cursor is - if(!is_relative && was_relative != is_relative) + if (!isRelative && wasRelative != isRelative) { mMouseManager->warpMouse(); } @@ -148,7 +143,9 @@ namespace MWInput mMouseManager->setMouseLookEnabled(!guiMode); if (guiMode) MWBase::Environment::get().getWindowManager()->showCrosshair(false); - MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mControllerManager->joystickLastUsed() || mControllerManager->gamepadGuiCursorEnabled())); + + bool isCursorVisible = guiMode && (!mControllerManager->joystickLastUsed() || mControllerManager->gamepadGuiCursorEnabled()); + MWBase::Environment::get().getWindowManager()->setCursorVisible(isCursorVisible); // if not in gui mode, the camera decides whether to show crosshair or not. } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 211a095831..4ecb6a82d5 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -13,17 +13,6 @@ #include "actions.hpp" -namespace MWInput -{ - class ControlSwitch; - class ActionManager; - class BindingsManager; - class ControllerManager; - class KeyboardManager; - class MouseManager; - class SensorManager; -} - namespace MWWorld { class Player; @@ -43,11 +32,18 @@ struct SDL_Window; namespace MWInput { + class ControlSwitch; + class ActionManager; + class BindingsManager; + class ControllerManager; + class KeyboardManager; + class MouseManager; + class SensorManager; + /** - * @brief Class that handles all input and key bindings for OpenMW. + * @brief Class that provides a high-level API for game input */ - class InputManager : - public MWBase::InputManager + class InputManager : public MWBase::InputManager { public: InputManager( @@ -99,6 +95,18 @@ namespace MWInput virtual void executeAction(int action); private: + void convertMousePosForMyGUI(int& x, int& y); + + void handleGuiArrowKey(int action); + + void updateCursorMode(); + + void quickKey(int index); + void showQuickKeysMenu(); + + void loadKeyDefaults(bool force = false); + void loadControllerDefaults(bool force = false); + SDLUtil::InputWrapper* mInputWrapper; bool mGrabCursor; @@ -111,18 +119,6 @@ namespace MWInput KeyboardManager* mKeyboardManager; MouseManager* mMouseManager; SensorManager* mSensorManager; - - void convertMousePosForMyGUI(int& x, int& y); - - void handleGuiArrowKey(int action); - - void updateCursorMode(); - - void quickKey(int index); - void showQuickKeysMenu(); - - void loadKeyDefaults(bool force = false); - void loadControllerDefaults(bool force = false); }; } #endif diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index 159ea388fa..afeef632fb 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -47,11 +47,13 @@ namespace MWInput consumed = true; mBindingsManager->setPlayerControlsEnabled(!consumed); } + if (arg.repeat) return; if (!mControlsDisabled && !consumed) mBindingsManager->keyPressed(arg); + MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); } diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index 30e32bef8e..cc20cc1ef1 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -47,10 +47,6 @@ namespace MWInput mGuiCursorY = mInvUiScalingFactor * h / 2.f; } - void MouseManager::clear() - { - } - void MouseManager::processChangedSettings(const Settings::CategorySettingVector& changed) { for (const auto& setting : changed) @@ -103,7 +99,7 @@ namespace MWInput rot[2] = -x; // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && input->getControlSwitch("playerlooking")) + if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && input->getControlSwitch("playerlooking")) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); player.yaw(x); @@ -130,7 +126,8 @@ namespace MWInput bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; - if(mBindingsManager->isDetectingBindingState()) return; // don't allow same mouseup to bind as initiated bind + if (mBindingsManager->isDetectingBindingState()) + return; // don't allow same mouseup to bind as initiated bind mBindingsManager->setPlayerControlsEnabled(!guiMode); mBindingsManager->mouseReleased(arg, id); @@ -154,9 +151,9 @@ namespace MWInput { guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); guiMode = MyGUI::InputManager::getInstance().injectMousePress(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; - if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) + if (MyGUI::InputManager::getInstance().getMouseFocusWidget () != 0) { - MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); + MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType(false); if (b && b->getEnabled() && id == SDL_BUTTON_LEFT) { MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index 2686c59b79..58d97f6e5d 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -20,8 +20,6 @@ namespace MWInput virtual ~MouseManager() = default; - void clear(); - void update(float dt, bool disableControls); virtual void mouseMoved(const SDLUtil::MouseMotionEvent &arg); diff --git a/apps/openmw/mwinput/sdlmappings.cpp b/apps/openmw/mwinput/sdlmappings.cpp index 8a9ccf4e79..0c3f5c5d85 100644 --- a/apps/openmw/mwinput/sdlmappings.cpp +++ b/apps/openmw/mwinput/sdlmappings.cpp @@ -206,14 +206,11 @@ namespace MWInput { static std::map keyMap; if (keyMap.empty()) - { initKeyMap(keyMap); - } MyGUI::KeyCode kc = MyGUI::KeyCode::None; - auto foundKey = keyMap.find(code); - if(foundKey != keyMap.end()) + if (foundKey != keyMap.end()) kc = foundKey->second; return kc; diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index 02669798ca..d70662f6a7 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -33,13 +33,6 @@ namespace MWInput updateSensors(); } - void SensorManager::clear() - { - mGyroXSpeed = 0.f; - mGyroYSpeed = 0.f; - mGyroUpdateTimer = 0.f; - } - SensorManager::~SensorManager() { if (mGyroscope != nullptr) @@ -246,7 +239,8 @@ namespace MWInput // More than half of second passed since the last gyroscope update. // A device more likely was disconnected or switched to the sleep mode. // Reset current rotation speed and wait for update. - clear(); + mGyroXSpeed = 0.f; + mGyroYSpeed = 0.f; mGyroUpdateTimer = 0.f; return; } diff --git a/apps/openmw/mwinput/sensormanager.hpp b/apps/openmw/mwinput/sensormanager.hpp index 9b24328f73..8f333ad314 100644 --- a/apps/openmw/mwinput/sensormanager.hpp +++ b/apps/openmw/mwinput/sensormanager.hpp @@ -27,8 +27,6 @@ namespace MWInput void init(); - void clear(); - void update(float dt); virtual void sensorUpdated(const SDL_SensorEvent &arg); From 0455f48d0218c3abd3e534d57e0581f5e0a7d143 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 17 Apr 2020 17:06:19 +0400 Subject: [PATCH 19/23] More formatting changes --- apps/openmw/mwinput/controllermanager.cpp | 9 ++++----- apps/openmw/mwinput/mousemanager.cpp | 22 +++++++++++----------- apps/openmw/mwinput/sensormanager.cpp | 19 +++++++++---------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index 5c5246cafd..a71c5b31a2 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -90,9 +90,9 @@ namespace MWInput if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) { - float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight)*2.0f-1.0f; - float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward)*2.0f-1.0f; - float zAxis = mBindingsManager->getActionValue(A_LookUpDown)*2.0f-1.0f; + float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight) * 2.0f - 1.0f; + float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward) * 2.0f - 1.0f; + float zAxis = mBindingsManager->getActionValue(A_LookUpDown) * 2.0f - 1.0f; xAxis *= (1.5f - mBindingsManager->getActionValue(A_Use)); yAxis *= (1.5f - mBindingsManager->getActionValue(A_Use)); @@ -138,7 +138,7 @@ namespace MWInput { triedToMove = true; player.setAutoMove (false); - player.setForwardBackward((yAxis - 0.5f) * 2 * -1); + player.setForwardBackward((0.5f - yAxis) * 2); } if (triedToMove) @@ -316,7 +316,6 @@ namespace MWInput { // Presumption of GUI mode will be removed in the future. // MyGUI KeyCodes *may* change. - MyGUI::KeyCode key = MyGUI::KeyCode::None; switch (arg.button) { diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index cc20cc1ef1..2cce1cd800 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -90,8 +90,8 @@ namespace MWInput if (mMouseLookEnabled && !mControlsDisabled) { - float x = arg.xrel * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); - float y = arg.yrel * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; + float x = arg.xrel * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f; + float y = arg.yrel * mCameraSensitivity * (mInvertY ? -1 : 1) * mCameraYMultiplier / 256.f; float rot[3]; rot[0] = -y; @@ -117,7 +117,7 @@ namespace MWInput { MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); - if(mBindingsManager->isDetectingBindingState()) + if (mBindingsManager->isDetectingBindingState()) { mBindingsManager->mouseReleased(arg, id); } @@ -176,18 +176,18 @@ namespace MWInput if (!mMouseLookEnabled) return; - float xAxis = mBindingsManager->getActionValue(A_LookLeftRight)*2.0f-1.0f; - float yAxis = mBindingsManager->getActionValue(A_LookUpDown)*2.0f-1.0f; + float xAxis = mBindingsManager->getActionValue(A_LookLeftRight) * 2.0f - 1.0f; + float yAxis = mBindingsManager->getActionValue(A_LookUpDown) * 2.0f - 1.0f; if (xAxis == 0 && yAxis == 0) return; float rot[3]; - rot[0] = yAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertY ? -1 : 1) * mCameraYMultiplier; + rot[0] = yAxis * dt * 1000.0f * mCameraSensitivity * (mInvertY ? -1 : 1) * mCameraYMultiplier / 256.f; rot[1] = 0.0f; - rot[2] = xAxis * (dt * 100.0f) * 10.0f * mCameraSensitivity * (1.0f/256.f) * (mInvertX ? -1 : 1); + rot[2] = xAxis * dt * 1000.0f * mCameraSensitivity * (mInvertX ? -1 : 1) / 256.f; // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); player.yaw(rot[2]); @@ -214,14 +214,14 @@ namespace MWInput mMouseWheel += mouseWheelMove; const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize(); - mGuiCursorX = std::max(0.f, std::min(mGuiCursorX, float(viewSize.width-1))); - mGuiCursorY = std::max(0.f, std::min(mGuiCursorY, float(viewSize.height-1))); + mGuiCursorX = std::max(0.f, std::min(mGuiCursorX, float(viewSize.width - 1))); + mGuiCursorY = std::max(0.f, std::min(mGuiCursorY, float(viewSize.height - 1))); MyGUI::InputManager::getInstance().injectMouseMove(static_cast(mGuiCursorX), static_cast(mGuiCursorY), mMouseWheel); } void MouseManager::warpMouse() { - mInputWrapper->warpMouse(static_cast(mGuiCursorX/mInvUiScalingFactor), static_cast(mGuiCursorY/mInvUiScalingFactor)); + mInputWrapper->warpMouse(static_cast(mGuiCursorX / mInvUiScalingFactor), static_cast(mGuiCursorY / mInvUiScalingFactor)); } } diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index d70662f6a7..f3c2c2305c 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -109,7 +109,6 @@ namespace MWInput if (Settings::Manager::getBool("enable gyroscope", "Input")) { int numSensors = SDL_NumSensors(); - for (int i = 0; i < numSensors; ++i) { if (SDL_SensorGetDeviceType(i) == SDL_SENSOR_GYRO) @@ -214,15 +213,15 @@ namespace MWInput switch (SDL_SensorGetType(sensor)) { - case SDL_SENSOR_ACCEL: - break; - case SDL_SENSOR_GYRO: - { - mGyroXSpeed = getGyroAxisSpeed(mGyroHAxis, arg); - mGyroYSpeed = getGyroAxisSpeed(mGyroVAxis, arg); - mGyroUpdateTimer = 0.f; + case SDL_SENSOR_ACCEL: + break; + case SDL_SENSOR_GYRO: + { + mGyroXSpeed = getGyroAxisSpeed(mGyroHAxis, arg); + mGyroYSpeed = getGyroAxisSpeed(mGyroVAxis, arg); + mGyroUpdateTimer = 0.f; - break; + break; } default: break; @@ -255,7 +254,7 @@ namespace MWInput rot[2] = mGyroXSpeed * dt * mGyroHSensitivity * 4 * (mInvertX ? -1 : 1); // Only actually turn player when we're not in vanity mode - if(!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking")) + if (!MWBase::Environment::get().getWorld()->vanityRotateCamera(rot) && MWBase::Environment::get().getInputManager()->getControlSwitch("playerlooking")) { MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); player.yaw(rot[2]); From b4e52a6bc8751fbd49e3f2a96294934f865501d9 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 17 Apr 2020 20:03:00 +0400 Subject: [PATCH 20/23] Add missing include --- apps/openmw/mwinput/keyboardmanager.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index afeef632fb..20115155e7 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -1,5 +1,7 @@ #include "keyboardmanager.hpp" +#include + #include #include "../mwbase/environment.hpp" From 73552f1d3cfb2c9de93017b82bed7dfdd6b43a81 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Fri, 24 Apr 2020 12:43:17 +0400 Subject: [PATCH 21/23] Move control switch reading/writing to relevant class --- apps/openmw/mwinput/controlswitch.cpp | 41 +++++++++++++++++++++++++ apps/openmw/mwinput/controlswitch.hpp | 16 ++++++++++ apps/openmw/mwinput/inputmanagerimp.cpp | 28 +++-------------- 3 files changed, 61 insertions(+), 24 deletions(-) diff --git a/apps/openmw/mwinput/controlswitch.cpp b/apps/openmw/mwinput/controlswitch.cpp index 6ea51064fc..33c4b75dcc 100644 --- a/apps/openmw/mwinput/controlswitch.cpp +++ b/apps/openmw/mwinput/controlswitch.cpp @@ -1,5 +1,11 @@ #include "controlswitch.hpp" +#include +#include +#include + +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -55,4 +61,39 @@ namespace MWInput } mSwitches[key] = value; } + + void ControlSwitch::write(ESM::ESMWriter& writer, Loading::Listener& /*progress*/) + { + ESM::ControlsState controls; + controls.mViewSwitchDisabled = !mSwitches["playerviewswitch"]; + controls.mControlsDisabled = !mSwitches["playercontrols"]; + controls.mJumpingDisabled = !mSwitches["playerjumping"]; + controls.mLookingDisabled = !mSwitches["playerlooking"]; + controls.mVanityModeDisabled = !mSwitches["vanitymode"]; + controls.mWeaponDrawingDisabled = !mSwitches["playerfighting"]; + controls.mSpellDrawingDisabled = !mSwitches["playermagic"]; + + writer.startRecord (ESM::REC_INPU); + controls.save(writer); + writer.endRecord (ESM::REC_INPU); + } + + void ControlSwitch::readRecord(ESM::ESMReader& reader, uint32_t type) + { + ESM::ControlsState controls; + controls.load(reader); + + set("playerviewswitch", !controls.mViewSwitchDisabled); + set("playercontrols", !controls.mControlsDisabled); + set("playerjumping", !controls.mJumpingDisabled); + set("playerlooking", !controls.mLookingDisabled); + set("vanitymode", !controls.mVanityModeDisabled); + set("playerfighting", !controls.mWeaponDrawingDisabled); + set("playermagic", !controls.mSpellDrawingDisabled); + } + + int ControlSwitch::countSavedGameRecords() const + { + return 1; + } } diff --git a/apps/openmw/mwinput/controlswitch.hpp b/apps/openmw/mwinput/controlswitch.hpp index 5fa475e770..3ca989e2ad 100644 --- a/apps/openmw/mwinput/controlswitch.hpp +++ b/apps/openmw/mwinput/controlswitch.hpp @@ -3,6 +3,18 @@ #include +namespace ESM +{ + struct ControlsState; + class ESMReader; + class ESMWriter; +} + +namespace Loading +{ + class Listener; +} + namespace MWInput { class ControlSwitch @@ -14,6 +26,10 @@ namespace MWInput void set(const std::string& key, bool value); void clear(); + void write(ESM::ESMWriter& writer, Loading::Listener& progress); + void readRecord(ESM::ESMReader& reader, uint32_t type); + int countSavedGameRecords() const; + private: std::map mSwitches; }; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 4f1ee78550..48e1581be0 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -208,39 +208,19 @@ namespace MWInput int InputManager::countSavedGameRecords() const { - return 1; + return mControlSwitch->countSavedGameRecords(); } - void InputManager::write(ESM::ESMWriter& writer, Loading::Listener& /*progress*/) + void InputManager::write(ESM::ESMWriter& writer, Loading::Listener& progress) { - ESM::ControlsState controls; - controls.mViewSwitchDisabled = !getControlSwitch("playerviewswitch"); - controls.mControlsDisabled = !getControlSwitch("playercontrols"); - controls.mJumpingDisabled = !getControlSwitch("playerjumping"); - controls.mLookingDisabled = !getControlSwitch("playerlooking"); - controls.mVanityModeDisabled = !getControlSwitch("vanitymode"); - controls.mWeaponDrawingDisabled = !getControlSwitch("playerfighting"); - controls.mSpellDrawingDisabled = !getControlSwitch("playermagic"); - - writer.startRecord (ESM::REC_INPU); - controls.save(writer); - writer.endRecord (ESM::REC_INPU); + mControlSwitch->write(writer, progress); } void InputManager::readRecord(ESM::ESMReader& reader, uint32_t type) { if (type == ESM::REC_INPU) { - ESM::ControlsState controls; - controls.load(reader); - - toggleControlSwitch("playerviewswitch", !controls.mViewSwitchDisabled); - toggleControlSwitch("playercontrols", !controls.mControlsDisabled); - toggleControlSwitch("playerjumping", !controls.mJumpingDisabled); - toggleControlSwitch("playerlooking", !controls.mLookingDisabled); - toggleControlSwitch("vanitymode", !controls.mVanityModeDisabled); - toggleControlSwitch("playerfighting", !controls.mWeaponDrawingDisabled); - toggleControlSwitch("playermagic", !controls.mSpellDrawingDisabled); + mControlSwitch->readRecord(reader, type); } } From a6514e7740712b92a69d57d901c1a95d7b338cf1 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sat, 9 May 2020 11:28:30 +0400 Subject: [PATCH 22/23] Add missing include --- apps/openmw/mwinput/controlswitch.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwinput/controlswitch.hpp b/apps/openmw/mwinput/controlswitch.hpp index 3ca989e2ad..38d01066bd 100644 --- a/apps/openmw/mwinput/controlswitch.hpp +++ b/apps/openmw/mwinput/controlswitch.hpp @@ -2,6 +2,7 @@ #define MWINPUT_CONTROLSWITCH_H #include +#include namespace ESM { From 41beca8125563729643407662ec51c04ddaa971c Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 10 May 2020 10:13:19 +0400 Subject: [PATCH 23/23] Refactor actions order setup --- apps/openmw/mwinput/bindingsmanager.cpp | 228 +++++++++++------------- 1 file changed, 102 insertions(+), 126 deletions(-) diff --git a/apps/openmw/mwinput/bindingsmanager.cpp b/apps/openmw/mwinput/bindingsmanager.cpp index f21e184b7a..11f714205d 100644 --- a/apps/openmw/mwinput/bindingsmanager.cpp +++ b/apps/openmw/mwinput/bindingsmanager.cpp @@ -417,57 +417,89 @@ namespace MWInput std::string BindingsManager::getActionDescription(int action) { - std::map descriptions; - - if (action == A_Screenshot) - return "Screenshot"; - else if (action == A_ZoomIn) - return "Zoom In"; - else if (action == A_ZoomOut) - return "Zoom Out"; - else if (action == A_ToggleHUD) - return "Toggle HUD"; - - descriptions[A_Use] = "sUse"; - descriptions[A_Activate] = "sActivate"; - descriptions[A_MoveBackward] = "sBack"; - descriptions[A_MoveForward] = "sForward"; - descriptions[A_MoveLeft] = "sLeft"; - descriptions[A_MoveRight] = "sRight"; - descriptions[A_ToggleWeapon] = "sReady_Weapon"; - descriptions[A_ToggleSpell] = "sReady_Magic"; - descriptions[A_CycleSpellLeft] = "sPrevSpell"; - descriptions[A_CycleSpellRight] = "sNextSpell"; - descriptions[A_CycleWeaponLeft] = "sPrevWeapon"; - descriptions[A_CycleWeaponRight] = "sNextWeapon"; - descriptions[A_Console] = "sConsoleTitle"; - descriptions[A_Run] = "sRun"; - descriptions[A_Sneak] = "sCrouch_Sneak"; - descriptions[A_AutoMove] = "sAuto_Run"; - descriptions[A_Jump] = "sJump"; - descriptions[A_Journal] = "sJournal"; - descriptions[A_Rest] = "sRestKey"; - descriptions[A_Inventory] = "sInventory"; - descriptions[A_TogglePOV] = "sTogglePOVCmd"; - descriptions[A_QuickKeysMenu] = "sQuickMenu"; - descriptions[A_QuickKey1] = "sQuick1Cmd"; - descriptions[A_QuickKey2] = "sQuick2Cmd"; - descriptions[A_QuickKey3] = "sQuick3Cmd"; - descriptions[A_QuickKey4] = "sQuick4Cmd"; - descriptions[A_QuickKey5] = "sQuick5Cmd"; - descriptions[A_QuickKey6] = "sQuick6Cmd"; - descriptions[A_QuickKey7] = "sQuick7Cmd"; - descriptions[A_QuickKey8] = "sQuick8Cmd"; - descriptions[A_QuickKey9] = "sQuick9Cmd"; - descriptions[A_QuickKey10] = "sQuick10Cmd"; - descriptions[A_AlwaysRun] = "sAlways_Run"; - descriptions[A_QuickSave] = "sQuickSaveCmd"; - descriptions[A_QuickLoad] = "sQuickLoadCmd"; - - if (descriptions[action].empty()) - return std::string(); // not configurable - - return "#{" + descriptions[action] + "}"; + switch (action) + { + case A_Screenshot: + return "Screenshot"; + case A_ZoomIn: + return "Zoom In"; + case A_ZoomOut: + return "Zoom Out"; + case A_ToggleHUD: + return "Toggle HUD"; + case A_Use: + return "#{sUse}"; + case A_Activate: + return "#{sActivate}"; + case A_MoveBackward: + return "#{sBack}"; + case A_MoveForward: + return "#{sForward}"; + case A_MoveLeft: + return "#{sLeft}"; + case A_MoveRight: + return "#{sRight}"; + case A_ToggleWeapon: + return "#{sReady_Weapon}"; + case A_ToggleSpell: + return "#{sReady_Magic}"; + case A_CycleSpellLeft: + return "#{sPrevSpell}"; + case A_CycleSpellRight: + return "#{sNextSpell}"; + case A_CycleWeaponLeft: + return "#{sPrevWeapon}"; + case A_CycleWeaponRight: + return "#{sNextWeapon}"; + case A_Console: + return "#{sConsoleTitle}"; + case A_Run: + return "#{sRun}"; + case A_Sneak: + return "#{sCrouch_Sneak}"; + case A_AutoMove: + return "#{sAuto_Run}"; + case A_Jump: + return "#{sJump}"; + case A_Journal: + return "#{sJournal}"; + case A_Rest: + return "#{sRestKey}"; + case A_Inventory: + return "#{sInventory}"; + case A_TogglePOV: + return "#{sTogglePOVCmd}"; + case A_QuickKeysMenu: + return "#{sQuickMenu}"; + case A_QuickKey1: + return "#{sQuick1Cmd}"; + case A_QuickKey2: + return "#{sQuick2Cmd}"; + case A_QuickKey3: + return "#{sQuick3Cmd}"; + case A_QuickKey4: + return "#{sQuick4Cmd}"; + case A_QuickKey5: + return "#{sQuick5Cmd}"; + case A_QuickKey6: + return "#{sQuick6Cmd}"; + case A_QuickKey7: + return "#{sQuick7Cmd}"; + case A_QuickKey8: + return "#{sQuick8Cmd}"; + case A_QuickKey9: + return "#{sQuick9Cmd}"; + case A_QuickKey10: + return "#{sQuick10Cmd}"; + case A_AlwaysRun: + return "#{sAlways_Run}"; + case A_QuickSave: + return "#{sQuickSaveCmd}"; + case A_QuickLoad: + return "#{sQuickLoadCmd}"; + default: + return std::string(); // not configurable + } } std::string BindingsManager::getActionKeyBindingName(int action) @@ -519,86 +551,30 @@ namespace MWInput std::vector BindingsManager::getActionKeySorting() { - std::vector ret; - ret.push_back(A_MoveForward); - ret.push_back(A_MoveBackward); - ret.push_back(A_MoveLeft); - ret.push_back(A_MoveRight); - ret.push_back(A_TogglePOV); - ret.push_back(A_ZoomIn); - ret.push_back(A_ZoomOut); - ret.push_back(A_Run); - ret.push_back(A_AlwaysRun); - ret.push_back(A_Sneak); - ret.push_back(A_Activate); - ret.push_back(A_Use); - ret.push_back(A_ToggleWeapon); - ret.push_back(A_ToggleSpell); - ret.push_back(A_CycleSpellLeft); - ret.push_back(A_CycleSpellRight); - ret.push_back(A_CycleWeaponLeft); - ret.push_back(A_CycleWeaponRight); - ret.push_back(A_AutoMove); - ret.push_back(A_Jump); - ret.push_back(A_Inventory); - ret.push_back(A_Journal); - ret.push_back(A_Rest); - ret.push_back(A_Console); - ret.push_back(A_QuickSave); - ret.push_back(A_QuickLoad); - ret.push_back(A_ToggleHUD); - ret.push_back(A_Screenshot); - ret.push_back(A_QuickKeysMenu); - ret.push_back(A_QuickKey1); - ret.push_back(A_QuickKey2); - ret.push_back(A_QuickKey3); - ret.push_back(A_QuickKey4); - ret.push_back(A_QuickKey5); - ret.push_back(A_QuickKey6); - ret.push_back(A_QuickKey7); - ret.push_back(A_QuickKey8); - ret.push_back(A_QuickKey9); - ret.push_back(A_QuickKey10); + static const std::vector actions + { + A_MoveForward, A_MoveBackward, A_MoveLeft, A_MoveRight, A_TogglePOV, A_ZoomIn, A_ZoomOut, + A_Run, A_AlwaysRun, A_Sneak, A_Activate, A_Use, A_ToggleWeapon, A_ToggleSpell, + A_CycleSpellLeft, A_CycleSpellRight, A_CycleWeaponLeft, A_CycleWeaponRight, A_AutoMove, + A_Jump, A_Inventory, A_Journal, A_Rest, A_Console, A_QuickSave, A_QuickLoad, + A_ToggleHUD, A_Screenshot, A_QuickKeysMenu, A_QuickKey1, A_QuickKey2, A_QuickKey3, + A_QuickKey4, A_QuickKey5, A_QuickKey6, A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10 + }; - return ret; + return actions; } std::vector BindingsManager::getActionControllerSorting() { - std::vector ret; - ret.push_back(A_TogglePOV); - ret.push_back(A_ZoomIn); - ret.push_back(A_ZoomOut); - ret.push_back(A_Sneak); - ret.push_back(A_Activate); - ret.push_back(A_Use); - ret.push_back(A_ToggleWeapon); - ret.push_back(A_ToggleSpell); - ret.push_back(A_AutoMove); - ret.push_back(A_Jump); - ret.push_back(A_Inventory); - ret.push_back(A_Journal); - ret.push_back(A_Rest); - ret.push_back(A_QuickSave); - ret.push_back(A_QuickLoad); - ret.push_back(A_ToggleHUD); - ret.push_back(A_Screenshot); - ret.push_back(A_QuickKeysMenu); - ret.push_back(A_QuickKey1); - ret.push_back(A_QuickKey2); - ret.push_back(A_QuickKey3); - ret.push_back(A_QuickKey4); - ret.push_back(A_QuickKey5); - ret.push_back(A_QuickKey6); - ret.push_back(A_QuickKey7); - ret.push_back(A_QuickKey8); - ret.push_back(A_QuickKey9); - ret.push_back(A_QuickKey10); - ret.push_back(A_CycleSpellLeft); - ret.push_back(A_CycleSpellRight); - ret.push_back(A_CycleWeaponLeft); - ret.push_back(A_CycleWeaponRight); + static const std::vector actions + { + A_TogglePOV, A_ZoomIn, A_ZoomOut, A_Sneak, A_Activate, A_Use, A_ToggleWeapon, A_ToggleSpell, + A_AutoMove, A_Jump, A_Inventory, A_Journal, A_Rest, A_QuickSave, A_QuickLoad, A_ToggleHUD, + A_Screenshot, A_QuickKeysMenu, A_QuickKey1, A_QuickKey2, A_QuickKey3, A_QuickKey4, + A_QuickKey5, A_QuickKey6, A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, + A_CycleSpellLeft, A_CycleSpellRight, A_CycleWeaponLeft, A_CycleWeaponRight + }; - return ret; + return actions; } void BindingsManager::enableDetectingBindingMode(int action, bool keyboard)