diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2b4739ba9..19cf4ef69 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 acfe4f8cd..590cf61a6 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 23562ba79..6b5b21653 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 000000000..55a0882f5 --- /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 000000000..d655e9c07 --- /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