From fcac7d3ab770c07468169b506c65660a1a84e435 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 8 Apr 2020 14:48:23 +0400 Subject: [PATCH] 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 ff24b880f..b5ea4fabf 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 bb2ff9998..29c876e2b 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 5326c2d5c..e79ec145a 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 1e5c89cda..f73aa7f3d 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 000000000..b34124773 --- /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 000000000..c0a9408c6 --- /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